
import java.io.*;
import java.util.zip.*;

public class InflateSkin
{
	int					inLen1;
	int					offset;
	byte[]				inBuf1;
	byte[]				outBuf;
	byte[]				cBuf;
	byte[]				uBuf;


	public InflateSkin() {
		cBuf = new byte[720*576*2];
		uBuf = new byte[720*576*2];
		outBuf = new byte[720*576*3+54];
	}

	public static void main (String argv []) {
		InflateSkin app = new InflateSkin();
		if (argv.length == 1)
			app.makeBmp(argv[0]);
		else
			System.out.println("Usage: java InflateSkin 3PG-something.pic");
	}

	public void makeBmp( String picName ) {
		loadFile(picName);
		if (inBuf1[0] != 124 || inBuf1[1] != 10) return;
		offset = 2;
		saveBitmap(720, 128, "3PG-infobox.bmp");
		saveBitmap(280,  50, "3PG-volume.bmp");
		saveBitmap(160, 128, "3PG-mini.bmp");
		saveBitmap(360,  88, "3PG-msgbox.bmp");
		saveBitmap( 80,  36, "3PG-progress1.bmp");
		saveBitmap( 52,  24, "3PG-progress2.bmp");
		saveBitmap(160, 160, "3PG-window.bmp");
		saveBitmap(336,  28, "3PG-timer.bmp");
		saveBitmap(922,  20, "3PG-icons.bmp");
		saveBitmap( 96,  32, "3PG-cursor.bmp");
	}

	public int convertBitmap( int width, int height ) {
		int x,y,i,k,r,g,b,col,clen,ulen,dlen,bpr,pad;

		clen = getInt(offset);
		ulen = getInt(offset+4);
		dlen = 0;
		offset+=8;
		for (x=0; x<clen; x++)
			cBuf[x] = inBuf1[offset+x];
		offset+=clen;
		try {
			Inflater decompr = new Inflater();
			decompr.setInput(cBuf, 0, clen);
			dlen = decompr.inflate(uBuf);
			decompr.end();
			if (dlen != ulen) System.out.println("Inflate error");
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
		bpr = (((width*3)+3)/4)*4;
		pad = bpr-width*3;
		i=8;
		k = (height-1)*bpr + 54;
		for (y=0; y<height; y++) {
			for (x=0; x<width; x++) {
				col = (((int)uBuf[i])&255)<<8 | (((int)uBuf[i+1])&255);
				r = (col >> 10) & 31;
				g = (col >> 5) & 31;
				b = col & 31;
				if (col == 0 || (r>28 && g==0 && b>28)) {		//transparent
					outBuf[k]   = (byte) 0xEE;
					outBuf[k+1] = (byte) 0;
					outBuf[k+2] = (byte) 0xEE;
				} else {
					outBuf[k]   = (byte) (b<<3);
					outBuf[k+1] = (byte) (g<<3);
					outBuf[k+2] = (byte) (r<<3);
				}
				i+=2;
				k+=3;
			}
			k -= (width*3)+bpr;
		}
		return clen;
	}

	public boolean loadFile( String fname ) {
		FileInputStream fis;
		try {
			File f = new File(fname);
			inLen1 = (int) f.length();
			System.out.println(fname+"  "+inLen1+" Bytes");
			fis = new FileInputStream(fname);
			inBuf1 = new byte[inLen1];
			fis.read(inBuf1);
			fis.close();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public void saveBitmap( int width, int height, String fname ) {
		FileOutputStream fos;
		int i,hdrlen,flen,dlen,color,bpr;

		i = convertBitmap(width, height);
		if (i > 0) System.out.println(fname+" "+i);
		for (i=0; i<54; i++) outBuf[i] = 0;
		hdrlen = 0x36;
		bpr = (((width*3)+3)/4)*4;
		flen   = bpr*height + 54;
		dlen   = bpr*height;
		color  = 0x180001;
		outBuf[ 0] = 0x42;
		outBuf[ 1] = 0x4D;
		outBuf[ 2] = (byte)(flen & 0xFF);
		outBuf[ 3] = (byte)((flen >> 8) & 0xFF);
		outBuf[ 4] = (byte)((flen >> 16) & 0xFF);
		outBuf[ 5] = (byte)((flen >> 24) & 0xFF);
		outBuf[10] = (byte)(hdrlen & 0xFF);
		outBuf[11] = (byte)((hdrlen >> 8) & 0xFF);
		outBuf[12] = (byte)((hdrlen >> 16) & 0xFF);
		outBuf[13] = (byte)((hdrlen >> 24) & 0xFF);
		outBuf[14] = 0x28;
		outBuf[18] = (byte)(width & 0xFF);
		outBuf[19] = (byte)((width >> 8) & 0xFF);
		outBuf[20] = (byte)((width >> 16) & 0xFF);
		outBuf[21] = (byte)((width >> 24) & 0xFF);
		outBuf[22] = (byte)(height & 0xFF);
		outBuf[23] = (byte)((height >> 8) & 0xFF);
		outBuf[24] = (byte)((height >> 16) & 0xFF);
		outBuf[25] = (byte)((height >> 24) & 0xFF);
		outBuf[26] = (byte)(color & 0xFF);
		outBuf[27] = (byte)((color >> 8) & 0xFF);
		outBuf[28] = (byte)((color >> 16) & 0xFF);
		outBuf[29] = (byte)((color >> 24) & 0xFF);
		outBuf[34] = (byte)(dlen & 0xFF);
		outBuf[35] = (byte)((dlen >> 8) & 0xFF);
		outBuf[36] = (byte)((dlen >> 16) & 0xFF);
		outBuf[37] = (byte)((dlen >> 24) & 0xFF);
		try {
			fos = new FileOutputStream(fname);
			fos.write(outBuf, 0, flen);
			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public int getByte( int index ) {
		if (index >= inLen1) return 0;
		return ((int)inBuf1[index]) & 255;
	}

	public int getWord( int index ) {
		return getByte(index)<<8 | getByte(index+1);
	}

	public int getInt( int index ) {
		return getWord(index)<<16 | getWord(index+2);
	}
}

