1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800 |
- /** @file
- Compression routine. The compression algorithm is a mixture of LZ77 and Huffman
- coding. LZ77 transforms the source data into a sequence of Original Characters
- and Pointers to repeated strings.
- This sequence is further divided into Blocks and Huffman codings are applied to
- each Block.
- Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
- 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.
- **/
- #include "Compress.h"
- #include "Decompress.h"
- #include "TianoCompress.h"
- #include "EfiUtilityMsgs.h"
- #include "ParseInf.h"
- #include <stdio.h>
- #include "assert.h"
- //
- // Macro Definitions
- //
- static BOOLEAN VerboseMode = FALSE;
- static BOOLEAN QuietMode = FALSE;
- #undef UINT8_MAX
- #define UINT8_MAX 0xff
- #define UINT8_BIT 8
- #define THRESHOLD 3
- #define INIT_CRC 0
- #define WNDBIT 19
- #define WNDSIZ (1U << WNDBIT)
- #define MAXMATCH 256
- #define BLKSIZ (1U << 14) // 16 * 1024U
- #define PERC_FLAG 0x80000000U
- #define CODE_BIT 16
- #define NIL 0
- #define MAX_HASH_VAL (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX)
- #define HASH(p, c) ((p) + ((c) << (WNDBIT - 9)) + WNDSIZ * 2)
- #define CRCPOLY 0xA001
- #define UPDATE_CRC(c) mCrc = mCrcTable[(mCrc ^ (c)) & 0xFF] ^ (mCrc >> UINT8_BIT)
- //
- // C: the Char&Len Set; P: the Position Set; T: the exTra Set
- //
- //#define NC (UINT8_MAX + MAXMATCH + 2 - THRESHOLD)
- #define CBIT 9
- #define NP (WNDBIT + 1)
- #define PBIT 5
- //#define NT (CODE_BIT + 3)
- //#define TBIT 5
- //#if NT > NP
- //#define NPT NT
- //#else
- //#define NPT NP
- //#endif
- //
- // Global Variables
- //
- STATIC BOOLEAN ENCODE = FALSE;
- STATIC BOOLEAN DECODE = FALSE;
- STATIC BOOLEAN UEFIMODE = FALSE;
- STATIC UINT8 *mSrc, *mDst, *mSrcUpperLimit, *mDstUpperLimit;
- STATIC UINT8 *mLevel, *mText, *mChildCount, *mBuf, mCLen[NC], mPTLen[NPT], *mLen;
- STATIC INT16 mHeap[NC + 1];
- STATIC INT32 mRemainder, mMatchLen, mBitCount, mHeapSize, mN;
- STATIC UINT32 mBufSiz = 0, mOutputPos, mOutputMask, mSubBitBuf, mCrc;
- STATIC UINT32 mCompSize, mOrigSize;
- STATIC UINT16 *mFreq, *mSortPtr, mLenCnt[17], mLeft[2 * NC - 1], mRight[2 * NC - 1], mCrcTable[UINT8_MAX + 1],
- mCFreq[2 * NC - 1], mCCode[NC], mPFreq[2 * NP - 1], mPTCode[NPT], mTFreq[2 * NT - 1];
- STATIC NODE mPos, mMatchPos, mAvail, *mPosition, *mParent, *mPrev, *mNext = NULL;
- static UINT64 DebugLevel;
- static BOOLEAN DebugMode;
- //
- // functions
- //
- EFI_STATUS
- TianoCompress (
- IN UINT8 *SrcBuffer,
- IN UINT32 SrcSize,
- IN UINT8 *DstBuffer,
- IN OUT UINT32 *DstSize
- )
- /*++
- Routine Description:
- The internal implementation of [Efi/Tiano]Compress().
- Arguments:
- SrcBuffer - The buffer storing the source data
- SrcSize - The size of source data
- DstBuffer - The buffer to store the compressed data
- 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_BUFFER_TOO_SMALL - The DstBuffer is too small. In this case,
- DstSize contains the size needed.
- EFI_SUCCESS - Compression is successful.
- EFI_OUT_OF_RESOURCES - No resource to complete function.
- EFI_INVALID_PARAMETER - Parameter supplied is wrong.
- --*/
- {
- EFI_STATUS Status;
- //
- // Initializations
- //
- mBufSiz = 0;
- mBuf = NULL;
- mText = NULL;
- mLevel = NULL;
- mChildCount = NULL;
- mPosition = NULL;
- mParent = NULL;
- mPrev = NULL;
- mNext = NULL;
- mSrc = SrcBuffer;
- mSrcUpperLimit = mSrc + SrcSize;
- mDst = DstBuffer;
- mDstUpperLimit = mDst +*DstSize;
- PutDword (0L);
- PutDword (0L);
- MakeCrcTable ();
- mOrigSize = mCompSize = 0;
- mCrc = INIT_CRC;
- //
- // Compress it
- //
- Status = Encode ();
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Null terminate the compressed data
- //
- if (mDst < mDstUpperLimit) {
- *mDst++ = 0;
- }
- //
- // Fill in compressed size and original size
- //
- mDst = DstBuffer;
- PutDword (mCompSize + 1);
- PutDword (mOrigSize);
- //
- // Return
- //
- if (mCompSize + 1 + 8 > *DstSize) {
- *DstSize = mCompSize + 1 + 8;
- return EFI_BUFFER_TOO_SMALL;
- } else {
- *DstSize = mCompSize + 1 + 8;
- return EFI_SUCCESS;
- }
- }
- STATIC
- VOID
- PutDword (
- IN UINT32 Data
- )
- /*++
- Routine Description:
- Put a dword to output stream
- Arguments:
- Data - the dword to put
- Returns: (VOID)
- --*/
- {
- if (mDst < mDstUpperLimit) {
- *mDst++ = (UINT8) (((UINT8) (Data)) & 0xff);
- }
- if (mDst < mDstUpperLimit) {
- *mDst++ = (UINT8) (((UINT8) (Data >> 0x08)) & 0xff);
- }
- if (mDst < mDstUpperLimit) {
- *mDst++ = (UINT8) (((UINT8) (Data >> 0x10)) & 0xff);
- }
- if (mDst < mDstUpperLimit) {
- *mDst++ = (UINT8) (((UINT8) (Data >> 0x18)) & 0xff);
- }
- }
- STATIC
- EFI_STATUS
- AllocateMemory (
- VOID
- )
- /*++
- Routine Description:
- Allocate memory spaces for data structures used in compression process
- Arguments:
- VOID
- Returns:
- EFI_SUCCESS - Memory is allocated successfully
- EFI_OUT_OF_RESOURCES - Allocation fails
- --*/
- {
- UINT32 Index;
- mText = malloc (WNDSIZ * 2 + MAXMATCH);
- if (mText == NULL) {
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- return EFI_OUT_OF_RESOURCES;
- }
- for (Index = 0; Index < WNDSIZ * 2 + MAXMATCH; Index++) {
- mText[Index] = 0;
- }
- mLevel = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mLevel));
- mChildCount = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mChildCount));
- mPosition = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mPosition));
- mParent = malloc (WNDSIZ * 2 * sizeof (*mParent));
- mPrev = malloc (WNDSIZ * 2 * sizeof (*mPrev));
- mNext = malloc ((MAX_HASH_VAL + 1) * sizeof (*mNext));
- if (mLevel == NULL || mChildCount == NULL || mPosition == NULL ||
- mParent == NULL || mPrev == NULL || mNext == NULL) {
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- return EFI_OUT_OF_RESOURCES;
- }
- mBufSiz = BLKSIZ;
- mBuf = malloc (mBufSiz);
- while (mBuf == NULL) {
- mBufSiz = (mBufSiz / 10U) * 9U;
- if (mBufSiz < 4 * 1024U) {
- return EFI_OUT_OF_RESOURCES;
- }
- mBuf = malloc (mBufSiz);
- }
- mBuf[0] = 0;
- return EFI_SUCCESS;
- }
- VOID
- FreeMemory (
- VOID
- )
- /*++
- Routine Description:
- Called when compression is completed to free memory previously allocated.
- Arguments: (VOID)
- Returns: (VOID)
- --*/
- {
- if (mText != NULL) {
- free (mText);
- }
- if (mLevel != NULL) {
- free (mLevel);
- }
- if (mChildCount != NULL) {
- free (mChildCount);
- }
- if (mPosition != NULL) {
- free (mPosition);
- }
- if (mParent != NULL) {
- free (mParent);
- }
- if (mPrev != NULL) {
- free (mPrev);
- }
- if (mNext != NULL) {
- free (mNext);
- }
- if (mBuf != NULL) {
- free (mBuf);
- }
- return ;
- }
- STATIC
- VOID
- InitSlide (
- VOID
- )
- /*++
- Routine Description:
- Initialize String Info Log data structures
- Arguments: (VOID)
- Returns: (VOID)
- --*/
- {
- NODE Index;
- for (Index = WNDSIZ; Index <= WNDSIZ + UINT8_MAX; Index++) {
- mLevel[Index] = 1;
- mPosition[Index] = NIL; // sentinel
- }
- for (Index = WNDSIZ; Index < WNDSIZ * 2; Index++) {
- mParent[Index] = NIL;
- }
- mAvail = 1;
- for (Index = 1; Index < WNDSIZ - 1; Index++) {
- mNext[Index] = (NODE) (Index + 1);
- }
- mNext[WNDSIZ - 1] = NIL;
- for (Index = WNDSIZ * 2; Index <= MAX_HASH_VAL; Index++) {
- mNext[Index] = NIL;
- }
- }
- STATIC
- NODE
- Child (
- IN NODE NodeQ,
- IN UINT8 CharC
- )
- /*++
- Routine Description:
- Find child node given the parent node and the edge character
- Arguments:
- NodeQ - the parent node
- CharC - the edge character
- Returns:
- The child node (NIL if not found)
- --*/
- {
- NODE NodeR;
- NodeR = mNext[HASH (NodeQ, CharC)];
- //
- // sentinel
- //
- mParent[NIL] = NodeQ;
- while (mParent[NodeR] != NodeQ) {
- NodeR = mNext[NodeR];
- }
- return NodeR;
- }
- STATIC
- VOID
- MakeChild (
- IN NODE Parent,
- IN UINT8 CharC,
- IN NODE Child
- )
- /*++
- Routine Description:
- Create a new child for a given parent node.
- Arguments:
- Parent - the parent node
- CharC - the edge character
- Child - the child node
- Returns: (VOID)
- --*/
- {
- NODE Node1;
- NODE Node2;
- Node1 = (NODE) HASH (Parent, CharC);
- Node2 = mNext[Node1];
- mNext[Node1] = Child;
- mNext[Child] = Node2;
- mPrev[Node2] = Child;
- mPrev[Child] = Node1;
- mParent[Child] = Parent;
- mChildCount[Parent]++;
- }
- STATIC
- VOID
- Split (
- NODE Old
- )
- /*++
- Routine Description:
- Split a node.
- Arguments:
- Old - the node to split
- Returns: (VOID)
- --*/
- {
- NODE New;
- NODE TempNode;
- New = mAvail;
- mAvail = mNext[New];
- mChildCount[New] = 0;
- TempNode = mPrev[Old];
- mPrev[New] = TempNode;
- mNext[TempNode] = New;
- TempNode = mNext[Old];
- mNext[New] = TempNode;
- mPrev[TempNode] = New;
- mParent[New] = mParent[Old];
- mLevel[New] = (UINT8) mMatchLen;
- mPosition[New] = mPos;
- MakeChild (New, mText[mMatchPos + mMatchLen], Old);
- MakeChild (New, mText[mPos + mMatchLen], mPos);
- }
- STATIC
- VOID
- InsertNode (
- VOID
- )
- /*++
- Routine Description:
- Insert string info for current position into the String Info Log
- Arguments: (VOID)
- Returns: (VOID)
- --*/
- {
- NODE NodeQ;
- NODE NodeR;
- NODE Index2;
- NODE NodeT;
- UINT8 CharC;
- UINT8 *t1;
- UINT8 *t2;
- if (mMatchLen >= 4) {
- //
- // We have just got a long match, the target tree
- // can be located by MatchPos + 1. Traverse the tree
- // from bottom up to get to a proper starting point.
- // The usage of PERC_FLAG ensures proper node deletion
- // in DeleteNode() later.
- //
- mMatchLen--;
- NodeR = (NODE) ((mMatchPos + 1) | WNDSIZ);
- NodeQ = mParent[NodeR];
- while (NodeQ == NIL) {
- NodeR = mNext[NodeR];
- NodeQ = mParent[NodeR];
- }
- while (mLevel[NodeQ] >= mMatchLen) {
- NodeR = NodeQ;
- NodeQ = mParent[NodeQ];
- }
- NodeT = NodeQ;
- while (mPosition[NodeT] < 0) {
- mPosition[NodeT] = mPos;
- NodeT = mParent[NodeT];
- }
- if (NodeT < WNDSIZ) {
- mPosition[NodeT] = (NODE) (mPos | (UINT32) PERC_FLAG);
- }
- } else {
- //
- // Locate the target tree
- //
- NodeQ = (NODE) (mText[mPos] + WNDSIZ);
- CharC = mText[mPos + 1];
- NodeR = Child (NodeQ, CharC);
- if (NodeR == NIL) {
- MakeChild (NodeQ, CharC, mPos);
- mMatchLen = 1;
- return ;
- }
- mMatchLen = 2;
- }
- //
- // Traverse down the tree to find a match.
- // Update Position value along the route.
- // Node split or creation is involved.
- //
- for (;;) {
- if (NodeR >= WNDSIZ) {
- Index2 = MAXMATCH;
- mMatchPos = NodeR;
- } else {
- Index2 = mLevel[NodeR];
- mMatchPos = (NODE) (mPosition[NodeR] & (UINT32)~PERC_FLAG);
- }
- if (mMatchPos >= mPos) {
- mMatchPos -= WNDSIZ;
- }
- t1 = &mText[mPos + mMatchLen];
- t2 = &mText[mMatchPos + mMatchLen];
- while (mMatchLen < Index2) {
- if (*t1 != *t2) {
- Split (NodeR);
- return ;
- }
- mMatchLen++;
- t1++;
- t2++;
- }
- if (mMatchLen >= MAXMATCH) {
- break;
- }
- mPosition[NodeR] = mPos;
- NodeQ = NodeR;
- NodeR = Child (NodeQ, *t1);
- if (NodeR == NIL) {
- MakeChild (NodeQ, *t1, mPos);
- return ;
- }
- mMatchLen++;
- }
- NodeT = mPrev[NodeR];
- mPrev[mPos] = NodeT;
- mNext[NodeT] = mPos;
- NodeT = mNext[NodeR];
- mNext[mPos] = NodeT;
- mPrev[NodeT] = mPos;
- mParent[mPos] = NodeQ;
- mParent[NodeR] = NIL;
- //
- // Special usage of 'next'
- //
- mNext[NodeR] = mPos;
- }
- STATIC
- VOID
- DeleteNode (
- VOID
- )
- /*++
- Routine Description:
- Delete outdated string info. (The Usage of PERC_FLAG
- ensures a clean deletion)
- Arguments: (VOID)
- Returns: (VOID)
- --*/
- {
- NODE NodeQ;
- NODE NodeR;
- NODE NodeS;
- NODE NodeT;
- NODE NodeU;
- if (mParent[mPos] == NIL) {
- return ;
- }
- NodeR = mPrev[mPos];
- NodeS = mNext[mPos];
- mNext[NodeR] = NodeS;
- mPrev[NodeS] = NodeR;
- NodeR = mParent[mPos];
- mParent[mPos] = NIL;
- if (NodeR >= WNDSIZ) {
- return ;
- }
- mChildCount[NodeR]--;
- if (mChildCount[NodeR] > 1) {
- return ;
- }
- NodeT = (NODE) (mPosition[NodeR] & (UINT32)~PERC_FLAG);
- if (NodeT >= mPos) {
- NodeT -= WNDSIZ;
- }
- NodeS = NodeT;
- NodeQ = mParent[NodeR];
- NodeU = mPosition[NodeQ];
- while (NodeU & (UINT32) PERC_FLAG) {
- NodeU &= (UINT32)~PERC_FLAG;
- if (NodeU >= mPos) {
- NodeU -= WNDSIZ;
- }
- if (NodeU > NodeS) {
- NodeS = NodeU;
- }
- mPosition[NodeQ] = (NODE) (NodeS | WNDSIZ);
- NodeQ = mParent[NodeQ];
- NodeU = mPosition[NodeQ];
- }
- if (NodeQ < WNDSIZ) {
- if (NodeU >= mPos) {
- NodeU -= WNDSIZ;
- }
- if (NodeU > NodeS) {
- NodeS = NodeU;
- }
- mPosition[NodeQ] = (NODE) (NodeS | WNDSIZ | (UINT32) PERC_FLAG);
- }
- NodeS = Child (NodeR, mText[NodeT + mLevel[NodeR]]);
- NodeT = mPrev[NodeS];
- NodeU = mNext[NodeS];
- mNext[NodeT] = NodeU;
- mPrev[NodeU] = NodeT;
- NodeT = mPrev[NodeR];
- mNext[NodeT] = NodeS;
- mPrev[NodeS] = NodeT;
- NodeT = mNext[NodeR];
- mPrev[NodeT] = NodeS;
- mNext[NodeS] = NodeT;
- mParent[NodeS] = mParent[NodeR];
- mParent[NodeR] = NIL;
- mNext[NodeR] = mAvail;
- mAvail = NodeR;
- }
- STATIC
- VOID
- GetNextMatch (
- VOID
- )
- /*++
- Routine Description:
- Advance the current position (read in new data if needed).
- Delete outdated string info. Find a match string for current position.
- Arguments: (VOID)
- Returns: (VOID)
- --*/
- {
- INT32 Number;
- mRemainder--;
- mPos++;
- if (mPos == WNDSIZ * 2) {
- memmove (&mText[0], &mText[WNDSIZ], WNDSIZ + MAXMATCH);
- Number = FreadCrc (&mText[WNDSIZ + MAXMATCH], WNDSIZ);
- mRemainder += Number;
- mPos = WNDSIZ;
- }
- DeleteNode ();
- InsertNode ();
- }
- STATIC
- EFI_STATUS
- Encode (
- VOID
- )
- /*++
- Routine Description:
- The main controlling routine for compression process.
- Arguments: (VOID)
- Returns:
- EFI_SUCCESS - The compression is successful
- EFI_OUT_0F_RESOURCES - Not enough memory for compression process
- --*/
- {
- EFI_STATUS Status;
- INT32 LastMatchLen;
- NODE LastMatchPos;
- Status = AllocateMemory ();
- if (EFI_ERROR (Status)) {
- FreeMemory ();
- return Status;
- }
- InitSlide ();
- HufEncodeStart ();
- mRemainder = FreadCrc (&mText[WNDSIZ], WNDSIZ + MAXMATCH);
- mMatchLen = 0;
- mPos = WNDSIZ;
- InsertNode ();
- if (mMatchLen > mRemainder) {
- mMatchLen = mRemainder;
- }
- while (mRemainder > 0) {
- LastMatchLen = mMatchLen;
- LastMatchPos = mMatchPos;
- GetNextMatch ();
- if (mMatchLen > mRemainder) {
- mMatchLen = mRemainder;
- }
- if (mMatchLen > LastMatchLen || LastMatchLen < THRESHOLD) {
- //
- // Not enough benefits are gained by outputting a pointer,
- // so just output the original character
- //
- Output (mText[mPos - 1], 0);
- } else {
- if (LastMatchLen == THRESHOLD) {
- if (((mPos - LastMatchPos - 2) & (WNDSIZ - 1)) > (1U << 11)) {
- Output (mText[mPos - 1], 0);
- continue;
- }
- }
- //
- // Outputting a pointer is beneficial enough, do it.
- //
- Output (
- LastMatchLen + (UINT8_MAX + 1 - THRESHOLD),
- (mPos - LastMatchPos - 2) & (WNDSIZ - 1)
- );
- LastMatchLen--;
- while (LastMatchLen > 0) {
- GetNextMatch ();
- LastMatchLen--;
- }
- if (mMatchLen > mRemainder) {
- mMatchLen = mRemainder;
- }
- }
- }
- HufEncodeEnd ();
- FreeMemory ();
- return EFI_SUCCESS;
- }
- STATIC
- VOID
- CountTFreq (
- VOID
- )
- /*++
- Routine Description:
- Count the frequencies for the Extra Set
- Arguments: (VOID)
- Returns: (VOID)
- --*/
- {
- INT32 Index;
- INT32 Index3;
- INT32 Number;
- INT32 Count;
- for (Index = 0; Index < NT; Index++) {
- mTFreq[Index] = 0;
- }
- Number = NC;
- while (Number > 0 && mCLen[Number - 1] == 0) {
- Number--;
- }
- Index = 0;
- while (Index < Number) {
- Index3 = mCLen[Index++];
- if (Index3 == 0) {
- Count = 1;
- while (Index < Number && mCLen[Index] == 0) {
- Index++;
- Count++;
- }
- if (Count <= 2) {
- mTFreq[0] = (UINT16) (mTFreq[0] + Count);
- } else if (Count <= 18) {
- mTFreq[1]++;
- } else if (Count == 19) {
- mTFreq[0]++;
- mTFreq[1]++;
- } else {
- mTFreq[2]++;
- }
- } else {
- mTFreq[Index3 + 2]++;
- }
- }
- }
- STATIC
- VOID
- WritePTLen (
- IN INT32 Number,
- IN INT32 nbit,
- IN INT32 Special
- )
- /*++
- Routine Description:
- Outputs the code length array for the Extra Set or the Position Set.
- Arguments:
- Number - the number of symbols
- nbit - the number of bits needed to represent 'n'
- Special - the special symbol that needs to be take care of
- Returns: (VOID)
- --*/
- {
- INT32 Index;
- INT32 Index3;
- while (Number > 0 && mPTLen[Number - 1] == 0) {
- Number--;
- }
- PutBits (nbit, Number);
- Index = 0;
- while (Index < Number) {
- Index3 = mPTLen[Index++];
- if (Index3 <= 6) {
- PutBits (3, Index3);
- } else {
- PutBits (Index3 - 3, (1U << (Index3 - 3)) - 2);
- }
- if (Index == Special) {
- while (Index < 6 && mPTLen[Index] == 0) {
- Index++;
- }
- PutBits (2, (Index - 3) & 3);
- }
- }
- }
- STATIC
- VOID
- WriteCLen (
- VOID
- )
- /*++
- Routine Description:
- Outputs the code length array for Char&Length Set
- Arguments: (VOID)
- Returns: (VOID)
- --*/
- {
- INT32 Index;
- INT32 Index3;
- INT32 Number;
- INT32 Count;
- Number = NC;
- while (Number > 0 && mCLen[Number - 1] == 0) {
- Number--;
- }
- PutBits (CBIT, Number);
- Index = 0;
- while (Index < Number) {
- Index3 = mCLen[Index++];
- if (Index3 == 0) {
- Count = 1;
- while (Index < Number && mCLen[Index] == 0) {
- Index++;
- Count++;
- }
- if (Count <= 2) {
- for (Index3 = 0; Index3 < Count; Index3++) {
- PutBits (mPTLen[0], mPTCode[0]);
- }
- } else if (Count <= 18) {
- PutBits (mPTLen[1], mPTCode[1]);
- PutBits (4, Count - 3);
- } else if (Count == 19) {
- PutBits (mPTLen[0], mPTCode[0]);
- PutBits (mPTLen[1], mPTCode[1]);
- PutBits (4, 15);
- } else {
- PutBits (mPTLen[2], mPTCode[2]);
- PutBits (CBIT, Count - 20);
- }
- } else {
- PutBits (mPTLen[Index3 + 2], mPTCode[Index3 + 2]);
- }
- }
- }
- STATIC
- VOID
- EncodeC (
- IN INT32 Value
- )
- {
- PutBits (mCLen[Value], mCCode[Value]);
- }
- STATIC
- VOID
- EncodeP (
- IN UINT32 Value
- )
- {
- UINT32 Index;
- UINT32 NodeQ;
- Index = 0;
- NodeQ = Value;
- while (NodeQ) {
- NodeQ >>= 1;
- Index++;
- }
- PutBits (mPTLen[Index], mPTCode[Index]);
- if (Index > 1) {
- PutBits (Index - 1, Value & (0xFFFFFFFFU >> (32 - Index + 1)));
- }
- }
- STATIC
- VOID
- SendBlock (
- VOID
- )
- /*++
- Routine Description:
- Huffman code the block and output it.
- Arguments:
- (VOID)
- Returns:
- (VOID)
- --*/
- {
- UINT32 Index;
- UINT32 Index2;
- UINT32 Index3;
- UINT32 Flags;
- UINT32 Root;
- UINT32 Pos;
- UINT32 Size;
- Flags = 0;
- Root = MakeTree (NC, mCFreq, mCLen, mCCode);
- Size = mCFreq[Root];
- PutBits (16, Size);
- if (Root >= NC) {
- CountTFreq ();
- Root = MakeTree (NT, mTFreq, mPTLen, mPTCode);
- if (Root >= NT) {
- WritePTLen (NT, TBIT, 3);
- } else {
- PutBits (TBIT, 0);
- PutBits (TBIT, Root);
- }
- WriteCLen ();
- } else {
- PutBits (TBIT, 0);
- PutBits (TBIT, 0);
- PutBits (CBIT, 0);
- PutBits (CBIT, Root);
- }
- Root = MakeTree (NP, mPFreq, mPTLen, mPTCode);
- if (Root >= NP) {
- WritePTLen (NP, PBIT, -1);
- } else {
- PutBits (PBIT, 0);
- PutBits (PBIT, Root);
- }
- Pos = 0;
- for (Index = 0; Index < Size; Index++) {
- if (Index % UINT8_BIT == 0) {
- Flags = mBuf[Pos++];
- } else {
- Flags <<= 1;
- }
- if (Flags & (1U << (UINT8_BIT - 1))) {
- EncodeC (mBuf[Pos++] + (1U << UINT8_BIT));
- Index3 = mBuf[Pos++];
- for (Index2 = 0; Index2 < 3; Index2++) {
- Index3 <<= UINT8_BIT;
- Index3 += mBuf[Pos++];
- }
- EncodeP (Index3);
- } else {
- EncodeC (mBuf[Pos++]);
- }
- }
- for (Index = 0; Index < NC; Index++) {
- mCFreq[Index] = 0;
- }
- for (Index = 0; Index < NP; Index++) {
- mPFreq[Index] = 0;
- }
- }
- STATIC
- VOID
- Output (
- IN UINT32 CharC,
- IN UINT32 Pos
- )
- /*++
- Routine Description:
- Outputs an Original Character or a Pointer
- Arguments:
- CharC - The original character or the 'String Length' element of a Pointer
- Pos - The 'Position' field of a Pointer
- Returns: (VOID)
- --*/
- {
- STATIC UINT32 CPos;
- if ((mOutputMask >>= 1) == 0) {
- mOutputMask = 1U << (UINT8_BIT - 1);
- //
- // Check the buffer overflow per outputing UINT8_BIT symbols
- // which is an Original Character or a Pointer. The biggest
- // symbol is a Pointer which occupies 5 bytes.
- //
- if (mOutputPos >= mBufSiz - 5 * UINT8_BIT) {
- SendBlock ();
- mOutputPos = 0;
- }
- CPos = mOutputPos++;
- mBuf[CPos] = 0;
- }
- mBuf[mOutputPos++] = (UINT8) CharC;
- mCFreq[CharC]++;
- if (CharC >= (1U << UINT8_BIT)) {
- mBuf[CPos] |= mOutputMask;
- mBuf[mOutputPos++] = (UINT8) (Pos >> 24);
- mBuf[mOutputPos++] = (UINT8) (Pos >> 16);
- mBuf[mOutputPos++] = (UINT8) (Pos >> (UINT8_BIT));
- mBuf[mOutputPos++] = (UINT8) Pos;
- CharC = 0;
- while (Pos) {
- Pos >>= 1;
- CharC++;
- }
- mPFreq[CharC]++;
- }
- }
- STATIC
- VOID
- HufEncodeStart (
- VOID
- )
- {
- INT32 Index;
- for (Index = 0; Index < NC; Index++) {
- mCFreq[Index] = 0;
- }
- for (Index = 0; Index < NP; Index++) {
- mPFreq[Index] = 0;
- }
- mOutputPos = mOutputMask = 0;
- InitPutBits ();
- return ;
- }
- STATIC
- VOID
- HufEncodeEnd (
- VOID
- )
- {
- SendBlock ();
- //
- // Flush remaining bits
- //
- PutBits (UINT8_BIT - 1, 0);
- return ;
- }
- STATIC
- VOID
- MakeCrcTable (
- VOID
- )
- {
- UINT32 Index;
- UINT32 Index2;
- UINT32 Temp;
- for (Index = 0; Index <= UINT8_MAX; Index++) {
- Temp = Index;
- for (Index2 = 0; Index2 < UINT8_BIT; Index2++) {
- if (Temp & 1) {
- Temp = (Temp >> 1) ^ CRCPOLY;
- } else {
- Temp >>= 1;
- }
- }
- mCrcTable[Index] = (UINT16) Temp;
- }
- }
- STATIC
- VOID
- PutBits (
- IN INT32 Number,
- IN UINT32 Value
- )
- /*++
- Routine Description:
- Outputs rightmost n bits of x
- Arguments:
- Number - the rightmost n bits of the data is used
- x - the data
- Returns: (VOID)
- --*/
- {
- UINT8 Temp;
- while (Number >= mBitCount) {
- //
- // Number -= mBitCount should never equal to 32
- //
- Temp = (UINT8) (mSubBitBuf | (Value >> (Number -= mBitCount)));
- if (mDst < mDstUpperLimit) {
- *mDst++ = Temp;
- }
- mCompSize++;
- mSubBitBuf = 0;
- mBitCount = UINT8_BIT;
- }
- mSubBitBuf |= Value << (mBitCount -= Number);
- }
- STATIC
- INT32
- FreadCrc (
- OUT UINT8 *Pointer,
- IN INT32 Number
- )
- /*++
- Routine Description:
- Read in source data
- Arguments:
- Pointer - the buffer to hold the data
- Number - number of bytes to read
- Returns:
- number of bytes actually read
- --*/
- {
- INT32 Index;
- for (Index = 0; mSrc < mSrcUpperLimit && Index < Number; Index++) {
- *Pointer++ = *mSrc++;
- }
- Number = Index;
- Pointer -= Number;
- mOrigSize += Number;
- Index--;
- while (Index >= 0) {
- UPDATE_CRC (*Pointer++);
- Index--;
- }
- return Number;
- }
- STATIC
- VOID
- InitPutBits (
- VOID
- )
- {
- mBitCount = UINT8_BIT;
- mSubBitBuf = 0;
- }
- STATIC
- VOID
- CountLen (
- IN INT32 Index
- )
- /*++
- Routine Description:
- Count the number of each code length for a Huffman tree.
- Arguments:
- Index - the top node
- Returns: (VOID)
- --*/
- {
- STATIC INT32 Depth = 0;
- if (Index < mN) {
- mLenCnt[(Depth < 16) ? Depth : 16]++;
- } else {
- Depth++;
- CountLen (mLeft[Index]);
- CountLen (mRight[Index]);
- Depth--;
- }
- }
- STATIC
- VOID
- MakeLen (
- IN INT32 Root
- )
- /*++
- Routine Description:
- Create code length array for a Huffman tree
- Arguments:
- Root - the root of the tree
- Returns:
- VOID
- --*/
- {
- INT32 Index;
- INT32 Index3;
- UINT32 Cum;
- for (Index = 0; Index <= 16; Index++) {
- mLenCnt[Index] = 0;
- }
- CountLen (Root);
- //
- // Adjust the length count array so that
- // no code will be generated longer than its designated length
- //
- Cum = 0;
- for (Index = 16; Index > 0; Index--) {
- Cum += mLenCnt[Index] << (16 - Index);
- }
- while (Cum != (1U << 16)) {
- mLenCnt[16]--;
- for (Index = 15; Index > 0; Index--) {
- if (mLenCnt[Index] != 0) {
- mLenCnt[Index]--;
- mLenCnt[Index + 1] += 2;
- break;
- }
- }
- Cum--;
- }
- for (Index = 16; Index > 0; Index--) {
- Index3 = mLenCnt[Index];
- Index3--;
- while (Index3 >= 0) {
- mLen[*mSortPtr++] = (UINT8) Index;
- Index3--;
- }
- }
- }
- STATIC
- VOID
- DownHeap (
- IN INT32 Index
- )
- {
- INT32 Index2;
- INT32 Index3;
- //
- // priority queue: send Index-th entry down heap
- //
- Index3 = mHeap[Index];
- Index2 = 2 * Index;
- while (Index2 <= mHeapSize) {
- if (Index2 < mHeapSize && mFreq[mHeap[Index2]] > mFreq[mHeap[Index2 + 1]]) {
- Index2++;
- }
- if (mFreq[Index3] <= mFreq[mHeap[Index2]]) {
- break;
- }
- mHeap[Index] = mHeap[Index2];
- Index = Index2;
- Index2 = 2 * Index;
- }
- mHeap[Index] = (INT16) Index3;
- }
- STATIC
- VOID
- MakeCode (
- IN INT32 Number,
- IN UINT8 Len[ ],
- OUT UINT16 Code[]
- )
- /*++
- Routine Description:
- Assign code to each symbol based on the code length array
- Arguments:
- Number - number of symbols
- Len - the code length array
- Code - stores codes for each symbol
- Returns: (VOID)
- --*/
- {
- INT32 Index;
- UINT16 Start[18];
- Start[1] = 0;
- for (Index = 1; Index <= 16; Index++) {
- Start[Index + 1] = (UINT16) ((Start[Index] + mLenCnt[Index]) << 1);
- }
- for (Index = 0; Index < Number; Index++) {
- Code[Index] = Start[Len[Index]]++;
- }
- }
- STATIC
- INT32
- MakeTree (
- IN INT32 NParm,
- IN UINT16 FreqParm[],
- OUT UINT8 LenParm[ ],
- OUT UINT16 CodeParm[]
- )
- /*++
- Routine Description:
- Generates Huffman codes given a frequency distribution of symbols
- Arguments:
- NParm - number of symbols
- FreqParm - frequency of each symbol
- LenParm - code length for each symbol
- CodeParm - code for each symbol
- Returns:
- Root of the Huffman tree.
- --*/
- {
- INT32 Index;
- INT32 Index2;
- INT32 Index3;
- INT32 Avail;
- //
- // make tree, calculate len[], return root
- //
- mN = NParm;
- mFreq = FreqParm;
- mLen = LenParm;
- Avail = mN;
- mHeapSize = 0;
- mHeap[1] = 0;
- for (Index = 0; Index < mN; Index++) {
- mLen[Index] = 0;
- if (mFreq[Index]) {
- mHeapSize++;
- mHeap[mHeapSize] = (INT16) Index;
- }
- }
- if (mHeapSize < 2) {
- CodeParm[mHeap[1]] = 0;
- return mHeap[1];
- }
- for (Index = mHeapSize / 2; Index >= 1; Index--) {
- //
- // make priority queue
- //
- DownHeap (Index);
- }
- mSortPtr = CodeParm;
- do {
- Index = mHeap[1];
- if (Index < mN) {
- *mSortPtr++ = (UINT16) Index;
- }
- mHeap[1] = mHeap[mHeapSize--];
- DownHeap (1);
- Index2 = mHeap[1];
- if (Index2 < mN) {
- *mSortPtr++ = (UINT16) Index2;
- }
- Index3 = Avail++;
- mFreq[Index3] = (UINT16) (mFreq[Index] + mFreq[Index2]);
- mHeap[1] = (INT16) Index3;
- DownHeap (1);
- mLeft[Index3] = (UINT16) Index;
- mRight[Index3] = (UINT16) Index2;
- } while (mHeapSize > 1);
- mSortPtr = CodeParm;
- MakeLen (Index3);
- MakeCode (NParm, LenParm, CodeParm);
- //
- // return root
- //
- return Index3;
- }
- EFI_STATUS
- GetFileContents (
- IN char *InputFileName,
- OUT UINT8 *FileBuffer,
- OUT UINT32 *BufferLength
- )
- /*++
- Routine Description:
- Get the contents of file specified in InputFileName
- into FileBuffer.
- Arguments:
- InputFileName - Name of the input file.
- FileBuffer - Output buffer to contain data
- BufferLength - Actual length of the data
- Returns:
- EFI_SUCCESS on successful return
- EFI_ABORTED if unable to open input file.
- --*/
- {
- UINTN Size;
- UINTN FileSize;
- FILE *InputFile;
- Size = 0;
- //
- // Copy the file contents to the output buffer.
- //
- InputFile = fopen (LongFilePath (InputFileName), "rb");
- if (InputFile == NULL) {
- Error (NULL, 0, 0001, "Error opening file: %s", InputFileName);
- return EFI_ABORTED;
- }
- fseek (InputFile, 0, SEEK_END);
- FileSize = ftell (InputFile);
- fseek (InputFile, 0, SEEK_SET);
- //
- // Now read the contents of the file into the buffer
- //
- if (FileSize > 0 && FileBuffer != NULL) {
- if (fread (FileBuffer, FileSize, 1, InputFile) != 1) {
- Error (NULL, 0, 0004, "Error reading contents of input file: %s", InputFileName);
- fclose (InputFile);
- return EFI_ABORTED;
- }
- }
- fclose (InputFile);
- Size += (UINTN) FileSize;
- *BufferLength = Size;
- if (FileBuffer != NULL) {
- return EFI_SUCCESS;
- } else {
- return EFI_BUFFER_TOO_SMALL;
- }
- }
- VOID
- Version (
- VOID
- )
- /*++
- Routine Description:
- Displays the standard utility information to SDTOUT
- Arguments:
- None
- Returns:
- None
- --*/
- {
- fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
- }
- VOID
- Usage (
- VOID
- )
- /*++
- Routine Description:
- Displays the utility usage syntax to STDOUT
- Arguments:
- None
- Returns:
- None
- --*/
- {
- //
- // Summary usage
- //
- fprintf (stdout, "Usage: %s -e|-d [options] <input_file>\n\n", UTILITY_NAME);
- //
- // Copyright declaration
- //
- fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
- //
- // Details Option
- //
- fprintf (stdout, "Options:\n");
- fprintf (stdout, " --uefi\n\
- Enable UefiCompress, use TianoCompress when without this option\n");
- fprintf (stdout, " -o FileName, --output FileName\n\
- File will be created to store the output content.\n");
- fprintf (stdout, " -v, --verbose\n\
- Turn on verbose output with informational messages.\n");
- fprintf (stdout, " -q, --quiet\n\
- Disable all messages except key message and fatal error\n");
- fprintf (stdout, " --debug [0-9]\n\
- Enable debug messages, at input debug level.\n");
- fprintf (stdout, " --version\n\
- Show program's version number and exit.\n");
- fprintf (stdout, " -h, --help\n\
- Show this help message and exit.\n");
- }
- int
- main (
- int argc,
- char *argv[]
- )
- /*++
- Routine Description:
- Main
- Arguments:
- command line parameters
- Returns:
- EFI_SUCCESS Section header successfully generated and section concatenated.
- EFI_ABORTED Could not generate the section
- EFI_OUT_OF_RESOURCES No resource to complete the operation.
- --*/
- {
- FILE *OutputFile;
- char *OutputFileName;
- char *InputFileName;
- FILE *InputFile;
- EFI_STATUS Status;
- UINT8 *FileBuffer;
- UINT8 *OutBuffer;
- UINT32 InputLength;
- UINT32 DstSize;
- SCRATCH_DATA *Scratch;
- UINT8 *Src;
- UINT32 OrigSize;
- UINT32 CompSize;
- SetUtilityName(UTILITY_NAME);
- FileBuffer = NULL;
- Src = NULL;
- OutBuffer = NULL;
- Scratch = NULL;
- OrigSize = 0;
- CompSize = 0;
- InputLength = 0;
- InputFileName = NULL;
- OutputFileName = NULL;
- InputFile = NULL;
- OutputFile = NULL;
- DstSize=0;
- DebugLevel = 0;
- DebugMode = FALSE;
- //
- // Verify the correct number of arguments
- //
- if (argc == 1) {
- Error (NULL, 0, 1001, "Missing options", "No input options specified.");
- Usage();
- return 0;
- }
- if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0)) {
- Usage();
- return 0;
- }
- if ((strcmp(argv[1], "--version") == 0)) {
- Version();
- return 0;
- }
- argc--;
- argv++;
- if (strcmp(argv[0],"-e") == 0) {
- //
- // encode the input file
- //
- ENCODE = TRUE;
- argc--;
- argv++;
- } else if (strcmp(argv[0], "-d") == 0) {
- //
- // decode the input file
- //
- DECODE = TRUE;
- argc--;
- argv++;
- } else {
- //
- // Error command line
- //
- Error (NULL, 0, 1003, "Invalid option value", "the options specified are not recognized.");
- Usage();
- return 1;
- }
- while (argc > 0) {
- if ((strcmp(argv[0], "-v") == 0) || (stricmp(argv[0], "--verbose") == 0)) {
- VerboseMode = TRUE;
- argc--;
- argv++;
- continue;
- }
- if (stricmp(argv[0], "--uefi") == 0) {
- UEFIMODE = TRUE;
- argc--;
- argv++;
- continue;
- }
- if (stricmp (argv[0], "--debug") == 0) {
- argc-=2;
- argv++;
- Status = AsciiStringToUint64(argv[0], FALSE, &DebugLevel);
- if (DebugLevel > 9) {
- Error (NULL, 0 ,2000, "Invalid parameter", "Unrecognized argument %s", argv[0]);
- goto ERROR;
- }
- if (DebugLevel>=5 && DebugLevel <=9){
- DebugMode = TRUE;
- } else {
- DebugMode = FALSE;
- }
- argv++;
- continue;
- }
- if ((strcmp(argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
- QuietMode = TRUE;
- argc--;
- argv++;
- continue;
- }
- if ((strcmp(argv[0], "-o") == 0) || (stricmp (argv[0], "--output") == 0)) {
- if (argv[1] == NULL || argv[1][0] == '-') {
- Error (NULL, 0, 1003, "Invalid option value", "Output File name is missing for -o option");
- goto ERROR;
- }
- OutputFileName = argv[1];
- argc -=2;
- argv +=2;
- continue;
- }
- if (argv[0][0]!='-') {
- InputFileName = argv[0];
- argc--;
- argv++;
- continue;
- }
- Error (NULL, 0, 1000, "Unknown option", argv[0]);
- goto ERROR;
- }
- if (InputFileName == NULL) {
- Error (NULL, 0, 1001, "Missing options", "No input files specified.");
- goto ERROR;
- }
- //
- // All Parameters has been parsed, now set the message print level
- //
- if (QuietMode) {
- SetPrintLevel(40);
- } else if (VerboseMode) {
- SetPrintLevel(15);
- } else if (DebugMode) {
- SetPrintLevel(DebugLevel);
- }
- if (VerboseMode) {
- VerboseMsg("%s tool start.\n", UTILITY_NAME);
- }
- Scratch = (SCRATCH_DATA *)malloc(sizeof(SCRATCH_DATA));
- if (Scratch == NULL) {
- Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
- goto ERROR;
- }
- InputFile = fopen (LongFilePath (InputFileName), "rb");
- if (InputFile == NULL) {
- Error (NULL, 0, 0001, "Error opening input file", InputFileName);
- goto ERROR;
- }
- Status = GetFileContents(
- InputFileName,
- FileBuffer,
- &InputLength);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- FileBuffer = (UINT8 *) malloc (InputLength);
- if (FileBuffer == NULL) {
- Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
- goto ERROR;
- }
- Status = GetFileContents (
- InputFileName,
- FileBuffer,
- &InputLength
- );
- }
- if (EFI_ERROR(Status)) {
- Error (NULL, 0, 0004, "Error getting contents of file: %s", InputFileName);
- goto ERROR;
- }
- if (OutputFileName == NULL) {
- OutputFileName = DEFAULT_OUTPUT_FILE;
- }
- OutputFile = fopen (LongFilePath (OutputFileName), "wb");
- if (OutputFile == NULL) {
- Error (NULL, 0, 0001, "Error opening output file for writing", OutputFileName);
- goto ERROR;
- }
- if (ENCODE) {
- //
- // First call TianoCompress to get DstSize
- //
- if (DebugMode) {
- DebugMsg(UTILITY_NAME, 0, DebugLevel, "Encoding", NULL);
- }
- if (UEFIMODE) {
- Status = EfiCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);
- } else {
- Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);
- }
- if (Status == EFI_BUFFER_TOO_SMALL) {
- OutBuffer = (UINT8 *) malloc (DstSize);
- if (OutBuffer == NULL) {
- Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
- goto ERROR;
- }
- }
- if (UEFIMODE) {
- Status = EfiCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);
- } else {
- Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);
- }
- if (Status != EFI_SUCCESS) {
- Error (NULL, 0, 0007, "Error compressing file", NULL);
- goto ERROR;
- }
- if (OutBuffer == NULL) {
- Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
- goto ERROR;
- }
- fwrite(OutBuffer,(size_t)DstSize, 1, OutputFile);
- fclose(OutputFile);
- fclose(InputFile);
- free(Scratch);
- free(FileBuffer);
- free(OutBuffer);
- if (DebugMode) {
- DebugMsg(UTILITY_NAME, 0, DebugLevel, "Encoding Successful!\n", NULL);
- }
- if (VerboseMode) {
- VerboseMsg("Encoding successful\n");
- }
- return 0;
- }
- else if (DECODE) {
- if (DebugMode) {
- DebugMsg(UTILITY_NAME, 0, DebugLevel, "Decoding\n", NULL);
- }
- if (UEFIMODE) {
- Status = Extract((VOID *)FileBuffer, InputLength, (VOID *)&OutBuffer, &DstSize, 1);
- if (Status != EFI_SUCCESS) {
- goto ERROR;
- }
- fwrite(OutBuffer, (size_t)(DstSize), 1, OutputFile);
- } else {
- if (InputLength < 8){
- Error (NULL, 0, 3000, "Invalid", "The input file %s is too small.", InputFileName);
- goto ERROR;
- }
- //
- // Get Compressed file original size
- //
- Src = (UINT8 *)FileBuffer;
- OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
- CompSize = Src[0] + (Src[1] << 8) + (Src[2] <<16) + (Src[3] <<24);
- //
- // Allocate OutputBuffer
- //
- if (InputLength < CompSize + 8 || (CompSize + 8) < 8) {
- Error (NULL, 0, 3000, "Invalid", "The input file %s data is invalid.", InputFileName);
- goto ERROR;
- }
- OutBuffer = (UINT8 *)malloc(OrigSize);
- if (OutBuffer == NULL) {
- Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
- goto ERROR;
- }
- Status = TDecompress((VOID *)FileBuffer, (VOID *)OutBuffer, (VOID *)Scratch, 2);
- if (Status != EFI_SUCCESS) {
- goto ERROR;
- }
- fwrite(OutBuffer, (size_t)(Scratch->mOrigSize), 1, OutputFile);
- }
- fclose(OutputFile);
- fclose(InputFile);
- if (Scratch != NULL) {
- free(Scratch);
- }
- if (FileBuffer != NULL) {
- free(FileBuffer);
- }
- if (OutBuffer != NULL) {
- free(OutBuffer);
- }
- if (DebugMode) {
- DebugMsg(UTILITY_NAME, 0, DebugLevel, "Encoding successful!\n", NULL);
- }
- if (VerboseMode) {
- VerboseMsg("Decoding successful\n");
- }
- return 0;
- }
- ERROR:
- if (DebugMode) {
- if (ENCODE) {
- DebugMsg(UTILITY_NAME, 0, DebugLevel, "Encoding Error\n", NULL);
- } else if (DECODE) {
- DebugMsg(UTILITY_NAME, 0, DebugLevel, "Decoding Error\n", NULL);
- }
- }
- if (OutputFile != NULL) {
- fclose(OutputFile);
- }
- if (InputFile != NULL) {
- fclose (InputFile);
- }
- if (Scratch != NULL) {
- free(Scratch);
- }
- if (FileBuffer != NULL) {
- free(FileBuffer);
- }
- if (OutBuffer != NULL) {
- free(OutBuffer);
- }
- if (VerboseMode) {
- VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME, GetUtilityStatus ());
- }
- return GetUtilityStatus ();
- }
- 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) (((UINT64)Sd->mBitBuf) << NumOfBits);
- while (NumOfBits > Sd->mBitCount) {
- Sd->mBitBuf |= (UINT32) (((UINT64)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;
- }
- 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;
- }
- 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;
- UINT16 WordOfStart;
- UINT16 WordOfCount;
- UINT16 MaxTableLength;
- for (Index = 0; Index <= 16; Index++) {
- Count[Index] = 0;
- }
- for (Index = 0; Index < NumOfChar; Index++) {
- if (BitLen[Index] > 16) {
- return (UINT16) BAD_TABLE;
- }
- Count[BitLen[Index]]++;
- }
- Start[0] = 0;
- Start[1] = 0;
- for (Index = 1; Index <= 16; Index++) {
- WordOfStart = Start[Index];
- WordOfCount = Count[Index];
- Start[Index + 1] = (UINT16) (WordOfStart + (WordOfCount << (16 - Index)));
- }
- if (Start[17] != 0) {
- //
- //(1U << 16)
- //
- return (UINT16) BAD_TABLE;
- }
- JuBits = (UINT16) (16 - TableBits);
- Weight[0] = 0;
- 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));
- MaxTableLength = (UINT16) (1U << TableBits);
- for (Char = 0; Char < NumOfChar; Char++) {
- Len = BitLen[Char];
- if (Len == 0 || Len >= 17) {
- continue;
- }
- NextCode = (UINT16) (Start[Len] + Weight[Len]);
- if (Len <= TableBits) {
- for (Index = Start[Len]; Index < NextCode; Index++) {
- if (Index >= MaxTableLength) {
- return (UINT16) BAD_TABLE;
- }
- 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;
- }
- 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;
- }
- 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;
- volatile UINT16 Index;
- UINT32 Mask;
- assert (nn <= NPT);
- 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);
- }
- 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;
- volatile 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 ;
- }
- 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;
- }
- 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) {
- goto Done ;
- }
- if (CharC < 256) {
- //
- // Process an Original character
- //
- if (Sd->mOutBuf >= Sd->mOrigSize) {
- goto Done ;
- } 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) {
- if (Sd->mOutBuf >= Sd->mOrigSize) {
- goto Done ;
- }
- if (DataIdx >= Sd->mOrigSize) {
- Sd->mBadTableFlag = (UINT16) BAD_TABLE;
- goto Done ;
- }
- Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
- BytesRemain--;
- }
- //
- // Once mOutBuf is fully filled, directly return
- //
- if (Sd->mOutBuf >= Sd->mOrigSize) {
- goto Done ;
- }
- }
- }
- Done:
- return ;
- }
- RETURN_STATUS
- EFIAPI
- TDecompress (
- IN VOID *Source,
- IN OUT VOID *Destination,
- IN OUT VOID *Scratch,
- IN UINT32 Version
- )
- /*++
- Routine Description:
- The internal implementation of Decompress().
- Arguments:
- Source - The source buffer containing the compressed data.
- Destination - The destination buffer to store the decompressed data
- Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
- Version - 1 for EFI1.1 Decompress algorithm, 2 for Tiano Decompress algorithm
- Returns:
- RETURN_SUCCESS - Decompression is successful
- RETURN_INVALID_PARAMETER - The source data is corrupted
- --*/
- {
- volatile UINT32 Index;
- UINT32 CompSize;
- UINT32 OrigSize;
- SCRATCH_DATA *Sd;
- CONST UINT8 *Src;
- UINT8 *Dst;
- //
- // Verify input is not NULL
- //
- assert(Source);
- // assert(Destination);
- assert(Scratch);
- Src = (UINT8 *)Source;
- Dst = (UINT8 *)Destination;
- Sd = (SCRATCH_DATA *) Scratch;
- 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 RETURN_SUCCESS;
- }
- 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:
- assert(FALSE);
- }
- Sd->mSrcBase = (UINT8 *)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
- //
- return RETURN_INVALID_PARAMETER;
- }
- return RETURN_SUCCESS;
- }
|