xref: /utopia/UTPA2-700.0.x/modules/gpd/drv/gpd/inflate.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 //    Software and any modification/derivatives thereof.
18 //    No right, ownership, or interest to MStar Software and any
19 //    modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 //    supplied together with third party`s software and the use of MStar
23 //    Software may require additional licenses from third parties.
24 //    Therefore, you hereby agree it is your sole responsibility to separately
25 //    obtain any and all third party right and license necessary for your use of
26 //    such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 //    MStar`s confidential information and you agree to keep MStar`s
30 //    confidential information in strictest confidence and not disclose to any
31 //    third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 //    kind. Any warranties are hereby expressly disclaimed by MStar, including
35 //    without limitation, any warranties of merchantability, non-infringement of
36 //    intellectual property rights, fitness for a particular purpose, error free
37 //    and in conformity with any international standard.  You agree to waive any
38 //    claim against MStar for any loss, damage, cost or expense that you may
39 //    incur related to your use of MStar Software.
40 //    In no event shall MStar be liable for any direct, indirect, incidental or
41 //    consequential damages, including without limitation, lost of profit or
42 //    revenues, lost or damage of data, and unauthorized system use.
43 //    You agree that this Section 4 shall still apply without being affected
44 //    even if MStar Software has been modified by MStar in accordance with your
45 //    request or instruction for your use, except otherwise agreed by both
46 //    parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 //    services in relation with MStar Software to you for your use of
50 //    MStar Software in conjunction with your or your customer`s product
51 //    ("Services").
52 //    You understand and agree that, except otherwise agreed by both parties in
53 //    writing, Services are provided on an "AS IS" basis and the warranty
54 //    disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 //    or otherwise:
58 //    (a) conferring any license or right to use MStar name, trademark, service
59 //        mark, symbol or any other identification;
60 //    (b) obligating MStar or any of its affiliates to furnish any person,
61 //        including without limitation, you and your customers, any assistance
62 //        of any kind whatsoever, or any information; or
63 //    (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 //    of Taiwan, R.O.C., excluding its conflict of law rules.
67 //    Any and all dispute arising out hereof or related hereto shall be finally
68 //    settled by arbitration referred to the Chinese Arbitration Association,
69 //    Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 //    Rules of the Association by three (3) arbitrators appointed in accordance
71 //    with the said Rules.
72 //    The place of arbitration shall be in Taipei, Taiwan and the language shall
73 //    be English.
74 //    The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 /* inflate.c -- zlib decompression
79  * Copyright (C) 1995-2005 Mark Adler
80  * For conditions of distribution and use, see copyright notice in zlib.h
81  */
82 
83 /*
84  * Change history:
85  *
86  * 1.2.beta0    24 Nov 2002
87  * - First version -- complete rewrite of inflate to simplify code, avoid
88  *   creation of window when not needed, minimize use of window when it is
89  *   needed, make inffast.c even faster, implement gzip decoding, and to
90  *   improve code readability and style over the previous zlib inflate code
91  *
92  * 1.2.beta1    25 Nov 2002
93  * - Use pointers for available input and output checking in inffast.c
94  * - Remove input and output counters in inffast.c
95  * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
96  * - Remove unnecessary second byte pull from length extra in inffast.c
97  * - Unroll direct copy to three copies per loop in inffast.c
98  *
99  * 1.2.beta2    4 Dec 2002
100  * - Change external routine names to reduce potential conflicts
101  * - Correct filename to inffixed.h for fixed tables in inflate.c
102  * - Make hbuf[] MS_U8 to match parameter type in inflate.c
103  * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
104  *   to avoid negation problem on Alphas (64 bit) in inflate.c
105  *
106  * 1.2.beta3    22 Dec 2002
107  * - Add comments on state->bits assertion in inffast.c
108  * - Add comments on op field in inftrees.h
109  * - Fix bug in reuse of allocated window after inflateReset()
110  * - Remove bit fields--back to byte structure for speed
111  * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
112  * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
113  * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
114  * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
115  * - Use local copies of stream next and avail values, as well as local bit
116  *   buffer and bit count in inflate()--for speed when inflate_fast() not used
117  *
118  * 1.2.beta4    1 Jan 2003
119  * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
120  * - Move a comment on output buffer sizes from inffast.c to inflate.c
121  * - Add comments in inffast.c to introduce the inflate_fast() routine
122  * - Rearrange window copies in inflate_fast() for speed and simplification
123  * - Unroll last copy for window match in inflate_fast()
124  * - Use local copies of window variables in inflate_fast() for speed
125  * - Pull out common write == 0 case for speed in inflate_fast()
126  * - Make op and len in inflate_fast() unsigned for consistency
127  * - Add FAR to lcode and dcode declarations in inflate_fast()
128  * - Simplified bad distance check in inflate_fast()
129  * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
130  *   source file infback.c to provide a call-back interface to inflate for
131  *   programs like gzip and unzip -- uses window as output buffer to avoid
132  *   window copying
133  *
134  * 1.2.beta5    1 Jan 2003
135  * - Improved inflateBack() interface to allow the caller to provide initial
136  *   input in strm.
137  * - Fixed stored blocks bug in inflateBack()
138  *
139  * 1.2.beta6    4 Jan 2003
140  * - Added comments in inffast.c on effectiveness of POSTINC
141  * - Typecasting all around to reduce compiler warnings
142  * - Changed loops from while (1) or do {} while (1) to for (;;), again to
143  *   make compilers happy
144  * - Changed type of window in inflateBackInit() to MS_U8 *
145  *
146  * 1.2.beta7    27 Jan 2003
147  * - Changed many types to unsigned or MS_U16 to avoid warnings
148  * - Added inflateCopy() function
149  *
150  * 1.2.0        9 Mar 2003
151  * - Changed inflateBack() interface to provide separate opaque descriptors
152  *   for the in() and out() functions
153  * - Changed inflateBack() argument and in_func typedef to swap the length
154  *   and buffer address return values for the input function
155  * - Check next_in and next_out for Z_NULL on entry to inflate()
156  *
157  * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
158  */
159 
160 #include "MsCommon.h"
161 #include "zutil.h"
162 #include "inftrees.h"
163 #include "inflate.h"
164 #include "gpd_reg.h"
165 #include "drvgpd.h"
166 
167 
168 #ifdef MAKEFIXED
169 #  ifndef BUILDFIXED
170 #    define BUILDFIXED
171 #  endif
172 #endif
173 
174 
175 extern MS_U16 read_fifo(MS_U32 n);
176 extern MS_U16 show_fifo(MS_U32 n);
177 
178 struct inflate_state inflatestate;
179 
180 
181 
182 /* function prototypes */
183 void gpdfixedtables OF((struct inflate_state FAR *state));
184 
185 #ifdef BUILDFIXED
186    void makefixed OF((void));
187 #endif
188 
189 #if 0
190 MS_U32 ZEXPORT gpdinflateReset(strm)
191 z_streamp strm;
192 {
193     struct inflate_state FAR *state;
194 
195     state = (struct inflate_state FAR *)strm->state;
196     state->mode = HEAD;
197     state->last = 0;
198     state->lencode = state->distcode = state->next = state->codes;
199 
200     return Z_OK;
201 }
202 #endif
203 
gpdinflateReset(z_streamp strm)204 MS_U32 ZEXPORT gpdinflateReset(z_streamp strm)
205 {
206     struct inflate_state FAR *state;
207 
208     state = (struct inflate_state FAR *)strm->state;
209     state->mode = HEAD;
210     state->last = 0;
211     state->lencode = state->distcode = state->next = state->codes;
212 
213     return Z_OK;
214 }
215 
216 
217 
gpdinflateInit2_(strm,windowBits,version,stream_size)218 MS_U32 ZEXPORT gpdinflateInit2_(strm, windowBits, version, stream_size)
219 z_streamp strm;
220 MS_U32 windowBits;
221 const char *version;
222 MS_U32 stream_size;
223 {
224     struct inflate_state FAR *state;
225 
226     state = (struct inflate_state FAR *)&inflatestate;
227     strm->state = (struct internal_state FAR *)state;
228 
229     return gpdinflateReset(strm);
230 }
231 
gpdinflateInit_(strm,version,stream_size)232 MS_U32 ZEXPORT gpdinflateInit_(strm, version, stream_size)
233 z_streamp strm;
234 const char *version;
235 MS_U32 stream_size;
236 {
237     return gpdinflateInit2_(strm, DEF_WBITS, version, stream_size);
238 }
239 
240 /*
241    Return state with length and distance decoding tables and index sizes set to
242    fixed code decoding.  Normally this returns fixed tables from inffixed.h.
243    If BUILDFIXED is defined, then instead this routine builds the tables the
244    first time it's called, and returns those tables the first time and
245    thereafter.  This reduces the size of the code by about 2K bytes, in
246    exchange for a little execution time.  However, BUILDFIXED should not be
247    used for threaded applications, since the rewriting of the tables and virgin
248    may not be thread-safe.
249  */
gpdfixedtables(state)250 void gpdfixedtables(state)
251 struct inflate_state FAR *state;
252 {
253     MS_U32 data;
254     MS_U16 tmp_data[16];
255 
256     /*
257     drv_gpd_set_lbase_g1(0);
258 
259     //set lbase7
260 
261     drv_gpd_set_lbase_g2(0);
262 
263 
264     //set lbase8  lbase9  lbase10
265 
266     data=0x18+(0xb0<<PNG_LBASE9_SHF)+(0x120<<PNG_LBASE10_SHF);
267 
268 
269     drv_gpd_set_lbase_g3(data);
270 
271     //console_printf("set lbase");
272     */
273 
274     memset(tmp_data, 0, sizeof(tmp_data));
275     tmp_data[8]  = 0x18;
276     tmp_data[9]  = 0xb0;
277     tmp_data[10] = 0x120;
278     drv_gpd_set_lbase(tmp_data);
279 
280 
281     //set lit_mincode_valid or dist_mincode_valid
282 
283 
284     data=0x1c0;
285     drv_gpd_set_lmincode_valid(data);
286 
287 
288 
289     //console_printf("set lit_mincode_valid or dist_mincode_valid");
290 
291 
292     drv_gpd_set_fixed_ldata();
293 
294     //console_printf("set ltbl_data");
295 
296 
297     //set lit_mincode
298 
299     /*
300     //set mincode7
301 
302 
303     drv_gpd_set_lmincode_g1(0);
304 
305     //set mincode8  mincode9
306 
307     data=0x30+(0x190<<PNG_MINCODE9_SHF);
308 
309     drv_gpd_set_lmincode_g2(data);
310     */
311 
312     memset(tmp_data, 0, sizeof(tmp_data));
313     tmp_data[8]  = 0x30;
314     tmp_data[9]  = 0x190;
315     drv_gpd_set_lmincode(tmp_data);
316 
317     //console_printf("set lit_mincode ");
318 
319     set_nop_cmd(10);
320 
321     /*
322     drv_gpd_set_dmincode_g5(0);
323     */
324 
325     memset(tmp_data, 0, sizeof(tmp_data));
326     drv_gpd_set_dmincode(tmp_data);
327 
328 }
329 
330 #ifdef MAKEFIXED
331 #include <stdio.h>
332 
333 /*
334    Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also
335    defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes
336    those tables to stdout, which would be piped to inffixed.h.  A small program
337    can simply call makefixed to do this:
338 
339     void makefixed(void);
340 
341     MS_U32 main(void)
342     {
343         makefixed();
344         return 0;
345     }
346 
347    Then that can be linked with zlib built with MAKEFIXED defined and run:
348 
349     a.out > inffixed.h
350  */
makefixed()351 void makefixed()
352 {
353     MS_U32 low, size;
354     struct inflate_state state;
355 
356     fixedtables(&state);
357     puts("    /* inffixed.h -- table for decoding fixed codes");
358     puts("     * Generated automatically by makefixed().");
359     puts("     */");
360     puts("");
361     puts("    /* WARNING: this file should *not* be used by applications.");
362     puts("       It is part of the implementation of this library and is");
363     puts("       subject to change. Applications should only use zlib.h.");
364     puts("     */");
365     puts("");
366     size = 1U << 9;
367     printf("    static const code lenfix[%u] = {", size);
368     low = 0;
369     for (;;) {
370         if ((low % 7) == 0) printf("\n        ");
371         printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
372                state.lencode[low].val);
373         if (++low == size) break;
374         putchar(',');
375     }
376     puts("\n    };");
377     size = 1U << 5;
378     printf("\n    static const code distfix[%u] = {", size);
379     low = 0;
380     for (;;) {
381         if ((low % 6) == 0) printf("\n        ");
382         printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
383                state.distcode[low].val);
384         if (++low == size) break;
385         putchar(',');
386     }
387     puts("\n    };");
388 }
389 #endif /* MAKEFIXED */
390 
391 /*
392    Update the window with the last wsize (normally 32K) bytes written before
393    returning.  If window does not exist yet, create it.  This is only called
394    when a window is already in use, or when output has been written during this
395    inflate call, but the end of the deflate stream has not been reached yet.
396    It is also called to create a window for dictionary data when a dictionary
397    is loaded.
398 
399    Providing output buffers larger than 32K to inflate() should provide a speed
400    advantage, since only the last 32K of output is copied to the sliding window
401    upon return from inflate(), and since all distances after the first 32K of
402    output will fall in the output data, making match copies simpler and faster.
403    The advantage may be dependent on the size of the processor's data caches.
404  */
405 
406 
407 
408 
409 /* Reverse the bytes in a 32-bit value */
410 MS_U32 num = 0, blk_typ;
411 static MS_U8 prev,curr;
412 extern MS_U32 nocompress, fix, dynamic;
413 
gpdinflate(strm,flag)414 MS_U32 ZEXPORT gpdinflate(strm, flag)
415 z_streamp strm;
416 MS_U32 flag;
417 {
418     MS_U32 i;
419     //extern MS_U32 huff_reg_time;
420     MS_U32 ncodebits;
421     MS_U32 ncodetmp;
422     //MS_U32 test1, test2;
423     MS_U32 dbport, bitoffset = 0, tmpxx;
424     //MS_U32 hold;
425     //MS_U32 bits;
426     MS_U8 readdata1/*, readdata2*/;
427     MS_U16 readtmp;
428     MS_U16 readdata3;
429     struct inflate_state FAR *state;
430     MS_U32 copy;
431     code this;                  /* current decoding table entry */
432     //code last;                  /* parent table entry */
433     MS_U32 len;               /* length to copy for repeats, bits to drop */
434     MS_U32 ret;                    /* return code */
435 #ifdef GUNZIP
436     //MS_U8 hbuf[4];      /* buffer for gzip header crc calculation */
437 #endif
438     static const MS_U16 order[20] = /* permutation of code lengths */
439         {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, 0};
440 
441     state = (struct inflate_state FAR *)strm->state;
442     if (flag == 0)
443     	state->mode = TYPEDO;
444     ret = Z_OK;
445 
446     for (;;)
447     {
448         switch (state->mode)
449         {
450         case HEAD:
451             read_fifo(16);
452             state->mode = TYPEDO;
453             break;
454 
455         case TYPEDO:
456             readtmp = read_fifo(3);
457             state->last = readtmp & 0x01;
458             readdata1 = (readtmp & 0x06) >> 1;
459             num++;
460             blk_typ = readdata1;
461 
462             switch(readdata1)
463             {
464             case 0:
465                 dbport = drv_gpd_bitpos();
466                 dbport &= (0x07);
467                 if (dbport)
468                 {
469                     bitoffset = 8 - dbport;
470                     dbport = read_fifo(bitoffset);
471                 }
472                 else
473                 {
474                     bitoffset = 0;
475                 }
476 
477                 curr = 0;
478                 state->mode = DONE;
479                 //set compression_type
480                 drv_gpd_set_cmp_type(curr);
481                 prev = curr;
482                 break;
483 
484             case 1:
485                 curr = 2;
486                 if(curr != prev)
487                     gpdfixedtables(state);
488                 state->mode = DONE;
489                 //set compression_type
490                 drv_gpd_set_cmp_type(curr);
491                 prev = curr;
492                 break;
493 
494             case 2:
495                 curr = 3;
496                 state->mode = TABLE;
497                 drv_gpd_set_cmp_type(curr);
498                 prev = curr;
499                 break;
500 
501             case 3:
502                 //console_printf("invalid block type\n");
503                 state->mode = BAD;
504             }
505             break;
506 
507         case TABLE:
508             readtmp = read_fifo(14);
509             state->nlen = (readtmp&(0x001f))+257;
510             state->ndist = ((readtmp&(0x03e0))>>5)+1;
511             state->ncode = ((readtmp&(0x3c00))>>10)+4;
512 #ifndef PKZIP_BUG_WORKAROUND
513             if (state->nlen > 286 || state->ndist > 30)
514             {
515                 state->mode = BAD;
516                 break;
517             }
518 #endif
519             state->have = 0;
520             state->mode = LENLENS;
521 
522         case LENLENS:
523             ncodebits = 3 * state->ncode;
524             while(ncodebits>=15)
525             {
526                 readtmp=read_fifo(15);
527 
528                 for(i = 0; i < 5; i++)
529                 {
530                     if(state->have < 19)
531                     {
532                         state->lens[order[state->have++]] = ((readtmp&((0x0007)<<(i*3)))>>(i*3));
533                     }
534                 }
535                 ncodebits-=15;
536             }
537             if(ncodebits)
538             {
539                 readtmp=read_fifo(ncodebits);
540                 ncodetmp = state->ncode%5;
541                 for(i=0;i<ncodetmp;i++)
542                 {
543                     if(state->have < 19)
544                     {
545                         state->lens[order[state->have++]]=((readtmp&((0x0007)<<(i*3)))>>(i*3));
546                     }
547                 }
548             }
549 
550             while (state->have < 19)
551                 state->lens[order[state->have++]] = 0;
552 
553             state->next = state->codes;
554             state->lencode = (code const FAR *)(state->next);
555             state->lenbits = 7;
556             ret = gpdinflate_table(CODES, state->lens, 19, &(state->next),
557             &(state->lenbits), state->work);
558 
559             if (ret)
560             {
561                 //console_printf("invalid code length set\n");
562                 state->mode = BAD;
563                 break;
564             }
565 
566             state->have = 0;
567             state->mode = CODELENS;
568 
569         case CODELENS:
570             while (state->have < state->nlen + state->ndist)
571             {
572                 readdata3 = show_fifo(state->lenbits);
573                 this = state->lencode[readdata3];
574 
575                 if (this.val < 16)
576                 {
577                     read_fifo(this.bits);
578                     state->lens[state->have++] = this.val;
579                 }
580                 else
581                 {
582                     if (this.val == 16)
583                     {
584                         if((this.bits+2)>16)
585                         {
586                             read_fifo(this.bits);
587                             copy=3+read_fifo(2);
588                         }
589                         else
590                         {
591                             tmpxx = this.bits+2;
592                             readtmp=read_fifo(tmpxx);
593                             copy=3+((readtmp>>this.bits)&0x0003);
594                         }
595 
596                         if (state->have == 0)
597                         {
598                             //console_printf("invalid bit length repeat\n");
599                             state->mode = BAD;
600                             break;
601                         }
602                         len = state->lens[state->have - 1];
603                     }
604 
605                     else if (this.val == 17)
606                     {
607                         if((this.bits+3)>16)
608                         {
609                             read_fifo(this.bits);
610                             copy=3+read_fifo(3);
611                         }
612                         else
613                         {
614                             tmpxx= this.bits+3;
615                             readtmp=read_fifo(tmpxx);
616                             copy=3+((readtmp>>this.bits)&0x0007);
617                         }
618                         len=0;
619                     }
620 
621                     else
622                     {
623                         if((this.bits+7)>16)
624                         {
625                             read_fifo(this.bits);
626                             copy=11+read_fifo(7);
627                         }
628                         else
629                         {
630                             tmpxx = this.bits+7;
631                             readtmp=read_fifo(tmpxx);
632                             copy=11+((readtmp>>this.bits)&0x007f);
633                         }
634                         len=0;
635                     }
636 
637                     if (state->have + copy > state->nlen + state->ndist)
638                     {
639 
640                         //console_printf("invalid bit length repeat\n");
641                         state->mode = BAD;
642                         break;
643                     }
644                     while (copy--)
645                     {
646                         state->lens[state->have++] = (MS_U16)len;
647 
648                     }
649                 }
650             }
651 
652 
653             /* handle error breaks in while */
654             if (state->mode == BAD) break;
655 
656             /* build code tables */
657             state->next = state->codes;
658             state->lencode = (code const FAR *)(state->next);
659             state->lenbits = 9;
660             ret = gpdinflate_table(LENS, state->lens, state->nlen, &(state->next),
661             &(state->lenbits), state->work);
662             if (ret)
663             {
664                 //console_printf("invalid literal/length set\n");
665                 state->mode = BAD;
666                 break;
667             }
668             state->distcode = (code const FAR *)(state->next);
669             state->distbits = 6;
670             ret = gpdinflate_table(DISTS, state->lens + state->nlen, state->ndist,
671             &(state->next), &(state->distbits), state->work);
672             if (ret)
673             {
674 
675                 //console_printf("invalid distance set\n");
676                 state->mode = BAD;
677                 break;
678             }
679 
680             state->mode = DONE;
681 
682 
683         case DONE:
684             if (state->last) {
685 
686                 prev=255;
687                 return Z_STREAM_END;
688             }
689             else
690                 return Z_OK;
691 
692         case BAD:
693             return Z_STREAM_ERROR;
694 
695         default:
696             return Z_STREAM_ERROR;
697         }
698     }
699     /*
700        Return from inflate(), updating the total counts and the check value.
701        If there was no progress during the inflate() call, return a buffer
702        error.  Call updatewindow() to create and/or update the window state.
703        Note: a memory error from inflate() is non-recoverable.
704      */
705 }
706 
707