123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- /**
- * @file hv_boot_Lzss.c
- * @brief Lzss source code.
- * @details This file provides the following functions: \n
- * (1) Initialization and de-initialization functions \n
- * (2) Start and stop functions \n
- * (3) Feed functions \n
- *
- * @author HiView SoC Software Team
- * @version 1.0.0
- * @date 2022-08-18
- * @copyright Copyright(c),2022-8, Hiview Software. All rights reserved.
- * @par History:
- * <table>
- * <tr><th>Author <th>Date <th>Change Description
- * <tr><td>HiView SoC Software Team <td>2022-08-23 <td>init
- * </table>
- */
- #include "hv_chip_Config.h"
- #include "hv_boot_Common.h"
- #define N 4096 /* size of ring buffer */
- #define F 18 /* upper limit for match_length */
- #define THRESHOLD 4 /* encode string into position and length if match_length is greater than this */
- #define NIL N /* index for root of binary search trees */
- static unsigned long int textsize = 0; /* text size counter */
- static unsigned long int codesize = 0; /* code size counter */
- static unsigned long int printcount = 0; /* counter for reporting progress every 1K bytes */
- static unsigned char text_buf[N + F - 1] = {0}; /* ring buffer of size N,with extra F-1 bytes to facilitate string comparison */
- static int match_position = 0;
- static int match_length = 0; /* of longest match. These are set by the InsertNode() procedure. */
- static int lson[N + 1] = {0};
- static int rson[N + 257] = {0};
- static int dad[N + 1] = {0}; /* left & right children &parents -- These constitute binary search trees. */
- /* input & output files */
- static unsigned char *infile = 0;
- static unsigned char *fileoff = 0;
- static unsigned char *outfile = 0;
- void InitTree(void) /* initialize trees */
- {
- int i;
- /* For i = 0 to N - 1, rson[i] and lson[i] will be the right and
- left children of node i. These nodes need not be initialized.
- Also, dad[i] is the parent of node i. These are initialized to
- NIL (= N), which stands for 'not used.'
- For i = 0 to 255, rson[N + i + 1] is the root of the tree
- for strings that begin with character i. These are initialized
- to NIL. Note there are 256 trees. */
- for (i = N + 1; i <= N + 256; i++) rson[i] = NIL;
- for (i = 0; i < N; i++) dad[i] = NIL;
- }
- void InsertNode(int r)
- /* Inserts string of length F, text_buf[r..r+F-1], into one of the
- trees (text_buf[r]'th tree) and returns the longest-match position
- and length via the global variables match_position and match_length.
- If match_length = F, then removes the old node in favor of the new
- one, because the old one will be deleted sooner.
- Note r plays double role, as tree node and position in buffer. */
- {
- int i, p, cmp;
- unsigned char *key;
- cmp = 1; key = &text_buf[r]; p = N + 1 + key[0];
- rson[r] = lson[r] = NIL; match_length = 0;
- for ( ; ; ) {
- if (cmp >= 0) {
- if (rson[p] != NIL) p = rson[p];
- else { rson[p] = r; dad[r] = p; return; }
- } else {
- if (lson[p] != NIL) p = lson[p];
- else { lson[p] = r; dad[r] = p; return; }
- }
- for (i = 1; i < F; i++)
- if ((cmp = key[i] - text_buf[p + i]) != 0) break;
- if (i > match_length) {
- match_position = p;
- if ((match_length = i) >= F) break;
- }
- }
- dad[r] = dad[p]; lson[r] = lson[p]; rson[r] = rson[p];
- dad[lson[p]] = r; dad[rson[p]] = r;
- if (rson[dad[p]] == p) rson[dad[p]] = r;
- else lson[dad[p]] = r;
- dad[p] = NIL; /* remove p */
- }
- void DeleteNode(int p) /* deletes node p from tree */
- {
- int q;
- if (dad[p] == NIL) return; /* not in tree */
- if (rson[p] == NIL) q = lson[p];
- else if (lson[p] == NIL) q = rson[p];
- else {
- q = lson[p];
- if (rson[q] != NIL) {
- do { q = rson[q]; } while (rson[q] != NIL);
- rson[dad[q]] = lson[q]; dad[lson[q]] = dad[q];
- lson[q] = lson[p]; dad[lson[p]] = q;
- }
- rson[q] = rson[p]; dad[rson[p]] = q;
- }
- dad[q] = dad[p];
- if (rson[dad[p]] == p) rson[dad[p]] = q; else lson[dad[p]] = q;
- dad[p] = NIL;
- }
- void Decode(void) /* Just the reverse of Encode(). */
- {
- int i, j, k, r, c;
- unsigned int flags;
- for (i = 0; i < N - F; i++) text_buf[i] = ' ';
- r = N - F; flags = 0;
- for ( ; ; ) {
- if (((flags >>= 1) & 256) == 0) {
- if (infile==fileoff)
- {
- break;
- }
- c = *infile++;
- flags = c | 0xff00; /* uses higher byte cleverly */
- } /* to count eight */
- if (flags & 1) {
- if (infile==fileoff)
- {
- break;
- }
- c = *infile++;
- *outfile++=c; text_buf[r++] = c; r &= (N - 1);
- } else {
- if (infile==fileoff)
- {
- break;
- }
- i = *infile++;
- if (infile==fileoff)
- {
- break;
- }
- j = *infile++;
- i |= ((j & 0xf0) << 4); j = (j & 0x0f) + THRESHOLD;
- for (k = 0; k <= j; k++) {
- c = text_buf[(i + k) & (N - 1)];
- *outfile++=c; text_buf[r++] = c; r &= (N - 1);
- }
- }
- }
- }
- int Hv_Boot_GetFileSize(void)
- {
- char *pcPoint = infile;
- int uiSize = 0;
- int iCount = 0;
- unsigned int uiMaigic = 0;
- Hv_Boot_Print_String(BOOT_DEBUG_LEVEL_INFO, ">>> check size in\n");
- Hv_Boot_PrintHex(BOOT_DEBUG_LEVEL_INFO, (unsigned int)infile);
- /* check magic "HIVIEW!" */
- for (pcPoint = infile, iCount = 0; iCount < 4; iCount++, pcPoint++)
- {
- uiMaigic = (uiMaigic << 8) + (*pcPoint);
- }
- if (uiMaigic != 0x48495649)
- {
- Hv_Boot_Print_String(BOOT_DEBUG_LEVEL_WAR, ">>> no hivi\n");
- return -1;
- }
- for (pcPoint = infile + 4, iCount = 0; iCount < 4; iCount++, pcPoint++)
- {
- uiMaigic = (uiMaigic << 8) + (*pcPoint);
- }
- if (uiMaigic != 0x4557210A)
- {
- Hv_Boot_Print_String(BOOT_DEBUG_LEVEL_WAR, ">>> no iew!\n");
- return -2;
- }
- /* check size */
- for (pcPoint = infile + 8, iCount = 0;
- (*pcPoint != 0xa) && (*pcPoint < 0x3a) && (*pcPoint > 0x2f) && (iCount < 8);
- pcPoint++,iCount++)
- {
- uiSize = uiSize * 10 + (*pcPoint - 0x30);
- }
- if ((uiSize > 512) && (uiSize < 1458716))
- {
- infile += 32;
- fileoff = infile + uiSize;
- Hv_Boot_PrintHex(BOOT_DEBUG_LEVEL_INFO, uiSize);
- return 0;
- }
- Hv_Boot_Print_String(BOOT_DEBUG_LEVEL_WAR, ">>> size wrong!\n");
- return -3;
- }
- int Hv_Boot_LzssDecompress(char *pcSrc, char *pcDst, int iChanegeEndian, int iSize)
- {
- int iLoop = 0;
- unsigned char ucTemp = 0;
- if (pcSrc != 0)
- {
- infile = pcSrc;
- }
- if (infile == 0)
- {
- return -1;
- }
- if (pcDst == 0)
- {
- return -1;
- }
- outfile = pcDst;
- if (Hv_Boot_GetFileSize())
- {
- if (iSize == 0)
- {
- return -1;
- } else {
- fileoff = infile + iSize;
- Hv_Boot_Print_String(BOOT_DEBUG_LEVEL_INFO, ">>> valid size\n");
- Hv_Boot_PrintHex(BOOT_DEBUG_LEVEL_INFO, (unsigned int)iSize);
- }
- }
- Hv_Boot_Print_String(BOOT_DEBUG_LEVEL_INFO, ">>> decompress bin\n");
- Hv_Boot_PrintHex(BOOT_DEBUG_LEVEL_INFO, (unsigned int)infile);
- Hv_Boot_PrintHex(BOOT_DEBUG_LEVEL_INFO, (unsigned int)fileoff);
- Decode();
- Hv_Boot_Print_String(BOOT_DEBUG_LEVEL_INFO, ">>> decompress bin over\n");
- Hv_Boot_PrintHex(BOOT_DEBUG_LEVEL_INFO, (unsigned int)pcDst);
- Hv_Boot_PrintHex(BOOT_DEBUG_LEVEL_INFO, (unsigned int)outfile);
- if (iChanegeEndian == 0)
- {
- return 0;
- }
- for (iLoop = 0; iLoop < (fileoff - infile); iLoop += 4)
- {
- ucTemp = *(infile+iLoop+3);
- *(infile+iLoop+3) = *(infile+iLoop+0);
- *(infile+iLoop+0) = ucTemp;
- ucTemp = *(infile+iLoop+2);
- *(infile+iLoop+2) = *(infile+iLoop+1);
- *(infile+iLoop+1) = ucTemp;
- }
- return 0;
- }
|