import java.io.*;

public class SPL
{
    public static void main(String args[])
	throws Exception
    {
	for (int i = 0;i < args.length; i++)
	    {
		System.err.println("processFile(\"" + args[i] + "\")");
		processFile(args[i]);
	    }
	return ;
    }
    
    private static void processFile(String str)
	throws Exception
    {
	long fileNumber = 0;
	FileOutputStream o = null;	
	long totalBytes = 0;
	long maxBytes = 0x20000000; // 500M
	
	byte magic[] = new byte[16];
	byte systemHeader[] = null; 
	
	byte dataMagic[] = new byte[16];
	byte dataHeader[] = null;
	byte dataImage[] = null;
	
	byte footer1[] = {(byte)0xF7, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x49, (byte)0x49, (byte)0x20, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,};
	byte footer2[] = {(byte)0x00, (byte)0x4F, (byte)0xD4, (byte)0x77, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,};

	long frame_i = 0, size = 0, frame_next = 0;
	int width = 0, height = 0, slice = 0, s_num = 0,
	    year = 0, month = 0, date = 0, hour = 0, min = 0;
	
	int subt = 0;

	System.err.println("file size = " + (size = (new File(str)).length()) + "byte[s] (" + Long.toHexString(size) + ")");
	FileInputStream f = new FileInputStream(str);
	// 1. read system header
	// magic number F5 01 01 01 49 49
	f.read(magic);
	System.err.print("[System Header] ");
	for (int i = 0 ; i < 8 ; i++)
	    System.err.print(byteToHexString(magic[i]) + " ");
	frame_next = (magic[7] & 0xff)*0x100 + (magic[6] & 0xff) - 0x10;
	System.err.println("... 0x" + Long.toHexString(frame_next) + "[bytes]");
	systemHeader = new byte[(int)frame_next];
	f.read(systemHeader);
	
	while(true)
	    {
		f.read(dataMagic);
		if (new String(dataMagic).equals(new String(footer1)))
		    {
			o.write(footer1);o.write(footer2);
			o.close();
			f.close();
			System.err.println("[EOF]");
			break ;
		    }
		System.out.print("[D] ");
		for (int i = 0 ; i < 8 ; i++)
		    System.err.print(byteToHexString(dataMagic[i]) + " ");
		frame_next = (dataMagic[7] & 0xff)*0x100 + (dataMagic[6] & 0xff) - 0x10;
		System.err.print(" 0x" + Long.toHexString(frame_next) + "[bytes] ");
		dataHeader = new byte[(int)frame_next];
		f.read(dataHeader);
		
		width = (dataHeader[3] & 0xff)*0x100 + (dataHeader[2] & 0xff);
		height = (dataHeader[5] & 0xff)*0x100 + (dataHeader[4] & 0xff);
		slice = (dataHeader[7] & 0xff)*0x100 + (dataHeader[6] & 0xff);
		s_num = (dataHeader[9] & 0xff)*0x100 + (dataHeader[8] & 0xff);
		System.err.print(width + "x" + height + " [" + slice + "slice(s)] (" + s_num + ")");

		year = (dataHeader[0xa0+9] & 0xff)*0x100 + (dataHeader[0xa0+8] & 0xff);
		month = (dataHeader[0xa0+11] & 0xff)*0x100 + (dataHeader[0xa0+10] & 0xff);
		date = (dataHeader[0xa0+13] & 0xff)*0x100 + (dataHeader[0xa0+12] & 0xff);
		hour = (dataHeader[0xa0+15] & 0xff)*0x100 + (dataHeader[0xa0+14] & 0xff);
		System.err.print(year + "/" + month + "/" + date + " " + hour + ":");
		min = (dataHeader[0xb0+1] & 0xff)*0x100 + (dataHeader[0] & 0xff);
		System.err.print(min + " ");
		
		frame_next = width*height*slice*2;
		System.err.print("0x" + Long.toHexString(frame_next) + "[bytes]");

		dataImage = new byte[(int)frame_next];
		f.read(dataImage);
		
		if (o == null)
		    {
			System.out.println("new FileOutputStream(\"" + str + "." + fileNumber + "\")");
			o = new FileOutputStream(str + "." + fileNumber);
			o.write(magic);o.write(systemHeader);
		    }
		if(totalBytes > maxBytes)
		    {
			o.write(footer1);o.write(footer2);
			o.close();
			fileNumber ++;
			System.out.println("new FileOutputStream(\"" + str + "." + fileNumber + "\")");
			o = new FileOutputStream(str + "." + fileNumber);
			o.write(magic);o.write(systemHeader);
			totalBytes = 0;
			subt = s_num;
		    }
		totalBytes += frame_next;
		
		// correct s_num (0...)
		s_num -= subt;
		dataHeader[8] = (byte)(((s_num) >>> 0) & 0xff);
		dataHeader[9] = (byte)(((s_num) >>> 8) & 0xff);
		System.err.println((dataHeader[9] & 0xff)*0x100 + (dataHeader[8] & 0xff) + ")");
		
		o.write(dataMagic);o.write(dataHeader);o.write(dataImage);
	    }
    }
    
    /**
     * byte value to hexString.
     * 
     * @param b byte-data
     * @return hexa-decimal string of byte b.
     */
    private static String byteToHexString(byte b)
    {
        String s = "0" + Integer.toHexString(b & 0xFF);
        String hex = s.substring(s.length() - 2, s.length());
        return hex.toUpperCase();
    }    
}
