Author Topic: FF7/FF8 LZS compression 'challenges' and Files (weee) [Fice]  (Read 4669 times)

Cyberman

  • *
  • Posts: 1572
    • View Profile
I'm still having problems decompressing the LZS compressed files using the algorhythm Fice has give.  I also do have a small 'update' to the documentation for it, LZOFFSET is 18 for the following reason 3 is your minimum length 18 is your maximum length.  The makers of the format likely surmized that if you can't go back at LEAST your maximum length and read all that data you will end up trying to read from unwritten data on the output (a bad thing) so they put that in to alleviate potention errors.

If I find the background files I'll be happy (smirk) either they are MIM BSX or DAT my guess is DAT or MIM.  Anyhow here is what I am using to decompress LZS (pardon the lack of commments).
Code: [Select]
#define  LZLEN    3
#define  LZOFFSET 18
AnsiString  TMain::LZSDec(AnsiString FName)
{
   fstream     File;
   fstream     Out;
   AnsiString  Return;
   char        Ctrl;
   short int   CtrlBits;
   unsigned short Ref;
   int         Offset, Len, DestLen, FileEnd;
   int         Pos, NewP, Result;
   char        OutB[64];

   File.open(FName.c_str(), fstream::in | fstream::binary);
   Return = "temp";
   Out.open(Return.c_str(), fstream::out | fstream::in | fstream::binary);
   if (File.is_open())
   {
      File.seekg(0, SEEK_END);
      FileEnd = File.tellg();
      File.seekg(0, SEEK_SET);
      if (Out.is_open())
      {
         DestLen = 0;
         CtrlBits = 0;
         Ctrl = 0xFF;
         while ((File.tellg() < FileEnd) && !File.eof())
         {
            if (CtrlBits == 0)
            {  // read more control bits here
               File.read(&Ctrl, 1);
               CtrlBits = 8;
            }
            if ((Ctrl & 0x01) == 0)
            {
               File.read((char *)&Ref, 2);
               Offset = (Ref & 0x00FF) << 4;
               Offset+= (Ref & 0x0F000) >> 12;
               Len = ((Ref & 0xF) >> 8) + LZLEN;
               Pos = Out.tellg();
               // the new position is
               // the current position - 18 - Offset
               NewP = Pos - LZOFFSET - Offset;
               // and the result with 0xFFF
               NewP &= 0x0FFF;
               if (NewP == 0)
                  break;
               // if the Offset position is <=
               // the current Output position
               if (NewP <= Pos)
               {  int I;

                  Offset = Len / NewP;
                  // the resulting position is within the file
                  Out.seekg(Pos - NewP, SEEK_SET);
                  // the Length is greater than the offset
                  if (Offset > 0)
                  {  // read the New Position bytes
                     Out.read(OutB, NewP);
                     // now write the data (Length / Offset) times
                     for (I = 0; I < Offset; I++)
                     {  // write out data here :)
                        Out.write(OutB, NewP);
                     }
                  }
                  else
                  {  // read len bytes
                     Out.read(OutB, Len);
                        // move back to our position
                     Out.seekg(Pos, SEEK_SET);
                     // write len bytes
                     Out.write(OutB, Len);
                  }
               }
               else
               {  // it's beyond the begining of the file
                  // so we just write out 0's
                  memset(OutB, 0, Len);
                  Out.write(OutB, Len);
               }
               DestLen += Len;
            }
            else
            {  // copy the byte
               File.read(OutB, 1);
               Out.write(OutB, 1);
               DestLen ++;
            }
            Ctrl >>=1;
            CtrlBits--;
         }
         Out.close();
      }
      File.close();
   }
   return Return;
}

ficedula

  • *
  • Posts: 2178
    • View Profile
    • http://www.ficedula.co.uk
FF7/FF8 LZS compression 'challenges' and Files (weee) [Fice]
« Reply #1 on: 2003-03-29 18:52:33 »
Eh, that description really is out of date. I should update it, or take it down, or do something with it...

I'll try and remember to do that.

Cyberman

  • *
  • Posts: 1572
    • View Profile
FF7/FF8 LZS compression 'challenges' and Files (weee) [Fice]
« Reply #2 on: 2003-03-29 21:40:49 »
Ack.. ok.. I'm trying to use this with the PSX version, it appears to me the format is not the same for people models as it is with the PC.p format.  I'm not sure what the data is in it.  I know bit maps are stuffed into it though.

Cyb

ficedula

  • *
  • Posts: 2178
    • View Profile
    • http://www.ficedula.co.uk
FF7/FF8 LZS compression 'challenges' and Files (weee) [Fice]
« Reply #3 on: 2003-03-30 11:13:34 »
New version of my LZS document up on my website.

And, incidentally, you ARE allowed to read from unwritten output; the document describes what you should do when it happens. FF7 does do that in some of the field files ;)

mirex

  • *
  • Posts: 1645
    • View Profile
    • http://mirex.mypage.sk
FF7/FF8 LZS compression 'challenges' and Files (weee) [Fice]
« Reply #4 on: 2003-03-31 11:05:24 »
Uhm im not sure but i think i read in some lzs description that if you read from negative offsets (before starting of file) you should write zeroes, and if you write from end of file its like this:

source, 6 bytes: abcdef
when reading 10 bytes from position 3 it should give you: defdefdefd

ficedula

  • *
  • Posts: 2178
    • View Profile
    • http://www.ficedula.co.uk
FF7/FF8 LZS compression 'challenges' and Files (weee) [Fice]
« Reply #5 on: 2003-03-31 15:48:54 »
Yep, that's what my document says at any rate... ;)
Both are correct, and as I've said, FF7 uses both in some of its files.

Cyberman

  • *
  • Posts: 1572
    • View Profile
It works now
« Reply #6 on: 2003-03-31 16:26:44 »
A few small changes and decoding works.. now all I need to do is be able to read the PSX model information.  Minor detail I suppose, it looks like everything is packed together (argh) So I suppose deciphering it might be 'fun' I wonder if the repacked them for the PSX (IE smaller footprint).

Cyb