#!/usr/bin/env perl

#    imp_dump.pl Copyright(C) 2008 Nick Rapallo, nrapallo@yahoo.ca
#
#    version 0.1 - 6 Oct 2008
#    Dump .imp details to screen and extract components like text/pics/links
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

#use GD::Image;
#use Getopt::Mixed;
use File::Basename;
use Cwd;

#select 1 for some lengthy records printout
my $opt_verbose = 1;        

#use strict;

#use vars qw ($opt_1200 $opt_1150 $opt_1100 $opt_verbose $opt_debug);

#Getopt::Mixed::getOptions ("1200 1150 1100 verbose debug);

sub fetch_TOC_header {
    my $screen_print = shift;
    my $header_print = shift;
    
    if ($imp_version == 1) {
        #1200/1150 Version 1 Header (10 bytes)
        read (FH,$imp_TOC,10);
        ($TOC_filename, $TOC_unknown, $TOC_filesize) = unpack("a4nN",$imp_TOC);
        if ($screen_print) {
            if ($header_print) { print "\n ======== $TOC_filename ========\n"; }
            if ($TOC_filename eq "    "  || $TOC_filename eq "DATA.FRK") {
               printf " File:DATA.FRK, \$%04X, Filesize:%7d\n", $TOC_unknown, $TOC_filesize;
            } else {
               printf " Filename:$TOC_filename, \$%04X, Filesize:%7d\n", $TOC_unknown, $TOC_filesize;
            }
        }
    } elsif ($imp_version == 2) {
        #1200/1150 Version 2 Header (20 bytes)
        read (FH,$imp_TOC,20);
        ($TOC_filename, $TOC_unknown1, $TOC_filesize, $TOC_filetype, $TOC_unknown2) = unpack("a4NNa4N",$imp_TOC);
        if ($screen_print) { 
            if ($header_print) { print "\n ======== $TOC_filetype ========\n"; }
            if ($TOC_filename eq "    "  || $TOC_filename eq "DATA.FRK") {
               printf " File:DATA.FRK, \$%04X, Filesize:%7d, Filetype:$TOC_filetype, \$%04X\n", $TOC_unknown1, $TOC_filesize, $TOC_unknown2; 
            } else {
               printf " Filename:$TOC_filename, \$%04X, Filesize:%7d, Filetype:$TOC_filetype, \$%04X\n", $TOC_unknown1, $TOC_filesize, $TOC_unknown2; 
            }
        }
    } else {
    	print "Warning:  unknown imp version $imp_version.\n";
    }
}

sub fetch_TOC_stnd_header {
    my $screen_print = shift;

    #Standard 1200/1150 Header (32 bytes)
    read (FH,$TOC_header,32);
    ($TOC_constant01, $TOC_filenameI, $TOC_unknown1, $TOC_offsetI, $TOC_unknown2, $TOC_unknown3, $TOC_unknown4, $TOC_unknown5, $TOC_unknown6)
        = unpack("na4NNnNNNN",$TOC_header);
    if ($screen_print) {
        printf " Header:TOCconst:%04X, TOCfname:$TOC_filenameI, TOCoffset:%7d\n", $TOC_constant01, $TOC_offsetI;
        if ($TOC_unknown1 + $TOC_unknown2 + $TOC_unknown3 + $TOC_unknown4 + $TOC_unknown5 + $TOC_unknown6 != 0  && $opt_verbose) {
            printf " Header:\$%08X, Unknown:\$%04X, \$%08X, \$%08X, \$%08X, \$%08X\n", $TOC_constant01, $TOC_unknown1, $TOC_offsetI, $TOC_unknown2, $TOC_unknown3, $TOC_unknown4, $TOC_unknown5, $TOC_unknown6;
        }
        $datalen = $TOC_offsetI - 32;
        $indexlen = $TOC_filesize - $TOC_offsetI;
        print " Data length = $datalen, Index length = $indexlen\n"; 
    }
}
 
sub fetch_TOC_index1 {
    my $screen_print = shift;

    if ($REB1200) {
        #Standard 1200 Header (12 bytes)
        read (FH,$TOC_index1,12) ;
        ($Index1_const1, $Index1_len, $Index1_offset, $Index1_const0)
            = unpack("nNNn",$TOC_index1);
        if ($screen_print) { printf " Index1:Index1_const1:%04X, len:%6d, offset:%7d, const0:%04X\n", $Index1_const1, $Index1_len, $Index1_offset, $Index1_const0; }
    } else {
        #Standard 1150 Header (14 bytes)
        read (FH,$TOC_index1,14) ;
        ($Index1_const1, $Index1_len1, $Index1_len2, $Index1_offset1, $Index1_offset2, $Index1_const0)
            = unpack("vvvvvV",$TOC_index1);
        $Index1_len = $Index1_len1*65536 + $Index1_len2;
        $Index1_offset = $Index1_offset1*65536 + $Index1_offset2;
        if ($screen_print) { printf " Index1:Index1_const1:%04X, len:%6d, offset:%7d, const0:%04X\n", $Index1_const1, $Index1_len, $Index1_offset, $Index1_const0; }
    }
}

sub fetch_TOC_index2 {
    my $screen_print = shift;

    if ($REB1200) {
        #Standard 1200 Header (12 bytes)
        read (FH,$TOC_index2,12) ;
        ($Index2_const1, $Index2_len, $Index2_offset, $Index2_const0)
            = unpack("nNNn",$TOC_index2);
        if ($screen_print) { printf " Index2:Index2_const1:%04X, len:%6d, offset:%7d, const0:%04X\n", $Index2_const1, $Index2_len, $Index2_offset, $Index2_const0; }
    } else {
        #Standard 1150 Header (14 bytes)
        read (FH,$TOC_index2,14) ;
        ($Index2_const1, $Index2_len1, $Index2_len2, $Index2_offset1, $Index2_offset2, $Index2_const0)
            = unpack("vvvvvV",$TOC_index2);
        $Index2_len = $Index2_len1*65536 + $Index2_len2;
        $Index2_offset = $Index2_offset1*65536 + $Index2_offset2;
        if ($screen_print) { printf " Index2:Index2_const1:%04X, len:%6d, offset:%7d, const0:%04X\n", $Index2_const1, $Index2_len, $Index2_offset, $Index2_const0; }
    }
}

my $fullpathfilename = shift;

my $idversion = "version 0.1";
my $usage = 'imp_dump ImpSource.imp';
if (not defined $fullpathfilename){
    print "Usage: $usage ($idversion)\n";
    die "\n" unless 0;
}

my $dirhere = cwd;
my ($fnbody,$fnpath,$fnext) = fileparse("$fullpathfilename",'\.\w+');
my $filename = $fnbody . $fnext;
my $explodedir = $fnbody;

$imp = $fullpathfilename;
$outimp = $filename;

my $imp_header;
my $imp_Book_Prop;
my $imp_RES_dirname;
my $Pic_ID;

# If we can't open a file, PANIC!
open (FH,$imp) or die ("couldn't open $imp\n");
binmode(FH);

chdir $fnpath;
mkdir $explodedir;
chdir $explodedir;

# Read first 48 bytes into buffer
read (FH,$imp_header,48) ;
 
# Use "n" which is most significant byte is first - big endian
# get 8 chars, skip 8 bytes, then pick up 2-byte integer (3 times) - big endian
# skip 4 bytes, skip 4 bytes again, then pick up 4-byte integers (twice) - big endian
# pick up 2-byte integer (2 times) - big endian and skip 4 bytes
# (v means 2 byte integer - little endian and V 4 byte integer - little endian; see the manual for unpack )
($imp_version, $imp_signature, $imp_unknown1, $imp_unknown2, $imp_countF, $imp_len_RES_dirname, $imp_countR, $imp_unknown3, $imp_unknown4, $imp_compression, $imp_encryption, $imp_type, $imp_zoom, $imp_unknown5)
   = unpack("na8NNnnnNNNNnnN",$imp_header);

#tz means type/zoom state
#==
#00 means Softbook 200/250e
#10 means REB 1200/GEB 2150
#20 means GEB 1150/EBW 1150
$imp_type = $imp_zoom >> 4;
$imp_zoom = $imp_zoom - $imp_type*16;
#set type of imp being processed i.e. REB 1200/Softbook or EBW 1150
$REB1200 = $imp_type == 1 || $imp_type == 0;

my $imp_type_device = "Unknown ImpDevice";
if ($imp_type == 0) { $imp_type_device = "Softbook 200/250e"; }
elsif ($imp_type == 1) { $imp_type_device = "REB 1200/GEB 2150"; }
elsif ($imp_type == 2) { $imp_type_device = "EBW 1150/GEB 1150"; }

if ($imp_signature ne "BOOKDOUG") {
    die "Error: $imp_signature, not a .imp file.\n" unless 0;
}

if ($imp_version != 1 && $imp_version != 2) {
    die "Error:  unknown version $imp_version.\n" unless 0;
}

# Read book properties into buffer
read (FH,$imp_Book_Prop,$imp_countR-24);
($imp_ID, $imp_Category, $imp_Subcategory, $imp_Title, $imp_Lname, $imp_Mname, $imp_Fname) 
   = unpack("Z*Z*Z*Z*Z*Z*Z*",$imp_Book_Prop);

my $imp_len_Book_Prop = length($imp_ID . $imp_Category . $imp_Subcategory . $imp_Title . $imp_Lname . $imp_Mname . $imp_Fname)+7;

# Read .RES directory name into buffer
read (FH,$imp_RES_dirname,$imp_len_RES_dirname);

# Print out Header details followed by each file type in TOC
print "imp_dump.pl ($idversion) Copyright (C) 2008 Nick Rapallo (nrapallo)\n";
print "====================================================================\n";
print "Imp Filename:$imp\n";
print "== Header (48 bytes) ==\n";
print "Version:$imp_version, \"$imp_signature\", CountRESFiles:$imp_countF, LengthRESdirname:$imp_len_RES_dirname, CountRemain:$imp_countR\nCompression:$imp_compression, Encryption:$imp_encryption, ImpType:$imp_type ($imp_type_device), ZoomState:$imp_zoom\n";
if ($imp_unknown1 + $imp_unknown2 + $imp_unknown3 + $imp_unknown4 + $imp_unknown5 != 0) {
    printf "Unknown1:\$%08X, 2:\$%08X, 3:\$%08X, 4:\$%08X, 5:\$%08X\n", $imp_unknown1, $imp_unknown2, $imp_unknown3, $imp_unknown4, $imp_unknown5;
}
print "=== Book Properties ===\n";
print "Book_Prop_length:$imp_len_Book_Prop\n";
printf"ebookID(%03d):$imp_ID\nCategory(%03d):$imp_Category, SubCat(not used)(%03d):$imp_Subcategory\nTitle(%03d):$imp_Title\nLName(%03d):$imp_Lname, MName(%03d):$imp_Mname, AuthorFNname(%03d):$imp_Fname\n", length($imp_ID), length($imp_Category), length($imp_Subcategory), length($imp_Title), length($imp_Lname), length($imp_Mname), length($imp_Fname);
print "== .RES filename used==\n";
printf"RESdirname(%03d):$imp_RES_dirname\n", length($imp_RES_dirname);

my $imp_offset_TOC = 48+$imp_len_Book_Prop+$imp_len_RES_dirname;
print "====================================================================\n";
print "Header length before .RES Table of Contents:$imp_offset_TOC\n";
print " == Table of Contents ==\n";

#read Table of Contents of .RES directory files
my $i;
my $TOC_filename, $TOC_filesize, $TOC_filetype;

# Read Table of Contents files information
for($i=1;$i<=$imp_countF;$i++)
{
    fetch_TOC_header( 1, 0 );
}

my $imp_TOC_file;
# Read each Table of Contents files in sequence
for($i=1;$i<=$imp_countF;$i++) {

    fetch_TOC_header( 1, 1 );

    if ($TOC_filetype eq "    ") {
    
        read (FH,$DataFrk_record,$TOC_filesize);
        
        if ($imp_compression) { $outfilename = $outimp; } else { $outfilename = $fnbody; }
        open BINFILE, ">$outfilename.txt" or die "Cannot create $outfilename file";
        binmode (BINFILE);
        print BINFILE $DataFrk_record;
        close BINFILE;

        if ($imp_compression) {
            printf "  Extracting compressed DATA.FRK to \"$outfilename.txt\" (%d chars)\n", $TOC_filesize;
            @deimp_args = ("\"$dirhere/deimp.exe\"", "-i", "\"$outfilename.txt\"", "-o", "\"$fnbody.txt\"");
            system(@deimp_args) == 0 or die "system @args failed: $?";
            printf "  and uncompressed text to \"$fnbody.txt\"\n"; 
        } else {
            printf "  Extracting uncompressed DATA.FRK to \"$outfilename.txt\" (%d chars)\n", $TOC_filesize; 
            #@deimp_args = ("\"$dirhere/deimp.exe\"", "-skip", "-i", "\"$outfilename.txt\"", "-o", "\"$fnbody.txt\"");
            #system(@deimp_args) == 0 or die "system @args failed: $?"
        }

    } elsif ($TOC_filetype eq "!!cm") {


        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "!!sw") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        my $sw_length = $TOC_offsetI-32;
        if ($opt_verbose) { printf "  sw_length:$sw_length\n"; }
        #read (FH,$sw_record,$sw_length);

        if ($opt_verbose) { printf "  sw_record:\n   "; }
        read (FH,$sw_record,$sw_length);
        for($j=1;$j<=$sw_length;$j++) {
	    if ($opt_verbose) { printf "%02X",unpack("C", substr($sw_record, $j-1)); }
	    if ($opt_verbose && $j % 2 == 0) { printf " "; }
	    if ($opt_verbose && $j % 16 == 0) { printf "\n   "; }
	}
        if ($opt_verbose) { printf "\n"; }
	
	my $sw_count = ($TOC_filesize-$sw_length-32)/16;
	if (!$REB1200) {
	    $sw_count = ($TOC_filesize-$sw_length-32)/18;
	}
        for($j=1;$j<=$sw_count;$j++) {
	    if ($REB1200) {
	        #1200 index
                read (FH,$sw_indexI,16);
                ($swI_seqnum, $swI_len, $swI_offset, $swI_const4, $swI_filetype)
                    = unpack("nNNna4",$sw_indexI);
                if ($opt_verbose) { printf " Index%02d:seqnum:%3d, len:%3d, offset:%5d, \$%04X, filetype:$swI_filetype\n",
                    $j, $swI_seqnum, $swI_len, $swI_offset, $swI_const4, $swI_filetype; }
	    } else {
	        #1150 index
                read (FH,$sw_indexI,18);
                ($swI_seqnum, $swI_len1, $swI_len2, $swI_offset1, $swI_offset2, $swI_unknown, $swI_const4, $swI_filetype)
                    = unpack("vvvvvvva4",$sw_indexI);
                $swI_len = $swI_len1*65536 + $swI_len2;
                $swI_offset = $swI_offset1*65536 + $swI_offset2;
                if ($opt_verbose) { printf " Index%02d:seqnum:%3d, len:%3d, offset:%5d, \$%04X, \$%04X, filetype:$swI_filetype\n",
                    $j, $swI_seqnum, $swI_len, $swI_offset, $swI_unknown, $swI_const4, $swI_filetype; }
	    }
        }

    } elsif ($TOC_filetype eq "AncT") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$AncT_record,$TOC_offsetI-32);
        fetch_TOC_index1 ( 1 );
        fetch_TOC_index2 ( 1 );
        
	#Resource ID 1 is for small view
	my $AncT_offset1 = $Index1_offset-32;
        if ($REB1200) {
            $AncT_count1 = unpack("N", substr($AncT_record, $AncT_offset1));
        } else {
            $AncT_count1 = unpack("V", substr($AncT_record, $AncT_offset1));
        }
	$AncT_offset1 += 4;
	print "  Number of Anchors1 (small view) indexed = $AncT_count1\n";
	if ($opt_verbose) { 
	    for($j=0;$j<$AncT_count1;$j++) {
                if ($REB1200) {
                    ($AncT_offset, $AncT_pagenum)
                        = unpack("NN", substr($AncT_record, $AncT_offset1+$j*8));
                } else {
                    ($AncT_offset, $AncT_pagenum)
                        = unpack("VV", substr($AncT_record, $AncT_offset1+$j*8));
                }
                printf "   offset:%7d, pagenum:%5d ", $AncT_offset, $AncT_pagenum;
	        if (($j+1) % 2 == 0) { printf "\n"; }
            }
            if (($j+1) % 2 == 0) { printf "\n"; }
        }

	#Resource ID 0 is for large view
	my $AncT_offset2 = $Index2_offset-32;
        if ($REB1200) {
            $AncT_count2 = unpack("N", substr($AncT_record, $AncT_offset2));
        } else {
            $AncT_count2 = unpack("V", substr($AncT_record, $AncT_offset2));
        }
	$AncT_offset2 += 4;
	print "  Number of Anchors2 (large view) indexed = $AncT_count2\n";
	if ($opt_verbose) { 
	    for($j=0;$j<$AncT_count2;$j++) {
                if ($REB1200) {
                    ($AncT_offset, $AncT_pagenum)
                        = unpack("NN", substr($AncT_record, $AncT_offset2+$j*8));
                } else {
                    ($AncT_offset, $AncT_pagenum)
                        = unpack("VV", substr($AncT_record, $AncT_offset2+$j*8));
                }
                printf "   offset:%7d, pagenum:%5d ", $AncT_offset, $AncT_pagenum;
	        if (($j+1) % 2 == 0) { printf "\n"; }
            }
            if (($j+1) % 2 == 0) { printf "\n"; }
        }

    } elsif ($TOC_filetype eq "AnTg") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "BGcl") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }

        read (FH,$BGcl_record,8) ;
        ($BGcl_const1, $BGcl_red, $BGcl_sred, $BGcl_green, $BGcl_sgreen, $BGcl_blue, $BGcl_sblue )
            = unpack("nCCCCCC",$BGcl_record);
        printf "  BGcl_const1:%02X, Red:%02X (\$%02X), Green:%02X (\$%02X), Blue:%02X (\$%02X)\n", $BGcl_const1, $BGcl_red, $BGcl_sred, $BGcl_green, $BGcl_sgreen, $BGcl_blue, $BGcl_sblue;

        fetch_TOC_index1 ( 1 );

    } elsif ($TOC_filetype eq "BPgz") {


        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_filesize-32);
        print "  Need to fill in these details... \n";
    
    } elsif ($TOC_filetype eq "BPgZ") {


        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_filesize-32);
        print "  Need to fill in these details... \n";
    
    } elsif ($TOC_filetype eq "Devm") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        my $Devm_count = $TOC_offsetI - 32;
        read (FH,$Devm_record,$Devm_count);
        ($Devm_ID)
            = unpack("n",$Devm_record);
        printf "   DeviceM:%3d (%d byte)\n", $DevmID, $Devm_count;
        
        fetch_TOC_index1 ( 1 );
    
    } elsif ($TOC_filetype eq "eLnk") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }

    } elsif ($TOC_filetype eq "ESts") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        my $ESts_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;

        my $ESts_count = ($TOC_offsetI - 32);
	if (!$REB1200) {
            $ESts_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
	}
	print "  Extended style information:\n";
        read (FH,$ESts_record,$ESts_count);
        ($ESts_Res1A, $ESts_Res1B, $ESts_Res1C)
            = unpack("NNN",$ESts_record);
        printf "   ESts_Resource1:\$%08X, \$%08X, \$%08X\n", $ESts_Res1A, $ESts_Res1B, $ESts_Res1C;
        ($ESts_Res11, $ESts_Res12, $ESts_Res13, $ESts_Res14)
            = unpack("NNNN",$ESts_record);
        printf "    1(x-sbp-orphan-pull):\$%08X, \$%08X, \$%08X, \$%08X\n", $ESts_Res11, $ESts_Res12, $ESts_Res13, $ESts_Res14;
        ($ESts_Res21, $ESts_Res22, $ESts_Res23, $ESts_Res24)
            = unpack("NNNN",$ESts_record);
        printf "    2(x-sbp-widow-push) :\$%08X, \$%08X, \$%08X, \$%08X\n", $ESts_Res21, $ESts_Res22, $ESts_Res23, $ESts_Res24;
        ($ESts_Res2A, $ESts_Res2B, $ESts_Res2C)
            = unpack("NNN",$ESts_record);
        printf "   ESts_Resource2:\$%08X, \$%08X, \$%08X\n", $ESts_Res2A, $ESts_Res2B, $ESts_Res2C;

	for($j=1;$j<=$ESts_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "HfPz") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "HfPZ") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "Hyp2") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "Lnks") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "Mrgn") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }

        read (FH,$Mrgn_record,4) ;
        ($Mrgn_const1, $Mrgn_const2)
            = unpack("nn",$Mrgn_record);
        printf "  Margin1 (Small view):%04X\n  Margin2 (Large view):%04X\n", $Mrgn_const1, $Mrgn_const2;

        fetch_TOC_index1 ( 1 );
        fetch_TOC_index2 ( 1 );

    } elsif ($TOC_filetype eq "Pc31") {


        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "Pcz0" || $TOC_filetype eq "PcZ0") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        my $Pcz0_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Pcz0_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
	}
        if ($TOC_filetype eq "Pcz0") { print "  Small view:\n"; } else { print "  Large view:\n"; }

        my $Pcz0_count = ($TOC_offsetI - 32)/46;
	print "  Number of images referenced = $Pcz0_count\n";
	for($j=1;$j<=$Pcz0_count;$j++) {
            read (FH,$Pcz0_record,46);
            ($Pcz0_constI, $Pcz0_horiz, $Pcz0_vert, $Pcz0_width, $Pcz0_height, $Pcz0_constB, $Pcz0_offset, $Pcz0_const01, $Pcz0_imgtype, $Pcz0_const1, $Pcz0_constU, $Pcz0_imgID, $Pcz0_const0)
                = unpack("a4NNNNnNNa4nnna6",$Pcz0_record);
            if ($opt_verbose) {
	        printf "   $Pcz0_constI, horiz:%3d, vert:%3d, width:%3d, height:%3d, \$%04X, offset:%7d, imgtype:%04s, imgID:%04X\n", $Pcz0_horiz, $Pcz0_vert, $Pcz0_width, $Pcz0_height, $Pcz0_constB, $Pcz0_offset, $Pcz0_imgtype, $Pcz0_imgID, $Pcz0_const0;
            }
        }

	for($j=1;$j<=$Pcz0_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
      
    } elsif ($TOC_filetype eq "Pcz1" || $TOC_filetype eq "PcZ1") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }

        if ($TOC_filetype eq "Pcz1") { print "  Small view:\n"; } else { print "  Large view:\n"; }
       
        if ($TOC_constant01 == 1) {

            my $Pcz1_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
        
            my $Pcz1_count = $TOC_offsetI - 32;
	    if (!$REB1200) {
                $Pcz1_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
	    }
	    for($j=1;$Pcz1_count>0;$j++) {
                read (FH,$Pcz1_record,30);
                $Pcz1_count -= 30; 
                ($Pcz1_constB, $Pcz1_left, $Pcz1_top, $Pcz1_width, $Pcz1_height, $Pcz1_const9, $Pcz1_constF, $Pcz1_const1)
                    = unpack("a4NNNNnNN",$Pcz1_record);
                $Pcz1_left &= 0xBFFF;
                $Pcz1_top &= 0xBFFF;
                if ($Pcz1_constB eq "borp") { 
                    printf "   $Pcz1_constB, left:%3d, top:%3d, width:%3d, height:%3d, \$%08X\n", $Pcz1_left, $Pcz1_top, $Pcz1_width, $Pcz1_height, $Pcz1_const9;
                } else {
                    read (FH,$Pcz1_constA,8);
                    $Pcz1_count -= 8; 
                    printf "   $Pcz1_constB, left:%3d, top:%3d, width:%3d, height:%3d, \$%08X, \$%08x\n", $Pcz1_left, $Pcz1_top, $Pcz1_width, $Pcz1_height, $Pcz1_const9, $Pcz1_constA;
                }
            }
	    printf "  Number of cells referenced = %d\n", $j-1;
 
 	    for($j=1;$j<=$Pcz1_indexcount;$j++) {
                fetch_TOC_index1 ( 1 );
            }
        } elsif ($TOC_constant01 == 2) {

            my $Pcz1_indexcount = ($TOC_filesize - $TOC_offsetI)/16 ;
        
            my $Pcz1_count = $TOC_offsetI - 32;
	    if (!$REB1200) {
                $Pcz1_indexcount = ($TOC_filesize - $TOC_offsetI)/18 ;
	    }
            read (FH,$Pcz1_record,$Pcz1_count);
 	    for($j=1;$j<=$Pcz1_indexcount;$j++) {
	        if ($REB1200) {
                    read (FH,$Pcz1_record,16);
                    ($Pcz1_ID, $Pcz1_len, $Pcz1_unknown, $Pcz1_offset, $Pcz1_const0)
                        = unpack("nNNNN",$Pcz1_record);
                    printf "   Pcz1_ID:%04X, len:%7d, unknown:%7d, offset:%7d, \$%08X\n", $Pcz1_ID, $Pcz1_len, $Pcz1_unknown, $Pcz1_offset, $Pcz1_const0;
                } else {
                    read (FH,$Pcz1_record,18);
                    ($Pcz1_ID, $Pcz1_unknown1, $Pcz1_len, $Pcz1_unknown2, $Pcz1_offset, $Pcz1_const0)
                        = unpack("vvVVVv",$Pcz1_record);
                    printf "   Pcz1_ID:%04X, \$%04X, len:%7d, unknown:%7d, offset:%7d, \$%08x\n", $Pcz1_ID, $Pcz1_unknown1, $Pcz1_len, $Pcz1_unknown2, $Pcz1_offset, $Pcz1_const0;
                }
            }
       } else {
            print "Warning:  unknown Pcz1/PcZ1 version $TOC_constant01.\n";
        }
    
    } elsif ($TOC_filetype eq "pInf") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        my $pInf_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $pInf_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
        
        my $pInf_count = ($TOC_offsetI - 32)/10;
	print "  Number of pInf referenced = $pInf_count\n";
	for($j=1;$j<=$pInf_count;$j++) {
            read (FH,$pInf_record,10);
            ($pInf_const13, $pInf_const0, $pInf_lpnum, $pInf_countI, $pInf_const32)
                = unpack("nnnnn",$pInf_record);
            printf "   \$%04X, \$%04X, LastPageNumber:%5d, ImgResCount:%5d, \$%04X\n", $pInf_const13, $pInf_const0, $pInf_lpnum, $pInf_countI, $pInf_const32;
        }

	for($j=1;$j<=$pInf_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "PPic") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }

        my $PPic_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $PPic_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
        
        my $PPic_count = ($TOC_offsetI - 32)/18;
	print "  Number of PPic referenced = $PPic_count\n";
	for($j=1;$j<=$PPic_count;$j++) {
            read (FH,$PPic_record,18);
            ($PPic_const3, $PPic_countC, $PPic_constB, $PPic_countI, $PPic_constP)
                = unpack("nNNNN",$PPic_record);
            printf "   \$%04X, countCells:%3d, Borders:%08X, countPics:%3d, Pictures:%08X\n", $PPic_const3, $PPic_countC, $PPic_constB, $PPic_countI, $PPic_constP;
        }

	for($j=1;$j<=$PPic_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "Styl") {


        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "StRn") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        my $StRn_count = ($TOC_offsetI - 32)/8;
	print "  Number of StRn referenced = $StRn_count\n";
	for($j=1;$j<=$StRn_count;$j++) {
            read (FH,$StRn_record,8);
            if ($REB1200) {
                ($StRn_offset, $StRn_styleI)
                    = unpack("NN",$StRn_record);
            } else {
                ($StRn_offset, $StRn_styleI)
                    = unpack("VV",$StRn_record);
            }
            printf "   StyleTextOffset:%7d, StyleIndex:%7d", $StRn_offset, $StRn_styleI;
	    if ($j % 2 == 0) { printf "\n"; }
        }
        if ($j % 2 == 0) { printf "\n"; }
        
        fetch_TOC_index1 ( 1 );
    
    } elsif ($TOC_filetype eq "StR2") {


        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_filesize-32);
        print "  Need to fill in these details... \n";
    
    } elsif ($TOC_filetype eq "Tabl") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
 
    } elsif ($TOC_filetype eq "TCel") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }

        read (FH,$TCel_record,$TOC_filesize-32);
        print "  Need to fill in these details when .imp has a table\n";
        
    } elsif ($TOC_filetype eq "TRow") {


        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_filesize-32);
        print "  Need to fill in these details when .imp has a table\n";
    
    } elsif ($TOC_filetype eq "ImRn") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        my $ImRn_count = ($TOC_offsetI - 32)/32;
        if (!$REB1200) {
            #data record size is 34 bytes plus 2 bytes except last record,
            #so '+2' then divide by '34+2'
            $ImRn_count = ($TOC_offsetI - 32+2)/36;
        }
	print "  Number of images indexed = $ImRn_count\n";
	for($j=1;$j<=$ImRn_count;$j++) {
            if ($REB1200) {
                read (FH,$ImRn_record,32);
                ($ImRn_constF, $ImRn_width, $ImRn_height, $ImRn_const0, $ImRn_constB, $ImRn_offset, $ImRn_unknown, $ImRn_imgtype, $ImRn_imgID)
                    = unpack("a8nnNnNNa4n",$ImRn_record);
    	        # the first unpack entry 'a8' ($ImRn_constF) does not yield FF's only 00's - why?
                #printf "  ImRn_constF:%08X, width:%3d, height:%3d, const0:%04X, constB:%02X, offset:%7d, imgtype:%04s, imgID:%5d\n", $ImRn_constF, $ImRn_width, $ImRn_height, $ImRn_const0, $ImRn_constB, $ImRn_offset, $ImRn_unknown, $ImRn_imgtype, $ImRn_imgID;
                printf "   width:%3d, height:%3d, aspect:%2.2f, \$%04X, offset:%7d, \$%08X, imgtype:%04s, imgID:%04X\n", $ImRn_width, $ImRn_height, $ImRn_width/$ImRn_height, $ImRn_constB, $ImRn_offset, $ImRn_unknown, $ImRn_imgtype, $ImRn_imgID;
            } else {
                read (FH,$ImRn_record,34);
                ($ImRn_constF, $ImRn_width, $ImRn_height, $ImRn_const0, $ImRn_constB, $ImRn_unknown1, $ImRn_offset1, $ImRn_offset2, $ImRn_unknown2, $ImRn_imgtype, $ImRn_imgID)
                    = unpack("a8vvVvvvvVa4v",$ImRn_record);
                $ImRn_offset = $ImRn_offset2*65536 + $ImRn_offset1;
                # WHY these extra 2 bytes!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                if ($j != $ImRn_count) { 
                    read (FH,$ImRn_record,2);
                    $ImRn_const2 = unpack("v",$ImRn_record);
                    printf "   width:%3d, height:%3d, aspect:%2.2f, \$%04X, \$%04X, offset:%7d, \$%08X, imgtype:%04s, imgID:%04X, \$%04X\n", $ImRn_width, $ImRn_height, $ImRn_width/$ImRn_height, $ImRn_constB, $ImRn_unknown1, $ImRn_offset, $ImRn_unknown2, $ImRn_imgtype, $ImRn_imgID, $ImRn_const2;
                } else {
    	            # the first unpack entry 'a8' ($ImRn_constF) does not yield FF's only 00's - why?
                    #printf "  ImRn_constF:%08X, width:%3d, height:%3d, const0:%04X, constB:%02X, offset:%7d, imgtype:%04s, imgID:%5d\n", $ImRn_constF, $ImRn_width, $ImRn_height, $ImRn_const0, $ImRn_constB, $ImRn_offset, $ImRn_unknown, $ImRn_imgtype, $ImRn_imgID;
                    printf "   width:%3d, height:%3d, aspect:%2.2f, \$%04X, \$%04X, offset:%7d, \$%08X, imgtype:%04s, imgID:%04X\n", $ImRn_width, $ImRn_height, $ImRn_width/$ImRn_height, $ImRn_constB, $ImRn_unknown1, $ImRn_offset, $ImRn_unknown2, $ImRn_imgtype, $ImRn_imgID;
                }
            }
        }

        fetch_TOC_index1 ( 1 );
    
    } elsif ($TOC_filetype eq "GIF ") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$GIF_record,$TOC_offsetI-32);

        my $GIF_count = ($TOC_filesize-$TOC_offsetI)/12;
        if (!$REB1200) {
            $GIF_count = ($TOC_filesize-$TOC_offsetI)/14;
        }
	print "  Number of GIF images = $GIF_count\n";
	for($j=1;$j<=$GIF_count;$j++) {
            if ($REB1200) {
                fetch_TOC_index1 ( 1 );
            } else {
                read (FH,$TOC_index1,14) ;
                ($Index1_const1, $Index1_unknown, $Index1_len1, $Index1_len2, $Index1_offset1, $Index1_offset2, $Index1_const0)
                    = unpack("vvvvvvv",$TOC_index1);
                $Index1_len = $Index1_len2*65536 + $Index1_len1;
                $Index1_offset = $Index1_offset2*65536 + $Index1_offset1;
                printf " Index1:Index1_const1:%04X,  \$%04X, len:%6d, offset:%7d, \$%04X\n", $Index1_const1, $Index1_unknown, $Index1_len, $Index1_offset, $Index1_const0;
            }
            #printf "  GIF  ID:%04X, \$%04X, imglength:%7d, imgoffset:%7d, \$:%04X\n", $Index1_const1, $Index1_unknown, $Index1_len, $Index1_offset, $Index1_const0;
            $Pic_ID = uc(unpack("H4", pack("n",$Index1_const1))); 
            open BINFILE, ">GIF_$Pic_ID.gif" or die "Cannot create .gif file";
            binmode (BINFILE);
            my $GIF_offset = $Index1_offset - 32;
            $GIF_image = unpack("a$Index1_len", substr($GIF_record, $GIF_offset));
            print BINFILE $GIF_image;
            close BINFILE;
        }
    
    } elsif ($TOC_filetype eq "JPEG") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }

        read (FH,$JPEG_record,$TOC_offsetI-32);

        my $JPEG_count = ($TOC_filesize-$TOC_offsetI)/12;
        if (!$REB1200) {
            $JPEG_count = ($TOC_filesize-$TOC_offsetI)/14;
        }
	print "  Number of JPEG images = $JPEG_count\n";
	for($j=1;$j<=$JPEG_count;$j++) {
            if ($REB1200) {
                fetch_TOC_index1 ( 1 );
            } else {
                read (FH,$TOC_index1,14) ;
                ($Index1_const1, $Index1_unknown, $Index1_len1, $Index1_len2, $Index1_offset1, $Index1_offset2, $Index1_const0)
                    = unpack("vvvvvvv",$TOC_index1);
                $Index1_len = $Index1_len2*65536 + $Index1_len1;
                $Index1_offset = $Index1_offset2*65536 + $Index1_offset1;
                printf " Index1:Index1_const1:%04X,  \$%04X, len:%6d, offset:%7d, \$%04X\n", $Index1_const1, $Index1_unknown, $Index1_len, $Index1_offset, $Index1_const0;
            }
            #printf "  JPEG ID:%04X, \$%04X, imglength:%7d, imgoffset:%7d, \$:%04X\n", $Index1_const1, $Index1_unknown, $Index1_len, $Index1_offset, $Index1_const0;
            $Pic_ID = uc(unpack("H4", pack("n",$Index1_const1))); 
            open BINFILE, ">JPEG_$Pic_ID.jpg" or die "Cannot create .jpg file";
            binmode (BINFILE);
            my $JPEG_offset = $Index1_offset - 32;
            $JPEG_image = unpack("a$Index1_len", substr($JPEG_record, $JPEG_offset));
            print BINFILE $JPEG_image;
            close BINFILE;
        }
    
    } elsif ($TOC_filetype eq "PIC2") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$PIC2_record,$TOC_offsetI-32);

        my $PIC2_count = ($TOC_filesize-$TOC_offsetI)/12;
        if (!$REB1200) {
            $PIC2_count = ($TOC_filesize-$TOC_offsetI)/14;
        }
	print "  Number of PIC2 images = $PIC2_count\n";
	for($j=1;$j<=$PIC2_count;$j++) {
            if ($REB1200) {
                fetch_TOC_index1 ( 1 );
            } else {
                read (FH,$TOC_index1,14) ;
                ($Index1_const1, $Index1_unknown, $Index1_len1, $Index1_len2, $Index1_offset1, $Index1_offset2, $Index1_const0)
                    = unpack("vvvvvvv",$TOC_index1);
                $Index1_len = $Index1_len2*65536 + $Index1_len1;
                $Index1_offset = $Index1_offset2*65536 + $Index1_offset1;
                printf " Index1:Index1_const1:%04X,  \$%04X, len:%6d, offset:%7d, \$%04X\n", $Index1_const1, $Index1_unknown, $Index1_len, $Index1_offset, $Index1_const0;
            }
            #printf "  PIC2 ID:%04X, \$%04X, imglength:%7d, imgoffset:%7d, \$:%04X\n", $Index1_const1, $Index1_unknown, $Index1_len, $Index1_offset, $Index1_const0;
            $Pic_ID = uc(unpack("H4", pack("n",$Index1_const1))); 
            open BINFILE, ">PIC2_$Pic_ID.png" or die "Cannot create .png file";
            binmode (BINFILE);
            my $PIC2_offset = $Index1_offset - 32;
            $PIC2_image = unpack("a$Index1_len", substr($PIC2_record, $PIC2_offset));
            print BINFILE $PIC2_image;
            close BINFILE;
        }
    
    } elsif ($TOC_filetype eq "PICT") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$PICT_record,$TOC_offsetI-32);

        my $PICT_count = ($TOC_filesize-$TOC_offsetI)/12;
        if (!$REB1200) {
            $PICT_count = ($TOC_filesize-$TOC_offsetI)/14;
        }
	print "  Number of PICT images = $PICT_count\n";
	for($j=1;$j<=$PICT_count;$j++) {
            if ($REB1200) {
                fetch_TOC_index1 ( 1 );
            } else {
                read (FH,$TOC_index1,14) ;
                ($Index1_const1, $Index1_unknown, $Index1_len1, $Index1_len2, $Index1_offset1, $Index1_offset2, $Index1_const0)
                    = unpack("vvvvvvv",$TOC_index1);
                $Index1_len = $Index1_len2*65536 + $Index1_len1;
                $Index1_offset = $Index1_offset2*65536 + $Index1_offset1;
                printf " Index1:Index1_const1:%04X,  \$%04X, len:%6d, offset:%7d, \$%04X\n", $Index1_const1, $Index1_unknown, $Index1_len, $Index1_offset, $Index1_const0;
            }
            #printf "  PICT ID:%04X, \$%04X, imglength:%7d, imgoffset:%7d, \$:%04X\n", $Index1_const1, $Index1_unknown, $Index1_len, $Index1_offset, $Index1_const0;
            $Pic_ID = uc(unpack("H4", pack("n",$Index1_const1))); 
            open BINFILE, ">PICT_$Pic_ID.pic" or die "Cannot create .pic file";
            binmode (BINFILE);
            my $PICT_offset = $Index1_offset - 32;
            $PICT_image = unpack("a$Index1_len", substr($PICT_record, $PICT_offset));
            print BINFILE $PICT_image;
            close BINFILE;
            #printf "  width:%3d, height:%3d, constB:%02X, offset:%7d, imgtype:%04s, imgID:%04X\n", $ImRn_width, $ImRn_height, $ImRn_constB, $ImRn_offset, $ImRn_imgtype, $ImRn_imgID;
	}
	
    } elsif ($TOC_filetype eq "PNG ") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$PNG_record,$TOC_offsetI-32);

        my $PNG_count = ($TOC_filesize-$TOC_offsetI)/12;
        if (!$REB1200) {
            $PNG_count = ($TOC_filesize-$TOC_offsetI)/14;
        }
	print "  Number of PNG images = $PNG_count\n";
	for($j=1;$j<=$PNG_count;$j++) {
            if ($REB1200) {
                fetch_TOC_index1 ( 1 );
            } else {
                read (FH,$TOC_index1,14) ;
                ($Index1_const1, $Index1_unknown, $Index1_len1, $Index1_len2, $Index1_offset1, $Index1_offset2, $Index1_const0)
                    = unpack("vvvvvvv",$TOC_index1);
                $Index1_len = $Index1_len2*65536 + $Index1_len1;
                $Index1_offset = $Index1_offset2*65536 + $Index1_offset1;
                printf " Index1:Index1_const1:%04X,  \$%04X, len:%6d, offset:%7d, \$%04X\n", $Index1_const1, $Index1_unknown, $Index1_len, $Index1_offset, $Index1_const0;
            }
            #printf "  PNG  ID:%04X, \$%04X, imglength:%7d, imgoffset:%7d, \$:%04X\n", $Index1_const1, $Index1_unknown, $Index1_len, $Index1_offset, $Index1_const0;
            $Pic_ID = uc(unpack("H4", pack("n",$Index1_const1))); 
            open BINFILE, ">PNG_$Pic_ID.png" or die "Cannot create .png file";
            binmode (BINFILE);
            my $PNG_offset = $Index1_offset - 32;
            $PNG_image = unpack("a$Index1_len", substr($PNG_record, $PNG_offset));
            print BINFILE $PNG_image;
            close BINFILE;
            #printf "  width:%3d, height:%3d, constB:%02X, offset:%7d, imgtype:%04s, imgID:%04X\n", $ImRn_width, $ImRn_height, $ImRn_constB, $ImRn_offset, $ImRn_imgtype, $ImRn_imgID;
        }
    
    } elsif ($TOC_filetype eq "HRle") {


        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "BPos") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "MRPs") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "Ano2") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "Hlts") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "BTok") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "BMks") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }

    } elsif ($TOC_filetype eq "TGNt") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }

    } elsif ($TOC_filetype eq "Form") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "FItm") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "FIDt") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } elsif ($TOC_filetype eq "FrDt") {

        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_offsetI-32);

        #This is temporary
        my $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/12 ;
	if (!$REB1200) {
            $Data_indexcount = ($TOC_filesize - $TOC_offsetI)/14 ;
        }
	for($j=1;$j<=$Data_indexcount;$j++) {
            fetch_TOC_index1 ( 1 );
        }
    
    } else {
 
        print "******** A new filetype encountered!!!\n";
        fetch_TOC_stnd_header( 1 );
        if ($TOC_filesize == 32) { next; }
        
        read (FH,$Data_record,$TOC_filesize-32);
        print "  Need to fill in these details... \n";
    }
}
printf "\n";