Ejemplo n.º 1
0
//Every block has the following header:
// 0 - compressed size includeing header (word)
// 2 - CRC-16 (word)
// 4 - block type
// 6 - uncompressed size (word)
// 8 .. (compressed size + 5) - compressed data (byte array)
dword CompressTFD (byte *pSrc, dword SourceBufferSize, byte *pDest, word TFDType, word SysID, void *pPercentFinishedCallback)
{
  word                  OrigSize, CompSize;
  dword                 OutBufferSize, NrBlocks = 0, FullSize = SourceBufferSize;
  byte                  *FileHeader;

  //PercentFinishedCallback is called for every block. PercentFinished contains a number between 0 and 100
  void (*PercentFinishedCallback) (dword PercentFinished) = pPercentFinishedCallback;

  //Build the tfd file header
  FileHeader = pDest;
  if (pDest)
  {
    STORE_WORD (pDest    , 0x0008);
    STORE_WORD (pDest + 4, SysID);
    STORE_WORD (pDest + 6, 0x0001);
    pDest += 10;
  }
  OutBufferSize = 10;

  while (SourceBufferSize)
  {
    if (PercentFinishedCallback) PercentFinishedCallback ((FullSize - SourceBufferSize) * 100 / FullSize);

    NrBlocks++;
    OrigSize = (SourceBufferSize > 0x7ffa) ? 0x7ffa : SourceBufferSize;

    if (pDest)
    {
      CompSize = CompressBlock (pSrc, OrigSize, pDest + 8);

      //Build the block header
      STORE_WORD (pDest    , CompSize + 6);
      STORE_WORD (pDest + 4, TFDType);
      STORE_WORD (pDest + 6, OrigSize);
      STORE_WORD (pDest + 2, CRC16 (0, pDest + 4, 4 + CompSize));
      pDest += CompSize + 8;
    }
    else CompSize = CompressBlock (pSrc, OrigSize, NULL);

    OutBufferSize    += CompSize + 8;
    SourceBufferSize -= OrigSize;
    pSrc             += OrigSize;
  }

  if (FileHeader)
  {
    STORE_WORD (FileHeader + 8, NrBlocks);
    STORE_WORD (FileHeader + 2, CRC16 (0, FileHeader + 4, 6));
  }

  if (PercentFinishedCallback) PercentFinishedCallback (100);

  return OutBufferSize;
}
Ejemplo n.º 2
0
//Every block has the following header:
// 0 - compressed size includeing header (word)
// 2 - CRC-16 (word)
// 4 - block type
// 6 - uncompressed size (word)
// 8 .. (compressed size + 5) - compressed data (byte array)
dword UncompressTFD (byte *pSrc, byte *pDest, void *pPercentFinishedCallback)
{
  word                  compSize = 0, uncompSize = 0, NrBlocks = 0;
  dword                 outSize = 0, i;

  //PercentFinishedCallback is called for every block. PercentFinished contains a number between 0 and 100
  void (*PercentFinishedCallback) (dword PercentFinished) = pPercentFinishedCallback;

  if (LOAD_WORD(pSrc) != 8) return 0;                              //Invalid header?
  if (CRC16 (0, pSrc + 4, 6) != LOAD_WORD(pSrc + 2)) return 0;     //Invalid header CRC?
  if (LOAD_WORD(pSrc + 6) != 1) return 0;                          //Invalid file version?

  NrBlocks = LOAD_WORD(pSrc + 8);

  pSrc += 10;

  for (i = 0; i < NrBlocks; i++)
  {
    if (PercentFinishedCallback) PercentFinishedCallback (i * 100 / NrBlocks);

    compSize   = LOAD_WORD(pSrc) - 6;
    uncompSize = LOAD_WORD(pSrc + 6);

    if (uncompSize > 0x7ffa) return 0;

    pSrc += 8;

    if(compSize == uncompSize)
    {
      // not compressed data, copy it directly
      if (pDest) memcpy(pDest, pSrc, uncompSize);
    }
    else
    {
      // compressed data, uncompress it
      if (!UncompressBlock (pSrc, compSize, pDest, uncompSize)) return 0;
    }

    if (pDest) pDest += uncompSize;
    pSrc += compSize;
    outSize += uncompSize;
  }
  if (PercentFinishedCallback) PercentFinishedCallback (100);

  return outSize;
}
// UncompressFirmware() is a function wrapper that decodes data blocks
// encoded with AR002 algorithm until the uncompressed size field
// is set to 0xfefe. This is normaly used for the Loader or the Firmware
// inside of the flash memory.
// The expected block structure is as follows:
// 0 - uncompressed size (word)
// 2 - compressed size (incl CRC-16) (word)
// 4 - CRC-16 (word)
// 6 .. (compressed size + 5) - compressed data (byte array)
dword UncompressFirmware(byte *pSrc, byte *pDest, void *pPercentFinishedCallback)
{
  TRACEENTER();

  word                  compSize = 0, uncompSize = 0;
  dword                 outSize = 0, NrBlocks = 0, CurrentBlock = 0;
  byte                  *OrigpSrc;

  if(!pSrc || !pDest)
  {
    TRACEEXIT();
    return 0;
  }

  //PercentFinishedCallback is called for every block. PercentFinished contains a number between 0 and 100
  void (*PercentFinishedCallback) (dword PercentFinished) = pPercentFinishedCallback;

  OrigpSrc   = pSrc;
  uncompSize = LOAD_WORD(pSrc + 0);
  compSize   = LOAD_WORD(pSrc + 2);

  //Count the number of blocks
  while(uncompSize != 0xfefe)
  {
    NrBlocks++;

    if(uncompSize > 0x8000)
    {
      //Uncompressed data block size too large
      TRACEEXIT();

      return 0;
    }

    pSrc += 4;
    pSrc += compSize;

    uncompSize = LOAD_WORD(pSrc + 0);
    compSize   = LOAD_WORD(pSrc + 2);
  }

  pSrc = OrigpSrc;
  uncompSize = LOAD_WORD(pSrc + 0);
  compSize   = LOAD_WORD(pSrc + 2);

  while(uncompSize != 0xfefe)
  {
    if(PercentFinishedCallback) PercentFinishedCallback(CurrentBlock * 100 / NrBlocks);
    CurrentBlock++;

    if(uncompSize > 0x8000)
    {
      //Uncompressed data block size too large
      TRACEEXIT();

      return 0;
    }

    pSrc += 6;

    if(compSize == uncompSize)
    {
      // data not compressed, copy it directly
      if(pDest) memcpy(pDest, pSrc, uncompSize);
    }
    else
    {
      // compressed data, uncompress it
      if(!UncompressBlock(pSrc, compSize, pDest, uncompSize))
      {
        //Uncompress has failed
        TRACEEXIT();
        return 0;
      }
    }

    if(pDest) pDest += uncompSize;
    pSrc += compSize;
    outSize += uncompSize;

    uncompSize = LOAD_WORD(pSrc + 0);
    compSize   = LOAD_WORD(pSrc + 2);
  }
  if(PercentFinishedCallback) PercentFinishedCallback(100);

  TRACEEXIT();
  return outSize;
}