mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-04 20:15:28 -04:00
#423 Implemented opBitsRect for pixmap + opBitsRgn, opPackBitsRgn and opDirectBitsRgn, with some additional clea-up.
This commit is contained in:
parent
2ea3acb2c6
commit
30582dc5e5
@ -750,10 +750,6 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
penPosition = origin;
|
penPosition = origin;
|
||||||
context.moveTo(penPosition);
|
context.moveTo(penPosition);
|
||||||
text = PICTUtil.readPascalString(pStream);
|
text = PICTUtil.readPascalString(pStream);
|
||||||
// TODO
|
|
||||||
//if (mGraphics != null) {
|
|
||||||
// mGraphics.drawString(text, penPosition.x, penPosition.y);
|
|
||||||
//}
|
|
||||||
context.drawString(text);
|
context.drawString(text);
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
System.out.println("longText origin: " + penPosition + ", text:" + text);
|
System.out.println("longText origin: " + penPosition + ", text:" + text);
|
||||||
@ -1400,74 +1396,18 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
// [5] For opcodes $0090 (BitsRect) and $0091 (BitsRgn), the data is unpacked. These
|
// [5] For opcodes $0090 (BitsRect) and $0091 (BitsRgn), the data is unpacked. These
|
||||||
// opcodes can be used only when rowBytes is less than 8.
|
// opcodes can be used only when rowBytes is less than 8.
|
||||||
/*
|
/*
|
||||||
PixMap: PixMap; {pixel map}
|
pixMap: PixMap; {pixel map}
|
||||||
ColorTable: ColorTable; {ColorTable record}
|
ColorTable: ColorTable; {ColorTable record}
|
||||||
srcRect: Rect; {source rectangle}
|
srcRect: Rect; {source rectangle}
|
||||||
dstRect: Rect; {destination rectangle}
|
dstRect: Rect; {destination rectangle}
|
||||||
mode: Word; {transfer mode (may include }
|
mode: Word; {transfer mode (may include }
|
||||||
{ new transfer modes)}
|
{ new transfer modes)}
|
||||||
PixData: PixData;
|
pixData: PixData;
|
||||||
*/
|
*/
|
||||||
|
readOpBits(pStream, false);
|
||||||
int rowBytesRaw = pStream.readUnsignedShort();
|
|
||||||
int rowBytes = rowBytesRaw & 0x7FFF;
|
|
||||||
|
|
||||||
// TODO: Use rowBytes to determine size of PixMap/ColorTable?
|
|
||||||
if ((rowBytesRaw & 0x8000) > 0) {
|
|
||||||
// Do stuff...
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get bounds rectangle. THIS IS NOT TO BE SCALED BY THE RESOLUTION!
|
|
||||||
bounds = new Rectangle();
|
|
||||||
y = pStream.readUnsignedShort();
|
|
||||||
x = pStream.readUnsignedShort();
|
|
||||||
bounds.setLocation(x, y);
|
|
||||||
|
|
||||||
y = pStream.readUnsignedShort();
|
|
||||||
x = pStream.readUnsignedShort();
|
|
||||||
bounds.setSize(x - bounds.x, y - bounds.y);
|
|
||||||
|
|
||||||
Rectangle srcRect = new Rectangle();
|
|
||||||
readRectangle(pStream, srcRect);
|
|
||||||
|
|
||||||
Rectangle dstRect = new Rectangle();
|
|
||||||
readRectangle(pStream, dstRect);
|
|
||||||
|
|
||||||
mode = pStream.readUnsignedShort();
|
|
||||||
|
|
||||||
if (DEBUG) {
|
|
||||||
System.out.print("bitsRect, rowBytes: " + rowBytes);
|
|
||||||
if ((rowBytesRaw & 0x8000) > 0) {
|
|
||||||
System.out.print(", it is a PixMap");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
System.out.print(", it is a BitMap");
|
|
||||||
}
|
|
||||||
System.out.print(", bounds: " + bounds);
|
|
||||||
System.out.print(", srcRect: " + srcRect);
|
|
||||||
System.out.print(", dstRect: " + dstRect);
|
|
||||||
System.out.print(", mode: " + mode);
|
|
||||||
System.out.println();
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferedImage image = new BufferedImage(bounds.width, bounds.height, BufferedImage.TYPE_BYTE_BINARY);
|
|
||||||
byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
|
|
||||||
|
|
||||||
// Read pixel data
|
|
||||||
int width = bounds.width / 8;
|
|
||||||
for (int i = 0; i < bounds.height; i++) {
|
|
||||||
pStream.readFully(data, i * width, width);
|
|
||||||
pStream.skipBytes(rowBytes - width);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw pixel data
|
|
||||||
Rectangle rect = new Rectangle(srcRect);
|
|
||||||
rect.translate(-bounds.x, -bounds.y);
|
|
||||||
context.copyBits(image, rect, dstRect, mode, null);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PICT.OP_BITS_RGN:
|
case PICT.OP_BITS_RGN:
|
||||||
// TODO: As OP_BITS_RECT but with clip
|
|
||||||
/*
|
/*
|
||||||
pixMap: PixMap;
|
pixMap: PixMap;
|
||||||
colorTable: ColorTable;
|
colorTable: ColorTable;
|
||||||
@ -1478,9 +1418,8 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
maskRgn: Rgn; {region for masking}
|
maskRgn: Rgn; {region for masking}
|
||||||
pixData: PixData;
|
pixData: PixData;
|
||||||
*/
|
*/
|
||||||
if (DEBUG) {
|
readOpBits(pStream, true);
|
||||||
System.out.println("bitsRgn - TODO");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x92:
|
case 0x92:
|
||||||
@ -1497,27 +1436,19 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PICT.OP_PACK_BITS_RECT:
|
case PICT.OP_PACK_BITS_RECT:
|
||||||
readOpPackBitsRect(pStream, pixmapCount++);
|
readOpPackBits(pStream, false, pixmapCount++);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PICT.OP_PACK_BITS_RGN:
|
case PICT.OP_PACK_BITS_RGN:
|
||||||
// TODO: As OP_PACK_BITS_RECT but with clip
|
readOpPackBits(pStream, true, pixmapCount++);
|
||||||
// TODO: Read/Skip data
|
|
||||||
if (DEBUG) {
|
|
||||||
System.out.println("packBitsRgn - TODO");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PICT.OP_DIRECT_BITS_RECT:
|
case PICT.OP_DIRECT_BITS_RECT:
|
||||||
readOpDirectBitsRect(pStream, pixmapCount++);
|
readOpDirectBits(pStream, false, pixmapCount++);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PICT.OP_DIRECT_BITS_RGN:
|
case PICT.OP_DIRECT_BITS_RGN:
|
||||||
// TODO: As OP_DIRECT_BITS_RECT but with clip
|
readOpDirectBits(pStream, true, pixmapCount++);
|
||||||
// TODO: Read/Skip data
|
|
||||||
if (DEBUG) {
|
|
||||||
System.out.println("directBitsRgn - TODO");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x9C:
|
case 0x9C:
|
||||||
@ -1553,12 +1484,6 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
case PICT.OP_END_OF_PICTURE:// OK
|
case PICT.OP_END_OF_PICTURE:// OK
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// WE DON'T CARE ABOUT CODES 0x100 to 0x2FE, even if it might be needed
|
|
||||||
|
|
||||||
// WE DON'T CARE ABOUT CODES 0x300 to 0xBFF, even if it might be needed
|
|
||||||
|
|
||||||
// WE DON'T CARE ABOUT CODES 0xC01 to 0x81FF, even if it might be needed
|
|
||||||
|
|
||||||
case PICT.OP_COMPRESSED_QUICKTIME:
|
case PICT.OP_COMPRESSED_QUICKTIME:
|
||||||
// $8200: CompressedQuickTime Data length (Long), data (private to QuickTime) 4 + data length
|
// $8200: CompressedQuickTime Data length (Long), data (private to QuickTime) 4 + data length
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@ -1573,25 +1498,16 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
// $8201: UncompressedQuickTime Data length (Long), data (private to QuickTime) 4 + data length
|
// $8201: UncompressedQuickTime Data length (Long), data (private to QuickTime) 4 + data length
|
||||||
// TODO: Read this as well, need test data
|
// TODO: Read this as well, need test data
|
||||||
dataLength = pStream.readInt();
|
dataLength = pStream.readInt();
|
||||||
pStream.readFully(new byte[dataLength], 0, dataLength);
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
System.out.println("unCompressedQuickTime");
|
System.out.println(String.format("unCompressedQuickTime, length %d", dataLength));
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xFFFF:// JUST JUMP OVER
|
|
||||||
dataLength = pStream.readInt();
|
|
||||||
pStream.readFully(new byte[dataLength], 0, dataLength);
|
pStream.readFully(new byte[dataLength], 0, dataLength);
|
||||||
if (DEBUG) {
|
|
||||||
System.out.println(String.format("%s: 0x%04x - length: %s", PICT.APPLE_USE_RESERVED_FIELD, opCode, dataLength));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// See: http://developer.apple.com/DOCUMENTATION/mac/QuickDraw/QuickDraw-461.html
|
// See: http://developer.apple.com/DOCUMENTATION/mac/QuickDraw/QuickDraw-461.html
|
||||||
if (opCode >= 0x00a0 && opCode <= 0x00af) {
|
if (opCode >= 0x00a2 && opCode <= 0x00af) {
|
||||||
dataLength = pStream.readUnsignedShort();
|
dataLength = pStream.readUnsignedShort();
|
||||||
pStream.readFully(new byte[dataLength], 0, dataLength);
|
|
||||||
}
|
}
|
||||||
else if (opCode >= 0x00b0 && opCode <= 0x00cf) {
|
else if (opCode >= 0x00b0 && opCode <= 0x00cf) {
|
||||||
// Zero-length
|
// Zero-length
|
||||||
@ -1599,13 +1515,11 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
else if (opCode >= 0x00d0 && opCode <= 0x00fe) {
|
else if (opCode >= 0x00d0 && opCode <= 0x00fe) {
|
||||||
dataLength = pStream.readInt();
|
dataLength = pStream.readInt();
|
||||||
pStream.readFully(new byte[dataLength], 0, dataLength);
|
|
||||||
}
|
}
|
||||||
else if (opCode >= 0x0100 && opCode <= 0x7fff) {
|
else if (opCode >= 0x0100 && opCode <= 0x7fff) {
|
||||||
// For opcodes $0100-$7FFF, the amount of data for
|
// For opcodes $0100-$7FFF, the amount of data for
|
||||||
// opcode $nnXX = 2 times nn bytes.
|
// opcode $nnXX = 2 times nn bytes.
|
||||||
dataLength = (opCode & 0xff00) >> 7;
|
dataLength = (opCode & 0xff00) >> 7;
|
||||||
pStream.readFully(new byte[dataLength], 0, dataLength);
|
|
||||||
}
|
}
|
||||||
else if (opCode >= 0x8000 && opCode <= 0x80ff) {
|
else if (opCode >= 0x8000 && opCode <= 0x80ff) {
|
||||||
// Zero-length
|
// Zero-length
|
||||||
@ -1613,17 +1527,21 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
else if (opCode >= 0x8100 && opCode <= 0x81ff) {
|
else if (opCode >= 0x8100 && opCode <= 0x81ff) {
|
||||||
dataLength = pStream.readInt();
|
dataLength = pStream.readInt();
|
||||||
pStream.readFully(new byte[dataLength], 0, dataLength);
|
}
|
||||||
|
else if (opCode == 0xffff) {
|
||||||
|
dataLength = pStream.readInt();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO: We could issue a warning and return instead? In any case, can't continue, as we don't know the length of the opcode...
|
|
||||||
// return;
|
|
||||||
throw new IIOException(String.format("Found unknown opcode: 0x%04x", opCode));
|
throw new IIOException(String.format("Found unknown opcode: 0x%04x", opCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
System.out.println(String.format("%s: 0x%04x - length: %s", PICT.APPLE_USE_RESERVED_FIELD, opCode, dataLength));
|
System.out.println(String.format("%s: 0x%04x - length: %s", PICT.APPLE_USE_RESERVED_FIELD, opCode, dataLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dataLength != 0) {
|
||||||
|
pStream.readFully(new byte[dataLength], 0, dataLength);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (opCode != PICT.OP_END_OF_PICTURE);
|
while (opCode != PICT.OP_END_OF_PICTURE);
|
||||||
@ -1731,17 +1649,15 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
MatteRect Rectangle for matte data 8
|
MatteRect Rectangle for matte data 8
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
private void readOpPackBits(final ImageInputStream pStream, final boolean hasRegion, final int pPixmapCount) throws IOException {
|
||||||
private void readOpPackBitsRect(final ImageInputStream pStream, final int pPixmapCount) throws IOException {
|
|
||||||
// Get rowBytes
|
// Get rowBytes
|
||||||
int rowBytesRaw = pStream.readUnsignedShort();
|
int rowBytesRaw = pStream.readUnsignedShort();
|
||||||
// System.out.println(String.format("%08d: 0x%04x", pStream.getStreamPosition(), rowBytesRaw));
|
|
||||||
// TODO: This way to determine pixmap vs bitmap is for version 2 only!
|
|
||||||
int rowBytes = rowBytesRaw & 0x7FFF;
|
int rowBytes = rowBytesRaw & 0x7FFF;
|
||||||
boolean isPixMap = (rowBytesRaw & 0x8000) > 0;
|
boolean isPixMap = (rowBytesRaw & 0x8000) > 0;
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
System.out.print("packBitsRect, rowBytes: " + rowBytes);
|
System.out.print(hasRegion ? "packBitsRgn" : "packBitsRect");
|
||||||
|
System.out.print(", rowBytes: " + rowBytes);
|
||||||
if (isPixMap) {
|
if (isPixMap) {
|
||||||
System.out.print(", it is a PixMap");
|
System.out.print(", it is a PixMap");
|
||||||
}
|
}
|
||||||
@ -1887,6 +1803,13 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
System.out.println(", mode: " + transferMode);
|
System.out.println(", mode: " + transferMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle regionBounds = new Rectangle();
|
||||||
|
Polygon region = hasRegion ? readRegion(pStream, regionBounds) : null;
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
verboseRegionCmd("region", regionBounds, region);
|
||||||
|
}
|
||||||
|
|
||||||
// Set up pixel buffer for the RGB values
|
// Set up pixel buffer for the RGB values
|
||||||
byte[] pixArray = new byte[srcRect.height * rowBytes];
|
byte[] pixArray = new byte[srcRect.height * rowBytes];
|
||||||
int pixBufOffset = 0;
|
int pixBufOffset = 0;
|
||||||
@ -1894,8 +1817,7 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
// Read in the RGB arrays
|
// Read in the RGB arrays
|
||||||
for (int scanline = 0; scanline < srcRect.height; scanline++) {
|
for (int scanline = 0; scanline < srcRect.height; scanline++) {
|
||||||
// Read in the scanline
|
// Read in the scanline
|
||||||
// TODO: This seems to be always compressed for v1 bitmaps...
|
if (rowBytes >= 8) {
|
||||||
if (!isPixMap || rowBytes > 8) {
|
|
||||||
// Get byteCount of the scanline
|
// Get byteCount of the scanline
|
||||||
int packedBytesCount = rowBytes > 250 ? pStream.readUnsignedShort() : pStream.readUnsignedByte();
|
int packedBytesCount = rowBytes > 250 ? pStream.readUnsignedShort() : pStream.readUnsignedByte();
|
||||||
|
|
||||||
@ -1924,7 +1846,7 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
// Get byteCount of the scanline
|
// Get byteCount of the scanline
|
||||||
int packedBytesCount;
|
int packedBytesCount;
|
||||||
|
|
||||||
if (rowBytes <= 8) {
|
if (rowBytes < 8) {
|
||||||
packedBytesCount = rowBytes;
|
packedBytesCount = rowBytes;
|
||||||
}
|
}
|
||||||
else if (rowBytes > 250) {
|
else if (rowBytes > 250) {
|
||||||
@ -1962,6 +1884,7 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
if (img != null) {
|
if (img != null) {
|
||||||
// TODO: FixMe.. Seems impossible to create a bufferedImage with a raster not starting at 0,0
|
// TODO: FixMe.. Seems impossible to create a bufferedImage with a raster not starting at 0,0
|
||||||
srcRect.setLocation(0, 0); // should not require this line..
|
srcRect.setLocation(0, 0); // should not require this line..
|
||||||
|
// context.copyBits(img, srcRect, dstRect, transferMode, region);
|
||||||
context.copyBits(img, srcRect, dstRect, transferMode, null);
|
context.copyBits(img, srcRect, dstRect, transferMode, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1981,16 +1904,18 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
* @throws javax.imageio.IIOException if the data can not be read.
|
* @throws javax.imageio.IIOException if the data can not be read.
|
||||||
* @throws java.io.IOException if an I/O error occurs while reading the image.
|
* @throws java.io.IOException if an I/O error occurs while reading the image.
|
||||||
*/
|
*/
|
||||||
private void readOpDirectBitsRect(final ImageInputStream pStream, final int pPixmapCount) throws IOException {
|
private void readOpDirectBits(final ImageInputStream pStream, final boolean hasRegion, final int pPixmapCount) throws IOException {
|
||||||
// Skip PixMap pointer (always 0x000000FF);
|
// Skip PixMap pointer (always 0x000000FF);
|
||||||
pStream.readInt();
|
pStream.readInt();
|
||||||
|
|
||||||
// Get rowBytes
|
// Get rowBytes
|
||||||
int rowBytesRaw = pStream.readUnsignedShort();
|
int rowBytesRaw = pStream.readUnsignedShort();
|
||||||
int rowBytes = rowBytesRaw & 0x7FFF;
|
int rowBytes = rowBytesRaw & 0x7FFF;
|
||||||
|
boolean isPixMap = (rowBytesRaw & 0x8000) > 0;
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
System.out.print("directBitsRect, rowBytes: " + rowBytes);
|
System.out.print(hasRegion ? "directBitsRgn" : "directBitsRect");
|
||||||
if ((rowBytesRaw & 0x8000) > 0) {
|
System.out.print(", rowBytes: " + rowBytes);
|
||||||
|
if (isPixMap) {
|
||||||
System.out.print(", it is a PixMap");
|
System.out.print(", it is a PixMap");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -2012,70 +1937,84 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
System.out.print(", bounds: " + bounds);
|
System.out.print(", bounds: " + bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get PixMap record version number
|
ColorModel colorModel = null;
|
||||||
int pmVersion = pStream.readUnsignedShort();
|
int packType;
|
||||||
if (DEBUG) {
|
int cmpSize;
|
||||||
System.out.print(", pmVersion: " + pmVersion);
|
int cmpCount;
|
||||||
}
|
|
||||||
|
|
||||||
// Get packing format
|
if (isPixMap) {
|
||||||
int packType = pStream.readUnsignedShort();
|
// Get PixMap record version number
|
||||||
if (DEBUG) {
|
int pmVersion = pStream.readUnsignedShort();
|
||||||
System.out.print(", packType: " + packType);
|
if (DEBUG) {
|
||||||
}
|
System.out.print(", pmVersion: " + pmVersion);
|
||||||
|
|
||||||
// Get size of packed data (not used for v2)
|
|
||||||
int packSize = pStream.readInt();
|
|
||||||
if (DEBUG) {
|
|
||||||
System.out.println(", packSize: " + packSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get resolution info
|
|
||||||
double hRes = PICTUtil.readFixedPoint(pStream);
|
|
||||||
double vRes = PICTUtil.readFixedPoint(pStream);
|
|
||||||
if (DEBUG) {
|
|
||||||
System.out.print("hRes: " + hRes + ", vRes: " + vRes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get pixel type
|
|
||||||
int pixelType = pStream.readUnsignedShort();
|
|
||||||
if (DEBUG) {
|
|
||||||
if (pixelType == 0) {
|
|
||||||
System.out.print(", indexed pixels");
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
System.out.print(", RGBDirect");
|
// Get packing format
|
||||||
|
packType = pStream.readUnsignedShort();
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.print(", packType: " + packType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get size of packed data (not used for v2)
|
||||||
|
int packSize = pStream.readInt();
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println(", packSize: " + packSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get resolution info
|
||||||
|
double hRes = PICTUtil.readFixedPoint(pStream);
|
||||||
|
double vRes = PICTUtil.readFixedPoint(pStream);
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.print("hRes: " + hRes + ", vRes: " + vRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get pixel type
|
||||||
|
int pixelType = pStream.readUnsignedShort();
|
||||||
|
if (DEBUG) {
|
||||||
|
if (pixelType == 0) {
|
||||||
|
System.out.print(", indexed pixels");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
System.out.print(", RGBDirect");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get pixel size
|
||||||
|
int pixelSize = pStream.readUnsignedShort();
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.print(", pixelSize:" + pixelSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get pixel component count
|
||||||
|
cmpCount = pStream.readUnsignedShort();
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.print(", cmpCount:" + cmpCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get pixel component size
|
||||||
|
cmpSize = pStream.readUnsignedShort();
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.print(", cmpSize:" + cmpSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// planeBytes (ignored)
|
||||||
|
pStream.readInt();
|
||||||
|
|
||||||
|
// Handle to ColorTable record, there should be none for direct
|
||||||
|
// bits so this should be 0, just skip
|
||||||
|
pStream.readInt();
|
||||||
|
|
||||||
|
// Reserved
|
||||||
|
pStream.readInt();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
// Get pixel size
|
// Old style BitMap record
|
||||||
int pixelSize = pStream.readUnsignedShort();
|
packType = 1;
|
||||||
if (DEBUG) {
|
cmpSize = 1;
|
||||||
System.out.print(", pixelSize:" + pixelSize);
|
cmpCount = 1;
|
||||||
|
colorModel = QuickDraw.MONOCHROME;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get pixel component count
|
|
||||||
int cmpCount = pStream.readUnsignedShort();
|
|
||||||
if (DEBUG) {
|
|
||||||
System.out.print(", cmpCount:" + cmpCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get pixel component size
|
|
||||||
int cmpSize = pStream.readUnsignedShort();
|
|
||||||
if (DEBUG) {
|
|
||||||
System.out.print(", cmpSize:" + cmpSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// planeBytes (ignored)
|
|
||||||
pStream.readInt();
|
|
||||||
|
|
||||||
// Handle to ColorTable record, there should be none for direct
|
|
||||||
// bits so this should be 0, just skip
|
|
||||||
pStream.readInt();
|
|
||||||
|
|
||||||
// Reserved
|
|
||||||
pStream.readInt();
|
|
||||||
|
|
||||||
// Get source rectangle. We DO NOT scale the coordinates by the
|
// Get source rectangle. We DO NOT scale the coordinates by the
|
||||||
// resolution info, since we are in pixmap coordinates here
|
// resolution info, since we are in pixmap coordinates here
|
||||||
Rectangle srcRect = new Rectangle();
|
Rectangle srcRect = new Rectangle();
|
||||||
@ -2102,7 +2041,13 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
// Get transfer mode
|
// Get transfer mode
|
||||||
int transferMode = pStream.readUnsignedShort();
|
int transferMode = pStream.readUnsignedShort();
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
System.out.println(", mode: " + transferMode);
|
System.out.print(", mode: " + transferMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
Polygon region = hasRegion ? readRegion(pStream, new Rectangle()) : null;
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println(hasRegion ? ", region: " + region : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up pixel buffer for the RGB values
|
// Set up pixel buffer for the RGB values
|
||||||
@ -2177,7 +2122,7 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
| (dstBytes[2 * bounds.width + i] & 0xFF);
|
| (dstBytes[2 * bounds.width + i] & 0xFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if (cmpCount == 4) {
|
||||||
// ARGB
|
// ARGB
|
||||||
for (int i = 0; i < srcRect.width; i++) {
|
for (int i = 0; i < srcRect.width; i++) {
|
||||||
// Get alpha values
|
// Get alpha values
|
||||||
@ -2228,18 +2173,23 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
// "pPixmapCount" will never be greater than the size of the vector
|
// "pPixmapCount" will never be greater than the size of the vector
|
||||||
if (images.size() <= pPixmapCount) {
|
if (images.size() <= pPixmapCount) {
|
||||||
// Create BufferedImage and add buffer it for multiple reads
|
// Create BufferedImage and add buffer it for multiple reads
|
||||||
DirectColorModel cm;
|
ColorModel cm;
|
||||||
WritableRaster raster;
|
WritableRaster raster;
|
||||||
|
|
||||||
if (packType == 3) {
|
if (colorModel != null) {
|
||||||
|
cm = colorModel;
|
||||||
|
DataBuffer db = new DataBufferByte(dstBytes, dstBytes.length);
|
||||||
|
raster = Raster.createPackedRaster(db, srcRect.width, srcRect.height, 1, null); // TODO: last param should ideally be srcRect.getLocation()
|
||||||
|
}
|
||||||
|
else if (packType == 3) {
|
||||||
cm = new DirectColorModel(15, 0x7C00, 0x03E0, 0x001F); // See BufferedImage TYPE_USHORT_555_RGB
|
cm = new DirectColorModel(15, 0x7C00, 0x03E0, 0x001F); // See BufferedImage TYPE_USHORT_555_RGB
|
||||||
DataBuffer db = new DataBufferUShort(shortArray, shortArray.length);
|
DataBuffer db = new DataBufferUShort(shortArray, shortArray.length);
|
||||||
raster = Raster.createPackedRaster(db, srcRect.width, srcRect.height, srcRect.width, cm.getMasks(), null); // TODO: last param should ideally be srcRect.getLocation()
|
raster = Raster.createPackedRaster(db, srcRect.width, srcRect.height, srcRect.width, ((DirectColorModel) cm).getMasks(), null); // TODO: last param should ideally be srcRect.getLocation()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cm = (DirectColorModel) ColorModel.getRGBdefault();
|
cm = ColorModel.getRGBdefault();
|
||||||
DataBuffer db = new DataBufferInt(pixArray, pixArray.length);
|
DataBuffer db = new DataBufferInt(pixArray, pixArray.length);
|
||||||
raster = Raster.createPackedRaster(db, srcRect.width, srcRect.height, srcRect.width, cm.getMasks(), null); // TODO: last param should ideally be srcRect.getLocation()
|
raster = Raster.createPackedRaster(db, srcRect.width, srcRect.height, srcRect.width, ((DirectColorModel) cm).getMasks(), null); // TODO: last param should ideally be srcRect.getLocation()
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferedImage img = new BufferedImage(cm, raster, cm.isAlphaPremultiplied(), null);
|
BufferedImage img = new BufferedImage(cm, raster, cm.isAlphaPremultiplied(), null);
|
||||||
@ -2252,6 +2202,7 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
if (img != null) {
|
if (img != null) {
|
||||||
// TODO: FixMe.. Something wrong here, might be the copyBits methods.
|
// TODO: FixMe.. Something wrong here, might be the copyBits methods.
|
||||||
srcRect.setLocation(0, 0); // should not require this line..
|
srcRect.setLocation(0, 0); // should not require this line..
|
||||||
|
// context.copyBits(img, srcRect, dstRect, transferMode, region);
|
||||||
context.copyBits(img, srcRect, dstRect, transferMode, null);
|
context.copyBits(img, srcRect, dstRect, transferMode, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2259,7 +2210,154 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
System.out.println();
|
System.out.println();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readOpBits(ImageInputStream pStream, boolean hasRegion) throws IOException {
|
||||||
|
// Get rowBytes
|
||||||
|
int rowBytesRaw = pStream.readUnsignedShort();
|
||||||
|
int rowBytes = rowBytesRaw & 0x7FFF;
|
||||||
|
boolean isPixMap = (rowBytesRaw & 0x8000) > 0;
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.print(hasRegion ? "bitsRgn" : "bitsRect");
|
||||||
|
System.out.print(", rowBytes: " + rowBytes);
|
||||||
|
if (isPixMap) {
|
||||||
|
System.out.print(", it is a PixMap");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
System.out.print(", it is a BitMap");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get bounds rectangle. THIS IS NOT TO BE SCALED BY THE RESOLUTION!
|
||||||
|
Rectangle bounds = new Rectangle();
|
||||||
|
int y = pStream.readUnsignedShort();
|
||||||
|
int x = pStream.readUnsignedShort();
|
||||||
|
bounds.setLocation(x, y);
|
||||||
|
|
||||||
|
y = pStream.readUnsignedShort();
|
||||||
|
x = pStream.readUnsignedShort();
|
||||||
|
bounds.setSize(x - bounds.x, y - bounds.y);
|
||||||
|
|
||||||
|
ColorModel colorModel;
|
||||||
|
int cmpSize;
|
||||||
|
|
||||||
|
if (isPixMap) {
|
||||||
|
// Get PixMap record version number
|
||||||
|
int pmVersion = pStream.readUnsignedShort();
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.print(", pmVersion: " + pmVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get packing format
|
||||||
|
int packType = pStream.readUnsignedShort();
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.print(", packType: " + packType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get size of packed data (not used for v2)
|
||||||
|
int packSize = pStream.readInt();
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println(", packSize: " + packSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get resolution info
|
||||||
|
double hRes = PICTUtil.readFixedPoint(pStream);
|
||||||
|
double vRes = PICTUtil.readFixedPoint(pStream);
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.print("hRes: " + hRes + ", vRes: " + vRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get pixel type
|
||||||
|
int pixelType = pStream.readUnsignedShort();
|
||||||
|
if (DEBUG) {
|
||||||
|
if (pixelType == 0) {
|
||||||
|
System.out.print(", indexed pixels");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
System.out.print(", RGBDirect");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get pixel size
|
||||||
|
int pixelSize = pStream.readUnsignedShort();
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.print(", pixelSize:" + pixelSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get pixel component count
|
||||||
|
int cmpCount = pStream.readUnsignedShort();
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.print(", cmpCount:" + cmpCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get pixel component size
|
||||||
|
cmpSize = pStream.readUnsignedShort();
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.print(", cmpSize:" + cmpSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// planeBytes (ignored)
|
||||||
|
int planeBytes = pStream.readInt();
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.print(", planeBytes:" + planeBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle to ColorTable record
|
||||||
|
int clutId = pStream.readInt();
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.print(", clutId:" + clutId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reserved
|
||||||
|
pStream.readInt();
|
||||||
|
|
||||||
|
// TODO: Seems to be packType 0 all the time?
|
||||||
|
// packType = 0 means default....
|
||||||
|
|
||||||
|
// Color table
|
||||||
|
colorModel = PICTUtil.readColorTable(pStream, pixelSize);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Old style BitMap record
|
||||||
|
colorModel = QuickDraw.MONOCHROME;
|
||||||
|
cmpSize = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle srcRect = new Rectangle();
|
||||||
|
readRectangle(pStream, srcRect);
|
||||||
|
|
||||||
|
Rectangle dstRect = new Rectangle();
|
||||||
|
readRectangle(pStream, dstRect);
|
||||||
|
|
||||||
|
// Get transfer mode
|
||||||
|
int mode = pStream.readUnsignedShort();
|
||||||
|
|
||||||
|
Polygon region = hasRegion ? readRegion(pStream, new Rectangle()) : null;
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.print(", bounds: " + bounds);
|
||||||
|
System.out.print(", srcRect: " + srcRect);
|
||||||
|
System.out.print(", dstRect: " + dstRect);
|
||||||
|
System.out.print(", mode: " + mode);
|
||||||
|
System.out.println(hasRegion ? ", region: " + region : "");
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] data = new byte[rowBytes * bounds.height];
|
||||||
|
|
||||||
|
// Read pixel data
|
||||||
|
for (int i = 0; i < bounds.height; i++) {
|
||||||
|
pStream.readFully(data, i * rowBytes, rowBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataBuffer db = new DataBufferByte(data, data.length);
|
||||||
|
WritableRaster raster = Raster.createPackedRaster(db, (rowBytes * 8) / cmpSize, srcRect.height, cmpSize, null); // TODO: last param should ideally be srcRect.getLocation()
|
||||||
|
BufferedImage image = new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), null);
|
||||||
|
|
||||||
|
// Draw pixel data
|
||||||
|
srcRect.setLocation(0, 0); // should not require this line..
|
||||||
|
dstRect.setLocation(0, 0); // should not require this line..
|
||||||
|
context.copyBits(image, srcRect, dstRect, mode, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2283,7 +2381,7 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read in a region. The inputstream should be positioned at the first byte
|
* Read in a region. The input stream should be positioned at the first byte
|
||||||
* of the region. {@code pBoundsRect} is a rectangle that will be set to the
|
* of the region. {@code pBoundsRect} is a rectangle that will be set to the
|
||||||
* region bounds.
|
* region bounds.
|
||||||
* The point array may therefore be empty if the region is just a rectangle.
|
* The point array may therefore be empty if the region is just a rectangle.
|
||||||
@ -2292,7 +2390,7 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
* @param pBoundsRect the bounds rectangle to read into
|
* @param pBoundsRect the bounds rectangle to read into
|
||||||
*
|
*
|
||||||
* @return the polygon containing the region, or an empty polygon if the
|
* @return the polygon containing the region, or an empty polygon if the
|
||||||
* region is a rectanlge.
|
* region is a rectangle.
|
||||||
*
|
*
|
||||||
* @throws IOException if an I/O error occurs while reading the image.
|
* @throws IOException if an I/O error occurs while reading the image.
|
||||||
*/
|
*/
|
||||||
@ -2303,31 +2401,46 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
int size = pStream.readUnsignedShort();
|
int size = pStream.readUnsignedShort();
|
||||||
|
|
||||||
// Get region bounds
|
// Get region bounds
|
||||||
int y = getYPtCoord(pStream.readUnsignedShort());
|
int y = getYPtCoord(pStream.readShort());
|
||||||
int x = getXPtCoord(pStream.readUnsignedShort());
|
int x = getXPtCoord(pStream.readShort());
|
||||||
pBoundsRect.setLocation(x, y);
|
pBoundsRect.setLocation(x, y);
|
||||||
|
|
||||||
y = getYPtCoord(pStream.readShort()) - pBoundsRect.getLocation().y;
|
y = getYPtCoord(pStream.readShort()) - pBoundsRect.getLocation().y;
|
||||||
x = getXPtCoord(pStream.readShort()) - pBoundsRect.getLocation().x;
|
x = getXPtCoord(pStream.readShort()) - pBoundsRect.getLocation().x;
|
||||||
pBoundsRect.setSize(x, y);
|
pBoundsRect.setSize(x, y);
|
||||||
|
|
||||||
// Initialize the point array to the right size
|
|
||||||
int points = (size - 10) / (2 * 2);
|
|
||||||
|
|
||||||
// Get the rest of the polygon points
|
|
||||||
Polygon polygon = new Polygon();
|
Polygon polygon = new Polygon();
|
||||||
for (int i = 0; i < points; i++) {
|
int count = (size - 10) / 2;
|
||||||
x = getXPtCoord(pStream.readShort());
|
boolean nextIsV = true;
|
||||||
y = getYPtCoord(pStream.readShort());
|
|
||||||
|
|
||||||
polygon.addPoint(x, y);
|
for (int i = 0; i < count; i++) {
|
||||||
|
short point = pStream.readShort();
|
||||||
|
|
||||||
|
if (nextIsV) {
|
||||||
|
if (point == 0x7fff) {
|
||||||
|
// Done
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
y = point;
|
||||||
|
nextIsV = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (point == 0x7fff) {
|
||||||
|
nextIsV = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = point;
|
||||||
|
polygon.addPoint(x, y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return polygon;
|
return polygon;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read in a polygon. The inputstream should be positioned at the first byte
|
* Read in a polygon. The input stream should be positioned at the first byte
|
||||||
* of the polygon.
|
* of the polygon.
|
||||||
*/
|
*/
|
||||||
private Polygon readPoly(DataInput pStream, Rectangle pBoundsRect) throws IOException {
|
private Polygon readPoly(DataInput pStream, Rectangle pBoundsRect) throws IOException {
|
||||||
@ -2344,7 +2457,7 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
pBoundsRect.setSize(x, y);
|
pBoundsRect.setSize(x, y);
|
||||||
|
|
||||||
// Initialize the point array to the right size
|
// Initialize the point array to the right size
|
||||||
int points = (size - 10) / (2 * 2);
|
int points = (size - 10) / 4;
|
||||||
|
|
||||||
// Get the rest of the polygon points
|
// Get the rest of the polygon points
|
||||||
Polygon polygon = new Polygon();
|
Polygon polygon = new Polygon();
|
||||||
@ -2390,7 +2503,7 @@ public final class PICTImageReader extends ImageReaderBase {
|
|||||||
int length = pStream.readUnsignedShort();
|
int length = pStream.readUnsignedShort();
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
System.err.println("Long comment: " + kind + ", " + length + " bytes");
|
System.out.println("Long comment: " + kind + ", " + length + " bytes");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get as many bytes as indicated by byte count
|
// Get as many bytes as indicated by byte count
|
||||||
|
Loading…
x
Reference in New Issue
Block a user