TianoDecompress.h revision 8c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805
18c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu/** @file
28c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Internal include file for Base UEFI Decompress Libary.
38c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
48c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Copyright (c) 2006, Intel Corporation
58c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  All rights reserved. This program and the accompanying materials
68c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  are licensed and made available under the terms and conditions of the BSD License
78c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  which accompanies this distribution.  The full text of the license may be found at
88c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  http://opensource.org/licenses/bsd-license.php
98c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
108c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
118c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
128c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
138c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Module Name:  BaseUefiCustomDecompressLibInternals.h
148c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
158c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu**/
168c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
178c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#ifndef __BASE_UEFI_TIANO_CUSTOM_DECOMPRESS_LIB_INTERNALS_H__
188c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#define __BASE_UEFI_TIANO_CUSTOM_DECOMPRESS_LIB_INTERNALS_H__
198c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
208c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#include <PiPei.h>
218c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
228c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#include <Library/UefiDecompressLib.h>
238c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#include <Library/DebugLib.h>
248c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#include <Library/BaseMemoryLib.h>
258c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
268c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu//
278c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu// Decompression algorithm begins here
288c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu//
298c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#define BITBUFSIZ 32
308c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#define MAXMATCH  256
318c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#define THRESHOLD 3
328c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#define CODE_BIT  16
338c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#define BAD_TABLE - 1
348c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
358c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu//
368c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu// C: Char&Len Set; P: Position Set; T: exTra Set
378c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu//
388c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#define NC      (0xff + MAXMATCH + 2 - THRESHOLD)
398c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#define CBIT    9
408c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#define MAXPBIT 5
418c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#define TBIT    5
428c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#define MAXNP   ((1U << MAXPBIT) - 1)
438c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#define NT      (CODE_BIT + 3)
448c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#if NT > MAXNP
458c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#define NPT NT
468c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#else
478c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#define NPT MAXNP
488c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#endif
498c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
508c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klutypedef struct {
518c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT8   *mSrcBase;  // Starting address of compressed data
528c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT8   *mDstBase;  // Starting address of decompressed data
538c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT32  mOutBuf;
548c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT32  mInBuf;
558c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
568c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT16  mBitCount;
578c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT32  mBitBuf;
588c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT32  mSubBitBuf;
598c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT16  mBlockSize;
608c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT32  mCompSize;
618c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT32  mOrigSize;
628c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
638c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT16  mBadTableFlag;
648c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
658c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT16  mLeft[2 * NC - 1];
668c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT16  mRight[2 * NC - 1];
678c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT8   mCLen[NC];
688c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT8   mPTLen[NPT];
698c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT16  mCTable[4096];
708c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT16  mPTTable[256];
718c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
728c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  //
738c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  // The length of the field 'Position Set Code Length Array Size' in Block Header.
748c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  // For UEFI 2.0 de/compression algorithm, mPBit = 4
758c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  // For Tiano de/compression algorithm, mPBit = 5
768c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  //
778c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  UINT8   mPBit;
788c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu} SCRATCH_DATA;
798c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
808c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu/**
818c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Read NumOfBit of bits from source into mBitBuf
828c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
838c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
848c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
858c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @param  Sd        The global scratch data
868c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @param  NumOfBits The number of bits to shift and read.
878c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
888c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu**/
898c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluVOID
908c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluFillBuf (
918c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  IN  SCRATCH_DATA  *Sd,
928c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  IN  UINT16        NumOfBits
938c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  );
948c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
958c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu/**
968c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Get NumOfBits of bits out from mBitBuf
978c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
988c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
998c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  NumOfBits of bits from source. Returns NumOfBits of bits that are
1008c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  popped out.
1018c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1028c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @param  Sd        The global scratch data.
1038c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @param  NumOfBits The number of bits to pop and read.
1048c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1058c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @return The bits that are popped out.
1068c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1078c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu**/
1088c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluUINT32
1098c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluGetBits (
1108c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  IN  SCRATCH_DATA  *Sd,
1118c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  IN  UINT16        NumOfBits
1128c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  );
1138c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1148c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu/**
1158c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Creates Huffman Code mapping table according to code length array.
1168c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1178c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Creates Huffman Code mapping table for Extra Set, Char&Len Set
1188c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  and Position Set according to code length array.
1198c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1208c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @param  Sd        The global scratch data
1218c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @param  NumOfChar Number of symbols in the symbol set
1228c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @param  BitLen    Code length array
1238c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @param  TableBits The width of the mapping table
1248c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @param  Table     The table
1258c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1268c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @retval  0 OK.
1278c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @retval  BAD_TABLE The table is corrupted.
1288c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1298c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu**/
1308c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluUINT16
1318c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluMakeTable (
1328c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  IN  SCRATCH_DATA  *Sd,
1338c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  IN  UINT16        NumOfChar,
1348c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  IN  UINT8         *BitLen,
1358c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  IN  UINT16        TableBits,
1368c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  OUT UINT16        *Table
1378c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  );
1388c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1398c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu/**
1408c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Decodes a position value.
1418c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1428c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Get a position value according to Position Huffman Table.
1438c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1448c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @param  Sd the global scratch data
1458c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1468c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @return The position value decoded.
1478c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1488c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu**/
1498c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluUINT32
1508c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluDecodeP (
1518c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  IN  SCRATCH_DATA  *Sd
1528c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  );
1538c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1548c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu/**
1558c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Reads code lengths for the Extra Set or the Position Set.
1568c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1578c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Read in the Extra Set or Pointion Set Length Arrary, then
1588c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  generate the Huffman code mapping for them.
1598c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1608c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @param  Sd      The global scratch data.
1618c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @param  nn      Number of symbols.
1628c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @param  nbit    Number of bits needed to represent nn.
1638c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @param  Special The special symbol that needs to be taken care of.
1648c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1658c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @retval  0 OK.
1668c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @retval  BAD_TABLE Table is corrupted.
1678c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1688c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu**/
1698c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluUINT16
1708c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluReadPTLen (
1718c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  IN  SCRATCH_DATA  *Sd,
1728c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  IN  UINT16        nn,
1738c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  IN  UINT16        nbit,
1748c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  IN  UINT16        Special
1758c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  );
1768c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1778c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu/**
1788c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Reads code lengths for Char&Len Set.
1798c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1808c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Read in and decode the Char&Len Set Code Length Array, then
1818c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  generate the Huffman Code mapping table for the Char&Len Set.
1828c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1838c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @param  Sd the global scratch data
1848c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1858c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu**/
1868c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluVOID
1878c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluReadCLen (
1888c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  SCRATCH_DATA  *Sd
1898c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  );
1908c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1918c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu/**
1928c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Decode a character/length value.
1938c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1948c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Read one value from mBitBuf, Get one code from mBitBuf. If it is at block boundary, generates
1958c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Huffman code mapping table for Extra Set, Code&Len Set and
1968c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Position Set.
1978c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
1988c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @param  Sd The global scratch data.
1998c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
2008c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @return The value decoded.
2018c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
2028c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu**/
2038c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluUINT16
2048c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluDecodeC (
2058c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  SCRATCH_DATA  *Sd
2068c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  );
2078c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
2088c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu/**
2098c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Decode the source data and put the resulting data into the destination buffer.
2108c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
2118c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  Decode the source data and put the resulting data into the destination buffer.
2128c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
2138c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  @param  Sd The global scratch data
2148c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
2158c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu**/
2168c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluVOID
2178c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluDecode (
2188c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  SCRATCH_DATA  *Sd
2198c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  );
2208c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
2218c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluRETURN_STATUS
2228c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluEFIAPI
2238c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805kluUefiTianoDecompress (
2248c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  IN CONST VOID  *Source,
2258c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  IN OUT VOID    *Destination,
2268c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  IN OUT VOID    *Scratch,
2278c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  IN UINT32      Version
2288c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu  );
2298c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu
2308c1ba7f5e5aef9ff8f4627e8af52932fb4f7b805klu#endif
231