dmolony-DiskBrowser/src/com/bytezone/diskbrowser/applefile/HiResImage.java

262 lines
7.0 KiB
Java
Executable File

package com.bytezone.diskbrowser.applefile;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.bytezone.diskbrowser.HexFormatter;
public class HiResImage extends AbstractFile
{
int fileType;
int auxType;
byte[] unpackedBuffer;
public HiResImage (String name, byte[] buffer)
{
super (name, buffer);
if (name.equals ("FLY LOGO") || name.equals ("BIGBAT.PAC")) // && reportedLength == 0x14FA)
{
this.buffer = unscrunch (buffer);
}
if (isGif (buffer))
makeGif ();
else
makeScreen1 (buffer);
}
public HiResImage (String name, byte[] buffer, int fileType, int auxType)
{
super (name, buffer);
this.fileType = fileType;
this.auxType = auxType;
if (fileType == 192 && auxType == 1)
{
unpackedBuffer = unpackBytes (buffer);
makeScreen2 (unpackedBuffer);
}
if (fileType == 192 && auxType == 2)
{
System.out.println ("yippee - Preferred picture format - " + name);
}
}
private void makeScreen1 (byte[] buffer)
{
int rows = buffer.length <= 8192 ? 192 : 384;
image = new BufferedImage (280, rows, BufferedImage.TYPE_BYTE_GRAY);
DataBuffer db = image.getRaster ().getDataBuffer ();
int element = 0;
byte[] mask = { 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
for (int z = 0; z < rows / 192; z++)
for (int i = 0; i < 3; i++)
for (int j = 0; j < 8; j++)
for (int k = 0; k < 8; k++)
{
int base = i * 0x28 + j * 0x80 + k * 0x400 + z * 0x2000;
int max = Math.min (base + 40, buffer.length);
for (int ptr = base; ptr < max; ptr++)
{
byte val = buffer[ptr];
if (val == 0) // no pixels set
{
element += 7;
continue;
}
for (int bit = 6; bit >= 0; bit--)
{
if ((val & mask[bit]) > 0)
db.setElem (element, 255);
element++;
}
}
}
}
private void makeScreen2 (byte[] buffer)
{
// System.out.println (HexFormatter.format (buffer, 32000, 640));
// for (int table = 0; table < 200; table++)
// {
// System.out.println (HexFormatter.format (buffer, ptr, 32));
// for (int color = 0; color < 16; color++)
// {
// int red = buffer[ptr++] & 0x0F;
// int green = (buffer[ptr] & 0xF0) >> 4;
// int blue = buffer[ptr++] & 0x0F;
// Color c = new Color (red, green, blue);
// }
// }
image = new BufferedImage (320, 200, BufferedImage.TYPE_BYTE_GRAY);
DataBuffer db = image.getRaster ().getDataBuffer ();
int element = 0;
int ptr = 0;
for (int row = 0; row < 200; row++)
for (int col = 0; col < 160; col++)
{
int pix1 = (buffer[ptr] & 0xF0) >> 4;
int pix2 = buffer[ptr] & 0x0F;
if (pix1 > 0)
db.setElem (element, 255);
if (pix2 > 0)
db.setElem (element + 1, 255);
element += 2;
ptr++;
}
}
// Beagle Bros routine to expand a hi-res screen
private byte[] unscrunch (byte[] src)
{
// byte[] dst = new byte[src.length < 0x2000 ? 0x2000 : 0x4000];
byte[] dst = new byte[0x2000];
int p1 = 0;
int p2 = 0;
// while (p1 < dst.length && p2 < src.length)
while (p1 < dst.length)
{
// System.out.printf ("%04X %04X%n", p1, p2);
byte b = src[p2++];
if ((b == (byte) 0x80) || (b == (byte) 0xFF))
{
b &= 0x7F;
int rpt = src[p2++];
for (int i = 0; i < rpt; i++)
dst[p1++] = b;
}
else
dst[p1++] = b;
}
return dst;
}
private void makeGif ()
{
try
{
image = ImageIO.read (new ByteArrayInputStream (buffer));
}
catch (IOException e)
{
e.printStackTrace ();
}
}
private byte[] unpackBytes (byte[] buffer)
{
// routine found here - http://kpreid.livejournal.com/4319.html
byte[] newBuf = new byte[32768];
byte[] fourBuf = new byte[4];
// System.out.println (HexFormatter.format (buffer));
int ptr = 0, newPtr = 0;
while (ptr < buffer.length)
{
int type = (buffer[ptr] & 0xC0) >> 6;
int count = (buffer[ptr++] & 0x3F) + 1;
switch (type)
{
case 0:
while (count-- != 0)
newBuf[newPtr++] = buffer[ptr++];
break;
case 1:
byte b = buffer[ptr++];
while (count-- != 0)
newBuf[newPtr++] = b;
break;
case 2:
for (int i = 0; i < 4; i++)
fourBuf[i] = buffer[ptr++];
while (count-- != 0)
for (int i = 0; i < 4; i++)
newBuf[newPtr++] = fourBuf[i];
break;
case 3:
b = buffer[ptr++];
count *= 4;
while (count-- != 0)
newBuf[newPtr++] = b;
break;
}
}
return newBuf;
}
@Override
public String getText ()
{
String auxText = "";
StringBuilder text = new StringBuilder ("Image File : " + name);
text.append (String.format ("%nFile type : $%02X", fileType));
switch (fileType)
{
case 8:
if (auxType < 0x4000)
auxText = "Graphics File";
else if (auxType == 0x4000)
auxText = "Packed Hi-Res File";
else if (auxType == 0x4001)
auxText = "Packed Double Hi-Res File";
break;
case 192:
if (auxType == 1)
{
if (unpackedBuffer == null)
unpackedBuffer = unpackBytes (buffer);
auxText = "Packed Super Hi-Res Image";
}
else if (auxType == 2)
auxText = "Super Hi-Res Image";
else if (auxType == 3)
auxText = "Packed QuickDraw II PICT File";
break;
case 193:
if (auxType == 0)
auxText = "Super Hi-res Screen Image";
else if (auxType == 1)
auxText = "QuickDraw PICT File";
else if (auxType == 2)
auxText = "Super Hi-Res 3200 color image";
}
if (!auxText.isEmpty ())
text.append (String.format ("%nAux type : $%04X %s", auxType, auxText));
text.append (String.format ("%nFile size : %,d", buffer.length));
if (unpackedBuffer != null)
{
text.append (String.format ("%nUnpacked : %,d%n%n", unpackedBuffer.length));
text.append (HexFormatter.format (unpackedBuffer));
}
return text.toString ();
}
public static boolean isGif (byte[] buffer)
{
if (buffer.length < 6)
return false;
String text = new String (buffer, 0, 6);
return text.equals ("GIF89a") || text.equals ("GIF87a");
}
}