Enable EFIv1 compression in bmpbklk_utility.

This lets bmpbklk_utility generate BMPBLOCKs with EFIv1-compressed bitmaps.
It also adds the ability to display or unpack BMPBLOCK blobs.

The compression/decompression routines come from the tianocore EDK on
sourceforge and are written in C, so now there's a mix of C and C++, but it
works just fine.

BUG=chromium-os:11491
TEST=manual

cd src/platform/vboot_reference
make
make runbmptests

Review URL: http://codereview.chromium.org/6508006

Change-Id: Ie05e1a3fd42f4694447c8c440b2432af4ac0f601
diff --git a/utility/efidecompress.c b/utility/efidecompress.c
new file mode 100644
index 0000000..8ec4a08
--- /dev/null
+++ b/utility/efidecompress.c
@@ -0,0 +1,1008 @@
+/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+  Decompress.c
+
+Abstract:
+
+  Decompressor. Algorithm Ported from OPSD code (Decomp.asm)
+
+--*/
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "eficompress.h"
+
+
+//
+// Decompression algorithm begins here
+//
+#define BITBUFSIZ 32
+#define MAXMATCH  256
+#define THRESHOLD 3
+#define CODE_BIT  16
+#define BAD_TABLE - 1
+
+//
+// C: Char&Len Set; P: Position Set; T: exTra Set
+//
+#define NC      (0xff + MAXMATCH + 2 - THRESHOLD)
+#define CBIT    9
+#define MAXPBIT 5
+#define TBIT    5
+#define MAXNP   ((1U << MAXPBIT) - 1)
+#define NT      (CODE_BIT + 3)
+#if NT > MAXNP
+#define NPT NT
+#else
+#define NPT MAXNP
+#endif
+
+typedef struct {
+  UINT8   *mSrcBase;  // Starting address of compressed data
+  UINT8   *mDstBase;  // Starting address of decompressed data
+  UINT32  mOutBuf;
+  UINT32  mInBuf;
+
+  UINT16  mBitCount;
+  UINT32  mBitBuf;
+  UINT32  mSubBitBuf;
+  UINT16  mBlockSize;
+  UINT32  mCompSize;
+  UINT32  mOrigSize;
+
+  UINT16  mBadTableFlag;
+
+  UINT16  mLeft[2 * NC - 1];
+  UINT16  mRight[2 * NC - 1];
+  UINT8   mCLen[NC];
+  UINT8   mPTLen[NPT];
+  UINT16  mCTable[4096];
+  UINT16  mPTTable[256];
+
+  //
+  // The length of the field 'Position Set Code Length Array Size' in Block Header.
+  // For EFI 1.1 de/compression algorithm, mPBit = 4
+  // For Tiano de/compression algorithm, mPBit = 5
+  //
+  UINT8   mPBit;
+} SCRATCH_DATA;
+
+STATIC
+VOID
+FillBuf (
+  IN  SCRATCH_DATA  *Sd,
+  IN  UINT16        NumOfBits
+  )
+/*++
+
+Routine Description:
+
+  Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
+
+Arguments:
+
+  Sd        - The global scratch data
+  NumOfBits  - The number of bits to shift and read.
+
+Returns: (VOID)
+
+--*/
+{
+  Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);
+
+  while (NumOfBits > Sd->mBitCount) {
+
+    Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
+
+    if (Sd->mCompSize > 0) {
+      //
+      // Get 1 byte into SubBitBuf
+      //
+      Sd->mCompSize--;
+      Sd->mSubBitBuf  = 0;
+      Sd->mSubBitBuf  = Sd->mSrcBase[Sd->mInBuf++];
+      Sd->mBitCount   = 8;
+
+    } else {
+      //
+      // No more bits from the source, just pad zero bit.
+      //
+      Sd->mSubBitBuf  = 0;
+      Sd->mBitCount   = 8;
+
+    }
+  }
+
+  Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);
+  Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;
+}
+
+STATIC
+UINT32
+GetBits (
+  IN  SCRATCH_DATA  *Sd,
+  IN  UINT16        NumOfBits
+  )
+/*++
+
+Routine Description:
+
+  Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
+  NumOfBits of bits from source. Returns NumOfBits of bits that are
+  popped out.
+
+Arguments:
+
+  Sd            - The global scratch data.
+  NumOfBits     - The number of bits to pop and read.
+
+Returns:
+
+  The bits that are popped out.
+
+--*/
+{
+  UINT32  OutBits;
+
+  OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));
+
+  FillBuf (Sd, NumOfBits);
+
+  return OutBits;
+}
+
+STATIC
+UINT16
+MakeTable (
+  IN  SCRATCH_DATA  *Sd,
+  IN  UINT16        NumOfChar,
+  IN  UINT8         *BitLen,
+  IN  UINT16        TableBits,
+  OUT UINT16        *Table
+  )
+/*++
+
+Routine Description:
+
+  Creates Huffman Code mapping table according to code length array.
+
+Arguments:
+
+  Sd        - The global scratch data
+  NumOfChar - Number of symbols in the symbol set
+  BitLen    - Code length array
+  TableBits - The width of the mapping table
+  Table     - The table
+
+Returns:
+
+  0         - OK.
+  BAD_TABLE - The table is corrupted.
+
+--*/
+{
+  UINT16  Count[17];
+  UINT16  Weight[17];
+  UINT16  Start[18];
+  UINT16  *Pointer;
+  UINT16  Index3;
+  UINT16  Index;
+  UINT16  Len;
+  UINT16  Char;
+  UINT16  JuBits;
+  UINT16  Avail;
+  UINT16  NextCode;
+  UINT16  Mask;
+
+  for (Index = 1; Index <= 16; Index++) {
+    Count[Index] = 0;
+  }
+
+  for (Index = 0; Index < NumOfChar; Index++) {
+    Count[BitLen[Index]]++;
+  }
+
+  Start[1] = 0;
+
+  for (Index = 1; Index <= 16; Index++) {
+    Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index)));
+  }
+
+  if (Start[17] != 0) {
+    /*(1U << 16)*/
+    return (UINT16) BAD_TABLE;
+  }
+
+  JuBits = (UINT16) (16 - TableBits);
+
+  for (Index = 1; Index <= TableBits; Index++) {
+    Start[Index] >>= JuBits;
+    Weight[Index] = (UINT16) (1U << (TableBits - Index));
+  }
+
+  while (Index <= 16) {
+    Weight[Index] = (UINT16) (1U << (16 - Index));
+    Index++;
+  }
+
+  Index = (UINT16) (Start[TableBits + 1] >> JuBits);
+
+  if (Index != 0) {
+    Index3 = (UINT16) (1U << TableBits);
+    while (Index != Index3) {
+      Table[Index++] = 0;
+    }
+  }
+
+  Avail = NumOfChar;
+  Mask  = (UINT16) (1U << (15 - TableBits));
+
+  for (Char = 0; Char < NumOfChar; Char++) {
+
+    Len = BitLen[Char];
+    if (Len == 0) {
+      continue;
+    }
+
+    NextCode = (UINT16) (Start[Len] + Weight[Len]);
+
+    if (Len <= TableBits) {
+
+      for (Index = Start[Len]; Index < NextCode; Index++) {
+        Table[Index] = Char;
+      }
+
+    } else {
+
+      Index3  = Start[Len];
+      Pointer = &Table[Index3 >> JuBits];
+      Index   = (UINT16) (Len - TableBits);
+
+      while (Index != 0) {
+        if (*Pointer == 0) {
+          Sd->mRight[Avail]                     = Sd->mLeft[Avail] = 0;
+          *Pointer = Avail++;
+        }
+
+        if (Index3 & Mask) {
+          Pointer = &Sd->mRight[*Pointer];
+        } else {
+          Pointer = &Sd->mLeft[*Pointer];
+        }
+
+        Index3 <<= 1;
+        Index--;
+      }
+
+      *Pointer = Char;
+
+    }
+
+    Start[Len] = NextCode;
+  }
+  //
+  // Succeeds
+  //
+  return 0;
+}
+
+STATIC
+UINT32
+DecodeP (
+  IN  SCRATCH_DATA  *Sd
+  )
+/*++
+
+Routine Description:
+
+  Decodes a position value.
+
+Arguments:
+
+  Sd      - the global scratch data
+
+Returns:
+
+  The position value decoded.
+
+--*/
+{
+  UINT16  Val;
+  UINT32  Mask;
+  UINT32  Pos;
+
+  Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
+
+  if (Val >= MAXNP) {
+    Mask = 1U << (BITBUFSIZ - 1 - 8);
+
+    do {
+
+      if (Sd->mBitBuf & Mask) {
+        Val = Sd->mRight[Val];
+      } else {
+        Val = Sd->mLeft[Val];
+      }
+
+      Mask >>= 1;
+    } while (Val >= MAXNP);
+  }
+  //
+  // Advance what we have read
+  //
+  FillBuf (Sd, Sd->mPTLen[Val]);
+
+  Pos = Val;
+  if (Val > 1) {
+    Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));
+  }
+
+  return Pos;
+}
+
+STATIC
+UINT16
+ReadPTLen (
+  IN  SCRATCH_DATA  *Sd,
+  IN  UINT16        nn,
+  IN  UINT16        nbit,
+  IN  UINT16        Special
+  )
+/*++
+
+Routine Description:
+
+  Reads code lengths for the Extra Set or the Position Set
+
+Arguments:
+
+  Sd        - The global scratch data
+  nn        - Number of symbols
+  nbit      - Number of bits needed to represent nn
+  Special   - The special symbol that needs to be taken care of
+
+Returns:
+
+  0         - OK.
+  BAD_TABLE - Table is corrupted.
+
+--*/
+{
+  UINT16  Number;
+  UINT16  CharC;
+  UINT16  Index;
+  UINT32  Mask;
+
+  Number = (UINT16) GetBits (Sd, nbit);
+
+  if (Number == 0) {
+    CharC = (UINT16) GetBits (Sd, nbit);
+
+    for (Index = 0; Index < 256; Index++) {
+      Sd->mPTTable[Index] = CharC;
+    }
+
+    for (Index = 0; Index < nn; Index++) {
+      Sd->mPTLen[Index] = 0;
+    }
+
+    return 0;
+  }
+
+  Index = 0;
+
+  while (Index < Number) {
+
+    CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));
+
+    if (CharC == 7) {
+      Mask = 1U << (BITBUFSIZ - 1 - 3);
+      while (Mask & Sd->mBitBuf) {
+        Mask >>= 1;
+        CharC += 1;
+      }
+    }
+
+    FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));
+
+    Sd->mPTLen[Index++] = (UINT8) CharC;
+
+    if (Index == Special) {
+      CharC = (UINT16) GetBits (Sd, 2);
+      while ((INT16) (--CharC) >= 0) {
+        Sd->mPTLen[Index++] = 0;
+      }
+    }
+  }
+
+  while (Index < nn) {
+    Sd->mPTLen[Index++] = 0;
+  }
+
+  return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);
+}
+
+STATIC
+VOID
+ReadCLen (
+  SCRATCH_DATA  *Sd
+  )
+/*++
+
+Routine Description:
+
+  Reads code lengths for Char&Len Set.
+
+Arguments:
+
+  Sd    - the global scratch data
+
+Returns: (VOID)
+
+--*/
+{
+  UINT16  Number;
+  UINT16  CharC;
+  UINT16  Index;
+  UINT32  Mask;
+
+  Number = (UINT16) GetBits (Sd, CBIT);
+
+  if (Number == 0) {
+    CharC = (UINT16) GetBits (Sd, CBIT);
+
+    for (Index = 0; Index < NC; Index++) {
+      Sd->mCLen[Index] = 0;
+    }
+
+    for (Index = 0; Index < 4096; Index++) {
+      Sd->mCTable[Index] = CharC;
+    }
+
+    return ;
+  }
+
+  Index = 0;
+  while (Index < Number) {
+
+    CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
+    if (CharC >= NT) {
+      Mask = 1U << (BITBUFSIZ - 1 - 8);
+
+      do {
+
+        if (Mask & Sd->mBitBuf) {
+          CharC = Sd->mRight[CharC];
+        } else {
+          CharC = Sd->mLeft[CharC];
+        }
+
+        Mask >>= 1;
+
+      } while (CharC >= NT);
+    }
+    //
+    // Advance what we have read
+    //
+    FillBuf (Sd, Sd->mPTLen[CharC]);
+
+    if (CharC <= 2) {
+
+      if (CharC == 0) {
+        CharC = 1;
+      } else if (CharC == 1) {
+        CharC = (UINT16) (GetBits (Sd, 4) + 3);
+      } else if (CharC == 2) {
+        CharC = (UINT16) (GetBits (Sd, CBIT) + 20);
+      }
+
+      while ((INT16) (--CharC) >= 0) {
+        Sd->mCLen[Index++] = 0;
+      }
+
+    } else {
+
+      Sd->mCLen[Index++] = (UINT8) (CharC - 2);
+
+    }
+  }
+
+  while (Index < NC) {
+    Sd->mCLen[Index++] = 0;
+  }
+
+  MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);
+
+  return ;
+}
+
+STATIC
+UINT16
+DecodeC (
+  SCRATCH_DATA  *Sd
+  )
+/*++
+
+Routine Description:
+
+  Decode a character/length value.
+
+Arguments:
+
+  Sd    - The global scratch data.
+
+Returns:
+
+  The value decoded.
+
+--*/
+{
+  UINT16  Index2;
+  UINT32  Mask;
+
+  if (Sd->mBlockSize == 0) {
+    //
+    // Starting a new block
+    //
+    Sd->mBlockSize    = (UINT16) GetBits (Sd, 16);
+    Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);
+    if (Sd->mBadTableFlag != 0) {
+      return 0;
+    }
+
+    ReadCLen (Sd);
+
+    Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));
+    if (Sd->mBadTableFlag != 0) {
+      return 0;
+    }
+  }
+
+  Sd->mBlockSize--;
+  Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];
+
+  if (Index2 >= NC) {
+    Mask = 1U << (BITBUFSIZ - 1 - 12);
+
+    do {
+      if (Sd->mBitBuf & Mask) {
+        Index2 = Sd->mRight[Index2];
+      } else {
+        Index2 = Sd->mLeft[Index2];
+      }
+
+      Mask >>= 1;
+    } while (Index2 >= NC);
+  }
+  //
+  // Advance what we have read
+  //
+  FillBuf (Sd, Sd->mCLen[Index2]);
+
+  return Index2;
+}
+
+STATIC
+VOID
+Decode (
+  SCRATCH_DATA  *Sd
+  )
+/*++
+
+Routine Description:
+
+  Decode the source data and put the resulting data into the destination buffer.
+
+Arguments:
+
+  Sd            - The global scratch data
+
+Returns: (VOID)
+
+ --*/
+{
+  UINT16  BytesRemain;
+  UINT32  DataIdx;
+  UINT16  CharC;
+
+  BytesRemain = (UINT16) (-1);
+
+  DataIdx     = 0;
+
+  for (;;) {
+    CharC = DecodeC (Sd);
+    if (Sd->mBadTableFlag != 0) {
+      return ;
+    }
+
+    if (CharC < 256) {
+      //
+      // Process an Original character
+      //
+      if (Sd->mOutBuf >= Sd->mOrigSize) {
+        return ;
+      } else {
+        Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;
+      }
+
+    } else {
+      //
+      // Process a Pointer
+      //
+      CharC       = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));
+
+      BytesRemain = CharC;
+
+      DataIdx     = Sd->mOutBuf - DecodeP (Sd) - 1;
+
+      BytesRemain--;
+      while ((INT16) (BytesRemain) >= 0) {
+        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
+        if (Sd->mOutBuf >= Sd->mOrigSize) {
+          return ;
+        }
+
+        BytesRemain--;
+      }
+    }
+  }
+
+  return ;
+}
+
+EFI_STATUS
+GetInfo (
+  IN      VOID    *Source,
+  IN      UINT32  SrcSize,
+  OUT     UINT32  *DstSize,
+  OUT     UINT32  *ScratchSize
+  )
+/*++
+
+Routine Description:
+
+  The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
+
+Arguments:
+
+  Source      - The source buffer containing the compressed data.
+  SrcSize     - The size of source buffer
+  DstSize     - The size of destination buffer.
+  ScratchSize - The size of scratch buffer.
+
+Returns:
+
+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.
+  EFI_INVALID_PARAMETER - The source data is corrupted
+
+--*/
+{
+  UINT8 *Src;
+
+  *ScratchSize  = sizeof (SCRATCH_DATA);
+
+  Src           = Source;
+  if (SrcSize < 8) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+Decompress (
+  IN      VOID    *Source,
+  IN      UINT32  SrcSize,
+  IN OUT  VOID    *Destination,
+  IN      UINT32  DstSize,
+  IN OUT  VOID    *Scratch,
+  IN      UINT32  ScratchSize,
+  IN      UINT8   Version
+  )
+/*++
+
+Routine Description:
+
+  The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
+
+Arguments:
+
+  Source      - The source buffer containing the compressed data.
+  SrcSize     - The size of source buffer
+  Destination - The destination buffer to store the decompressed data
+  DstSize     - The size of destination buffer.
+  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.
+  ScratchSize - The size of scratch buffer.
+  Version     - The version of de/compression algorithm.
+                Version 1 for EFI 1.1 de/compression algorithm.
+                Version 2 for Tiano de/compression algorithm.
+
+Returns:
+
+  EFI_SUCCESS           - Decompression is successfull
+  EFI_INVALID_PARAMETER - The source data is corrupted
+
+--*/
+{
+  UINT32        Index;
+  UINT32        CompSize;
+  UINT32        OrigSize;
+  EFI_STATUS    Status;
+  SCRATCH_DATA  *Sd;
+  UINT8         *Src;
+  UINT8         *Dst;
+
+  Status  = EFI_SUCCESS;
+  Src     = Source;
+  Dst     = Destination;
+
+  if (ScratchSize < sizeof (SCRATCH_DATA)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Sd = (SCRATCH_DATA *) Scratch;
+
+  if (SrcSize < 8) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  CompSize  = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
+  OrigSize  = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
+
+  //
+  // If compressed file size is 0, return
+  //
+  if (OrigSize == 0) {
+    return Status;
+  }
+
+  if (SrcSize < CompSize + 8) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (DstSize != OrigSize) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Src = Src + 8;
+
+  for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {
+    ((UINT8 *) Sd)[Index] = 0;
+  }
+  //
+  // The length of the field 'Position Set Code Length Array Size' in Block Header.
+  // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4
+  // For Tiano de/compression algorithm(Version 2), mPBit = 5
+  //
+  switch (Version) {
+  case 1:
+    Sd->mPBit = 4;
+    break;
+
+  case 2:
+    Sd->mPBit = 5;
+    break;
+
+  default:
+    //
+    // Currently, only have 2 versions
+    //
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Sd->mSrcBase  = Src;
+  Sd->mDstBase  = Dst;
+  Sd->mCompSize = CompSize;
+  Sd->mOrigSize = OrigSize;
+
+  //
+  // Fill the first BITBUFSIZ bits
+  //
+  FillBuf (Sd, BITBUFSIZ);
+
+  //
+  // Decompress it
+  //
+  Decode (Sd);
+
+  if (Sd->mBadTableFlag != 0) {
+    //
+    // Something wrong with the source
+    //
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+EfiGetInfo (
+  IN      VOID                    *Source,
+  IN      UINT32                  SrcSize,
+  OUT     UINT32                  *DstSize,
+  OUT     UINT32                  *ScratchSize
+  )
+/*++
+
+Routine Description:
+
+  The implementation is same as that  of EFI_DECOMPRESS_PROTOCOL.GetInfo().
+
+Arguments:
+
+  This        - The protocol instance pointer
+  Source      - The source buffer containing the compressed data.
+  SrcSize     - The size of source buffer
+  DstSize     - The size of destination buffer.
+  ScratchSize - The size of scratch buffer.
+
+Returns:
+
+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.
+  EFI_INVALID_PARAMETER - The source data is corrupted
+
+--*/
+{
+  return GetInfo (
+          Source,
+          SrcSize,
+          DstSize,
+          ScratchSize
+          );
+}
+
+EFI_STATUS
+EFIAPI
+EfiDecompress (
+  IN      VOID                    *Source,
+  IN      UINT32                  SrcSize,
+  IN OUT  VOID                    *Destination,
+  IN      UINT32                  DstSize,
+  IN OUT  VOID                    *Scratch,
+  IN      UINT32                  ScratchSize
+  )
+/*++
+
+Routine Description:
+
+  The implementation is same as that of EFI_DECOMPRESS_PROTOCOL.Decompress().
+
+Arguments:
+
+  This        - The protocol instance pointer
+  Source      - The source buffer containing the compressed data.
+  SrcSize     - The size of source buffer
+  Destination - The destination buffer to store the decompressed data
+  DstSize     - The size of destination buffer.
+  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.
+  ScratchSize - The size of scratch buffer.
+
+Returns:
+
+  EFI_SUCCESS           - Decompression is successfull
+  EFI_INVALID_PARAMETER - The source data is corrupted
+
+--*/
+{
+  //
+  // For EFI 1.1 de/compression algorithm, the version is 1.
+  //
+  return Decompress (
+          Source,
+          SrcSize,
+          Destination,
+          DstSize,
+          Scratch,
+          ScratchSize,
+          1
+          );
+}
+
+EFI_STATUS
+EFIAPI
+TianoGetInfo (
+  IN      VOID                          *Source,
+  IN      UINT32                        SrcSize,
+  OUT     UINT32                        *DstSize,
+  OUT     UINT32                        *ScratchSize
+  )
+/*++
+
+Routine Description:
+
+  The implementation is same as that of EFI_TIANO_DECOMPRESS_PROTOCOL.GetInfo().
+
+Arguments:
+
+  This        - The protocol instance pointer
+  Source      - The source buffer containing the compressed data.
+  SrcSize     - The size of source buffer
+  DstSize     - The size of destination buffer.
+  ScratchSize - The size of scratch buffer.
+
+Returns:
+
+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.
+  EFI_INVALID_PARAMETER - The source data is corrupted
+
+--*/
+{
+  return GetInfo (
+          Source,
+          SrcSize,
+          DstSize,
+          ScratchSize
+          );
+}
+
+EFI_STATUS
+EFIAPI
+TianoDecompress (
+  IN      VOID                          *Source,
+  IN      UINT32                        SrcSize,
+  IN OUT  VOID                          *Destination,
+  IN      UINT32                        DstSize,
+  IN OUT  VOID                          *Scratch,
+  IN      UINT32                        ScratchSize
+  )
+/*++
+
+Routine Description:
+
+  The implementation is same as that  of EFI_TIANO_DECOMPRESS_PROTOCOL.Decompress().
+
+Arguments:
+
+  This        - The protocol instance pointer
+  Source      - The source buffer containing the compressed data.
+  SrcSize     - The size of source buffer
+  Destination - The destination buffer to store the decompressed data
+  DstSize     - The size of destination buffer.
+  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.
+  ScratchSize - The size of scratch buffer.
+
+Returns:
+
+  EFI_SUCCESS           - Decompression is successfull
+  EFI_INVALID_PARAMETER - The source data is corrupted
+
+--*/
+{
+  //
+  // For Tiano de/compression algorithm, the version is 2.
+  //
+  return Decompress (
+          Source,
+          SrcSize,
+          Destination,
+          DstSize,
+          Scratch,
+          ScratchSize,
+          2
+          );
+}