summaryrefslogtreecommitdiff
path: root/graphics/sam2p/l1zip.psm
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /graphics/sam2p/l1zip.psm
Initial commit
Diffstat (limited to 'graphics/sam2p/l1zip.psm')
-rw-r--r--graphics/sam2p/l1zip.psm1439
1 files changed, 1439 insertions, 0 deletions
diff --git a/graphics/sam2p/l1zip.psm b/graphics/sam2p/l1zip.psm
new file mode 100644
index 0000000000..0c462a09ee
--- /dev/null
+++ b/graphics/sam2p/l1zip.psm
@@ -0,0 +1,1439 @@
+/*%
+% l1zip.psm -- /FlateDecode image data implementation for /PSL1
+% by pts@fazekas.hu at Sun Sep 22 01:01:00 CEST 2002
+% formerly flatedecode.psm -- please run faltedecode_eps_helper.sh...
+% by pts@fazekas.hu at Fri Sep 20 23:31:36 CEST 2002
+% -- Sat Sep 21 01:11:10 CEST 2002
+% doesn't work -- Sat Sep 21 02:52:36 CEST 2002
+% disallow preread==8, allow preread==0 WORKS -- Sat Sep 21 20:22:07 CEST 2002
+% derived from statecat.psm -- a stateful, faster minimalistic zcat (gzip -cd)
+% implementation, implemented in pure PostScript LanguageLevel1 (Run
+% through cpp (C preprocessor) to get the PostScript file
+% statecat.psm by pts@fazekas.hu
+% originally rcm.c
+% original author: Ron McFarland <rcm@one.net>, 1996
+% formally muzcat.c (at Tue Dec 25 11:07:47 CET 2001)
+% based on statecat.ps.3 by pts@fazekas.hu
+% rewritten, restructured and extended at Tue Dec 25 21:00:33 CET 2001
+% translated to PostScript except fvWork at Tue Dec 25 23:11:31 CET 2001
+% translated to PostScript altogether at Thu Dec 27 01:10:58 CET 2001
+% translation works with `cat random.file.gz random.file.gz'' at Thu Dec 27 14:19:36 CET 2001
+% Thu Dec 27 18:37:03 CET 2001:
+% statecat.ps: 1071960 ms user time (249.293 times slower than gunzip)
+% function inlining at Thu Dec 27 21:51:45 CET 2001
+% shorter keywords at Thu Dec 27 23:52:46 CET 2001
+% at Sat Feb 23 17:05:43 CET 2002:
+% statecat.ps originally: 5388 bytes
+% after eliminate-NULLs trick: 5349 bytes
+% after anti-32768... trick 5229 bytes
+% 5041
+%*/
+/*
+% Imp: more efficient optimize CFG_FMT_ZLIB_ONLY
+% Imp: do `F closefile', `T closefile' in %<True>
+% Not: don't inline TE_read for USE_HEXD (15*5 bytes for ACSO0g is not tolerable)
+% OK : verify a85_getc for really eating EOD (~>) chars
+% OK : find and catalogize `|' and other one-char abbrs
+% OK : shorter operator names (i.e `E' for `def', as in test_vm_eps.eps)
+% OK : shorter var names (such as `preread', `past')
+% Not: make global vars numbered, not named...
+% OK : make constU[]-3 a string, not an array
+% OK : make constW, constP, constL strings, not arrays
+% Imp: inline all except fvMktree (too long), fvFree (recursive) and fvWork (too long)
+% OK : verify, examine StateCatDict (45)
+% OK : find unused vars (such as `moo') in StateCatDict
+% OK : is constM or 1<< faster?? (decided 1<<)
+% OK : anti-`/z 42 eq', ensure `eq' compares numbers (INT_EQ)
+% OK : verify if/ifelse for ENDIF
+% OK : verify direction of `for's
+% OK : eliminate `stopped' context because it catches errors
+% OK : clear stack before `exit'
+% OK : verify `/name' against `name'; grep m@/@
+% OK : verify that `}' is followed by correct if|ifelse|def|bind|stopped|loop|for
+%
+% Typical error: syntax: /^#/
+% Typical error: syntax: m@/ +\w@
+% Typical error: mispelling
+% Typical error: missing `pop' at `dup ... eq{exit}if'
+% Typical error: missing `for|if|...' after '}'
+*/
+
+#include "psmlib.psm"
+
+#if USE_A85D
+#else
+ #if USE_HEXD
+ #else
+ #define USE_BINARY 1
+ #endif
+#endif
+
+#if USE_NO_BIND
+ #define BIND_DEF def
+#else
+ #define BIND_DEF bind def
+#endif
+
+/* --- .pin begins */
+
+%<Head>
+%!PS-Adobe-3.0`E
+%%Inflater: pts@fazekas.hu l1zip.psm
+%%Pages: 1
+`X%%DocumentData: `B
+%%LanguageLevel: 1
+`I%%EndComments
+%%Page: 1 1
+%</Head>
+
+%<Open>
+save`s `R
+%</Open>
+
+/* 88 dict dup /TokDict exch def begin */
+%<Abbr acount=26 xcount=62>
+begin
+%</Abbr>
+
+%<A x "load def"/> % best to make it first
+%<A E def/> % best to make it second
+
+%<A + add/>
+%<A , and/>
+%<A - sub/>
+%<A . lt/>
+%<A : for/>
+%<A ; getinterval/>
+%<A = eq/>
+%<A @ loop/>
+%<A A currentfile/>
+%<A H 32768/> /*!=LZW*/
+%<A J 32767/> /*!=LZW*/
+%<A O pop/>
+%<A X exit/>
+%<A a packedarray/>
+%<A b bitshift/>
+%<A c exch/>
+%<A g get/>
+%<A y copy/>
+%<A i ifelse/>
+%<A j if/>
+%<A t put/>
+%<A u dup/>
+%<A ~ ne/>
+#if 0 /* important in LZW, but not in Flate */
+ %<A * gt/>
+ %<A L length/>
+ %<A r read/>
+ %<A s string/>
+#endif
+#if USE_A85D
+%<D d a85_getc/>
+%<D S xS/>
+%<D D xD/>
+%<D C xC/>
+#endif
+#if USE_HEXD
+%<D d .hexd.un/>
+%<A S readhexstring/>
+%<D D .hexd.un/>
+%<D C .hexd./>
+#endif
+#if USE_BINARY
+%<D d .binary.un/>
+#if USE_PALETTE
+%<A S readstring/>
+#endif
+%<D D .binary.un/>
+%<D C .binary.un/>
+#endif
+
+#if USE_SHORT_NAMES
+% Free for short names: *?\^_`| BFGIKLMNPQRTUVWYZ efhklmnopqrsvwz
+% Numerical comments denote # calls or # accesses
+% : B: TokSubs
+%<D F Bary/> /* F must be overridden with array to avoid early TokSubs */
+% : G
+%<D I fxIgnore8/> % ? + 3
+%<D K Sbuf/>
+%<D L fvFree/> % 5
+%<D M fvMktree/> % 5
+%<D N .N./>
+%<D P preread/>
+%<D Q mQ/> % 6
+%<D R fxRead8/> % 6
+%<D T Gary/> /* T must be overridden with array to avoid early TokSubs */
+%<D U fvFree/> % 5
+%<D V fvMktree/> % 5
+%<D Y fxRead16/> % 7 /* formerly: C */
+%<D W oP/> % 4
+%<D Z .Z./>
+%<D e oO/> % 7
+%<D f .f./>
+%<D h .h./>
+%<D k fxSkip/> % 4
+%<D l constZ19/> % 3
+%<D m mode/>
+%<D n mF/> % 6
+%<D o .o./>
+%<D p .p./>
+%<D q .q./>
+%<D r fvRead/> % 10
+%<D s past/>
+%<D v .v./>
+%<D w tY/> % 6
+%<D z Tvar/>
+/* %<D z fxIgnore8z/> % 3 */ /* not a function anymore */
+%<D * fvWork/> % 1
+%<D _ fxRead8EOF/> % 1
+%<D ? Dvar/>
+%<D | fvMain/>
+#endif
+
+%<TokSubs name=B inlining=0/>
+
+#if USE_CURRENTFILE
+ #define STDIN currentfile
+#endif
+
+%<Test>
+#if USE_DEBUG2
+/FP /fileposition x
+#endif
+
+#if USE_BINARY
+ {mark /F currentfile/FlateDecode filter def}stopped
+#endif
+#if USE_A85D
+ {mark /T currentfile/ASCII85Decode filter def /F T/FlateDecode filter def}stopped
+#endif
+#if USE_HEXD
+ {mark /T currentfile/ASCIIHexDecode filter def /F T/FlateDecode filter def}stopped
+#endif
+/Z exch def cleartomark
+/G{`i}def % image, imagemask or `false 3 colorimage`
+`w `h `b[1 0 0 -1 0 `h]
+#if USE_TRUE
+true
+#else
+Z
+#endif
+%</Test>
+
+%<S len=32768>
+32768 string dup /Sbuf exch def
+%</S>
+
+%<True>
+ fvMain
+%</True>
+
+%<False>
+F G
+F closefile
+#if !USE_BINARY
+T closefile
+#endif
+%</False>
+
+#define ZZZ_ASET(aname,idx,b) aname idx b put
+#define ZZZ_AREF(aname,idx) aname idx get
+#define PASS
+#define GLOBAL_VAR0(t,name)
+#define SLOCAL_VAR0(t,name)
+#define GLOBAL_VAR(t,name) /name null def
+#define SLOCAL_VAR(t,name) /name null def
+#define GLOBAL_ARRAY(t,name,size) /name size t def
+#define LOCAL_VAR(a,b)
+
+#if 0 /* LINE_DEBUG */
+#define put (put:__LINE__) === put
+#define get (get:__LINE__) === get
+#endif
+
+%<Defs>
+% Imp: F closefile, T closefile
+/* We must define constants and global arrays first. */
+
+#define NULL 0
+#define NODESIZE 1998 /* NODESIZE%3==0 */
+/** Binary (Huffman) tree of nodes. */
+GLOBAL_ARRAY(array,N,NODESIZE)
+/**
+ * Contains the code word lengths used for Huffman code generation in
+ * fvMktree(). 320==288+32. 320 is large enough to hold both the code lengths
+ * of the literal--length (288) and the distance (32) Huffman trees -- and
+ * large enough to hold the auxilary Huffman tree (used for building the
+ * real tree) of length 19.
+ */
+GLOBAL_ARRAY(array,Z,320)
+GLOBAL_ARRAY(array,Bary,17)
+GLOBAL_ARRAY(array,Gary,17)
+#if CFG_NO_VAR_S
+#else
+GLOBAL_ARRAY(string,Sbuf,32768)
+#endif
+/constZ19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19 packedarray def
+#if USE_HEXD
+ /C(.)def
+#endif
+
+{ /* We start declaring functions inside the brace */
+
+#define constW { 16 17 18 0 8 7 9 6 10 5 11 4 12 3 13 2 14 1 15 } /* 19 packedarray def */
+#define constU { 3 4 5 6 7 8 9 10 11 13 15 17 19 23 27 31 35 43 51 59 67 83 99 115 131 163 195 227 258 } /* 29 packedarray def */
+#define constP { 0 0 0 0 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 0 } /* 29 packedarray def */
+#define constQ { 1 2 3 4 5 7 9 13 17 25 33 49 65 97 129 193 257 385 513 769 1025 1537 2049 3073 4097 6145 8193 12289 16385 24577 } /* 30 packedarray def */
+#define constL { 0 0 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 } /* 30 packedarray def */
+#if 0
+#define constM { 0 1 3 7 15 31 63 127 255 511 1023 2047 4095 8191 } /* 14 packedarray def */
+#endif
+
+#if USE_A85D
+ GLOBAL_VAR0(SINT32,xS) /* Variable `xS' was formerly called: `sx' */
+ GLOBAL_VAR0(SINT32,xD) /* Variable `xD' was formerly called: `dx' */
+ GLOBAL_VAR0(SINT32,xC) /* Variable `xC' was formerly called: `c0' */
+ /** - a85_getc <0..255|511>
+ * Reads a char from `currentfile' as /ASCII85Decode
+ */
+ /a85_getc{ % Simple getchar() of ASCII85Decode filter :-)), formerly /d
+ PSM_A85_GETC
+ }BIND_DEF
+#endif
+
+#if USE_NO_EOF
+ #define my_getchar() TE_read( )
+ #define my_ignorechar() TE_read(pop)
+#else
+ #define my_getchar() TE_read() {511}ifelse
+ #define my_ignorechar() TE_read(pop) if
+#endif
+
+
+/** Index of the first free node in <code>N</code>. */
+GLOBAL_VAR0(WORD,Dvar)
+
+GLOBAL_VAR0(WORD,Tvar) /* index (in S) of the first free position, [0..32767] */
+
+/* GLOBAL_VAR(NODEN,no) -- unused */
+/* GLOBAL_VAR(WORD,roo) -- unused */
+/* GLOBAL_VAR(WORD,rf) -- unused */
+/* GLOBAL_VAR(WORD,moo) -- unused */
+/* GLOBAL_VAR(WORD,mo) -- unused */
+/* GLOBAL_VAR(WORD,oooo) -- unused */
+/* GLOBAL_VAR(WORD,x) -- unused */
+GLOBAL_VAR0(WORD,mQ)
+GLOBAL_VAR0(WORD,mF)
+GLOBAL_VAR0(WORD,o)
+GLOBAL_VAR0(WORD,q)
+GLOBAL_VAR0(WORD,mode) /* MODE_* */
+GLOBAL_VAR0(WORD,tY) /* FMT_*; formerly ty */
+GLOBAL_VAR0(WORD,oO)
+GLOBAL_VAR0(WORD,oP)
+GLOBAL_VAR0(WORD,f)
+GLOBAL_VAR0(WORD,p)
+GLOBAL_VAR0(WORD,v)
+GLOBAL_VAR0(WORD,h)
+
+
+#define AREF_S(idx) AREF(Sbuf,idx)
+#define ASET_S(idx,val) ASET(Sbuf,idx,val)
+
+/* Reading Operations:
+
+-- fxRead8(): read a 8-bit byte at byte boundary
+-- fxRead16z(): read a 16-bit word at byte boundary, MSB first (ZIP)
+-- fxRead16(): read a 16-bit word at byte boundary, LSB first (normal)
+-- fxSkip(): skip to next byte boundary
+-- fxRead1(): read 1 bit (for Huffman)
+-- fvRead(): read any amount of bits (0..13), LSB first
+*/
+
+/* Dat: FlateDecode bit packing order is: (b7*128+...+b0)+(b15*128+...+b8)
+
+/** char, 0..255 */
+SLOCAL_VAR0(WORD,preread)
+/** -1..-8: bits of bufread[pos] already read */
+SLOCAL_VAR0(WORD,past)
+
+% static void fxInit(void) {
+% /fxInit {
+#define fxInit \
+ /preread 0 def \
+ /past -8 def
+% }BIND_DEF
+
+/* #define ASSERT_PREREAD_NOT_EOF() preread 255 gt ASSERT_FALSE_POP((unexpected eof)) */
+#define ASSERT_NOT_EOF(val) ASSERT_TRUE(val dup 255 and eq,(non-EOF expected))
+#define ASSERT_PREREAD_NOT_EOF() ASSERT_NOT_EOF(preread)
+
+/** reads 0..13 bits */
+% static WORD fvRead(WORD arg) {
+/fvRead {
+ DEBUG(dup (==> fvRead\() exch 42 string cvs concatstrings (\)\n) concatstrings)
+ DEBUG(( past=) past neg 42 string cvs concatstrings
+ ( preread=) preread 42 string cvs concatstrings
+ (\n) concatstrings concatstrings)
+ dup 0 INT_NE{
+ ASSERT_PREREAD_NOT_EOF()
+ past
+ % Stack: arg -opast
+ dup preread exch bitshift exch % SHR
+ % Stack: arg preread>>opast opast
+ dup 3 index sub
+ % Stack: arg ret==:preread>>-opast -opast -past==:-opast-arg
+ dup -8 ge{
+ /past exch def % BUG fixed at Thu Dec 27 14:53:53 CET 2001
+ pop
+ % Stack: arg ret
+ }{
+ ASSERT_TRUE(dup -9 le,(-past>=9))
+ /preread my_getchar() def
+ ASSERT_PREREAD_NOT_EOF()
+ dup -16 ge{ /* _GT_ */
+ 8 add /past exch def
+ 8 add
+ % Stack: arg ret==:preread>>opast 8-opast
+ preread exch bitshift % SHL
+ add
+ % Stack: arg ret''
+ }{
+ 16 add /past exch def
+ 8 add 2 copy
+ % Stack: arg retold 8-opast ret 8-opast
+ preread exch bitshift add % SHL
+ % Stack: arg retold 8-opast ret''
+ /preread my_getchar() def % BUG fixed at Thu Dec 27 15:40:53 CET 2001
+ ASSERT_TRUE(past -1 le,(-past>=1))
+ ASSERT_TRUE(past -4 ge,(-past<=4))
+ ASSERT_PREREAD_NOT_EOF()
+ exch 8 add preread exch bitshift add
+ % Stack: arg retold ret''
+ exch pop
+ % Stack: arg ret''
+ }ifelse
+ }ifelse
+ % Stack: arg ret
+ % exch constM exch get and % ret&=((1<<arg)-1);
+ % ^^^ BUG (re)-fixed at Thu Dec 27 14:50:49 CET 2001
+ exch 1 exch bitshift 1 sub and
+ }if
+ DEBUG(dup (<-- fvRead=) exch 42 string cvs concatstrings (\n) concatstrings)
+ % (%stderr) (w) file (<fvRead\n) writestring
+ % fvRead(0)==0 implicitly assumed
+}BIND_DEF
+
+% static WORD fxRead1(void) {
+% /fxRead1{
+#define fxRead1 \
+ ASSERT_PREREAD_NOT_EOF() \
+ past dup -8 INT_EQ{ \
+ pop \
+ /preread my_getchar() def \
+ /past -1 def \
+ preread 1 and \
+ /* Stack: ret */ \
+ }{ \
+ dup 1 sub /past exch def \
+ preread exch bitshift 1 and \
+ /* Stack: ret */ \
+ }ifelse
+% }BIND_DEF
+
+#if 0 /* old style past==0, inline only speed-critical functions */
+ % static void fxSkip(void) {
+ % /fxSkip{
+ #define fxSkip \
+ past 0 INT_NE{ \
+ ASSERT_PREREAD_NOT_EOF() \
+ /preread my_getchar() def \
+ /past 0 def \
+ }if
+ % }BIND_DEF
+
+ % static WORD fxRead16(void) {
+ % /fxRead16{
+ #define fxRead16 \
+ ASSERT_TRUE(past 0 INT_EQ,(past==0)) \
+ ASSERT_PREREAD_NOT_EOF() \
+ preread \
+ /* Stack: ret */ \
+ my_getchar() dup /preread exch def \
+ ASSERT_PREREAD_NOT_EOF() \
+ 8 bitshift \
+ add \
+ /preread my_getchar() def
+ % }BIND_DEF
+
+ % static WORD fxRead8(void) {
+ % /fxRead8{
+ #define fxRead8 \
+ ASSERT_TRUE(past 0 INT_EQ,(past==0)) \
+ ASSERT_PREREAD_NOT_EOF() \
+ preread \
+ /* Stack: ret */ \
+ /preread my_getchar() def
+ % }BIND_DEF
+
+ % static void fxIgnore8(WORD how_many_bytes) {
+ #define fxIgnore8 \
+ ASSERT_TRUE(dup 0 gt,(fxIgnore8arg>0)) \
+ ASSERT_TRUE(past 0 INT_EQ,(past==0)) \
+ ASSERT_PREREAD_NOT_EOF() \
+ -1 2 {pop my_ignorechar()}for \
+ /preread my_getchar() def
+
+ #define fxIgnore8z \
+ ASSERT_TRUE(past 0 INT_EQ,(past==0)) \
+ ASSERT_PREREAD_NOT_EOF() \
+ dup 0 INT_NE{ \
+ -1 2 {pop DEBUG2((fI8z)===) my_ignorechar()}for \
+ /preread my_getchar() def \
+ }{pop}ifelse
+
+ % static WORD fxRead8EOF(void) {
+ % /fxRead8EOF{
+ #define fxRead8EOF \
+ ASSERT_TRUE(past 0 INT_EQ,(past==0)) \
+ preread \
+ /* Stack: ret */ \
+ /preread my_getchar() def
+ % }BIND_DEF
+#else
+ #if 0
+ /* old-style: past==0 */
+ % static void fxSkip(void) {
+ /fxSkip{
+ past 0 INT_NE{
+ ASSERT_PREREAD_NOT_EOF()
+ /preread my_getchar() def
+ /past 0 def
+ }if
+ }BIND_DEF
+ % static WORD fxRead8(void) {
+ /fxRead8{
+ ASSERT_TRUE(past 0 INT_EQ,(past==0))
+ ASSERT_PREREAD_NOT_EOF()
+ preread
+ /* Stack: ret */
+ /preread my_getchar() def
+ }BIND_DEF
+ /fxIgnore8z{
+ % Same as void fxIgnore8(WORD how_many_bytes), but allow 0 as arg
+ ASSERT_TRUE(past 0 INT_EQ,(past==0))
+ ASSERT_PREREAD_NOT_EOF()
+ dup 0 INT_NE{
+ -1 2 {pop DEBUG2((fI8z)===) my_ignorechar()}for
+ /preread my_getchar() def
+ }{pop}ifelse
+ }BIND_DEF
+ /fxRead8EOF{
+ ASSERT_TRUE(past 0 INT_EQ,(past==0))
+ preread
+ /* Stack: ret */
+ /preread my_getchar() def
+ }BIND_DEF
+ #else
+ #define fxSkip /past -8 def
+ #define fxRead8 \
+ ASSERT_TRUE(past -8 INT_EQ,(past==-8)) \
+ my_getchar() ASSERT_NOT_EOF(dup)
+ % }BIND_DEF
+ #define fxRead8EOF \
+ ASSERT_TRUE(past -8 INT_EQ,(past==-8)) \
+ my_getchar()
+ % }BIND_DEF
+ #endif
+
+ % static WORD fxRead16(void) {
+ /fxRead16{
+ ASSERT_TRUE(past -8 INT_EQ,(past==-8))
+ my_getchar() ASSERT_NOT_EOF(dup)
+ my_getchar() ASSERT_NOT_EOF(dup)
+ 8 bitshift add
+ }BIND_DEF
+
+ % static void fxIgnore8(WORD how_many_bytes) {
+ /fxIgnore8{
+ ASSERT_TRUE(dup 0 gt,(fxIgnore8arg>0))
+ ASSERT_TRUE(past -8 INT_EQ,(past==-8))
+ ASSERT_PREREAD_NOT_EOF()
+ {my_getchar() ASSERT_NOT_EOF(dup) pop }repeat
+ }BIND_DEF
+ #define fxIgnore8z fxIgnore8
+#endif
+
+#define fvReadq fvRead
+/** Reads an uint16 from the ZIP file */
+#define fxRead16z fxRead16
+
+/**
+ * Allocates a new node and initializes it with empty content. This function
+ * lets us get rid of the global variable F (which was buggily uninitialized
+ * in the original scm.c).
+ * @return pointer to the newly allocated node
+ * @whichcode -1
+ */
+% DEFUN_0(NODEN,fvNalloc)
+% /fvNalloc{
+#define fvNalloc \
+ /* GLOBAL_REF(N) */ \
+ /* GLOBAL_REF(Dvar) */ \
+ /* LOCAL_VAR(NODEN,no) */ /* the first/next free node */ \
+ /* FUNCODE */ \
+ Dvar \
+ /* Stack: no */ \
+ ASSERT_TRUE(dup NODESIZE lt,(Dvar<NODESIZE)) \
+ dup N exch get /Dvar exch def /* SET(Dvar,AREF(N,no)); % not free anymore */ \
+ dup N exch NULL put /* ASET(N,no,NULL); */ /* clear; the other two fields are already cleared */ \
+ /* Stack: no */
+% }BIND_DEF
+
+/**
+ * Frees the Huffman tree originating from <code>root</code> recursively.
+ * Used <code>I</code> as input only.
+ * Moved <code>I</code> into a argeter.
+ * @param arg root node index in N
+ */
+% DEFUN_1_VOID(fvFree,NODEN)
+/fvFree{
+ % GLOBAL_REF(N)
+ % GLOBAL_REF(Dvar)
+ N exch dup NULL INT_NE{
+ 2 copy get fvFree
+ 2 copy 1 add get fvFree % fvFree(AREF(N,arg+1));
+ 2 copy 1 add NULL put % ASET(N,arg+1,NULL); /* clear */
+ 2 copy 2 add 0 put % ASET(N,arg+2,0); /* clear */
+ 2 copy Dvar put % ASET(N,arg,Dvar); /* link to the beginning of the free list */
+ /Dvar exch def pop % SET(Dvar,arg); /* set it free */
+ }{
+ % BUG fixed at Thu Dec 27 11:52:59 CET 2001
+ pop pop
+ }ifelse
+}BIND_DEF
+
+/**
+ * Goes down (descends) enough levels in the binary tree of (struct node)s.
+ * Reads numbers from input encoded as a Huffman tree represented by the
+ * (struct node)s.
+ * Called only from 2 places.
+ * Used <code>I</code> as both input and output, but the output is never used
+ * in the program. So I've put <code>I</code> to a argument.
+ * @param arg root is only for input
+ * @whichcode 3
+ */
+% DEFUN_1(WORD,fvDescend,NODEN)
+% /fvDescend{
+#define fvDescend \
+ /* GLOBAL_REF(N) */ \
+ /* FUNCODE */ \
+ DEBUG(dup (==> fvDescend\() exch 42 string cvs concatstrings (\)\n) concatstrings) \
+ N exch \
+ { /* Stack: N arg */ \
+ 2 copy get NULL INT_EQ{exit}if /* WHILE(NE(NULL,AREF(N,arg))) */ \
+ 2 copy fxRead1 add get exch pop /* SET(arg,AREF(N,arg+fxRead1())); */ \
+ }loop /* ENDWHILE */ \
+ /* Stack: N arg */ \
+ 2 add get \
+ DEBUG(dup (<-- fvDescend=) exch 42 string cvs concatstrings (\n) concatstrings) \
+ /* RETURN(fvDescend,AREF(N,arg+2)) */ /* arg->value; */
+% }BIND_DEF
+
+/**
+ * Allocates new (struct node)s. This is the Huffman tree
+ * builder. It reads the global array <code>Z</code>: the code lengths have
+ * been already stored there.
+ * Used <code>I</code> as output only, so I moved it to the return value.
+ * @param arg the number of entries (codes) of the Huffman tree to be built
+ * @return the root of the Huffman tree just built
+ * @whichcode 5
+ */
+% DEFUN_1(NODEN,fvMktree,WORD)
+/fvMktree{ % BUG fixed at Thu Dec 27 11:54:02 CET 2001
+ % GLOBAL_REF(B)
+ % GLOBAL_REF(G)
+ % GLOBAL_REF(N)
+ % GLOBAL_REF(Z)
+ % LOCAL_VAR(WORD,moo)
+ % LOCAL_VAR(WORD,mQ)
+ % LOCAL_VAR(WORD,mo)
+ % LOCAL_VAR(WORD,mF)
+ % FUNCODE
+ constZ19 0 17 getinterval Bary copy pop % OK to copy packedarray -> array
+ % Stack: arg
+ Bary Z 0 1 4 index 1 sub
+ % Stack: arg Bary Z 0 1 arg-1
+ { % Stack: arg Bary Z moo
+ 3 copy get
+ % Stack: arg Bary Z moo Bary Z[moo]
+ 2 copy get 1 add put
+ % Stack: arg Bary Z moo
+ pop
+ }for % WHILE(LT(moo,arg)) INCR(AREF(Bary,AREF(Z,moo))); INCR(moo); ENDWHILE
+ % Stack: arg Bary Z
+ pop 0 0 put % ASET(Bary,0,0);
+ Gary 0 0 put % ASET(Gary,0,0);
+ % Stack: arg
+ Gary Bary 0 1 15 % SET(moo,0); WHILE(LT(moo,16))
+ { % Stack: arg Gary Bary moo
+ 2 copy get
+ % Stack: arg Gary Bary moo Bary[moo]
+ 3 index 2 index get
+ % Stack: arg Gary Bary moo Bary[moo] Gary[moo]
+ add dup add % BUG fixed at Thu Dec 27 15:05:51 CET 2001
+ % Stack: arg Gary Bary moo 2*(Bary[moo]+Gary[moo])
+ 3 index exch 2 index 1 add exch
+ % Stack: arg Gary Bary moo Gary moo+1 2*(Bary[moo]+Gary[moo])
+ % ASET(Gary, moo+1,TWICE(AREF(Gary,moo)+AREF(Bary,moo)));
+ put pop
+ }for % BUG fixed at Thu Dec 27 14:59:52 CET 2001
+ % Stack: arg Gary Bary
+ pop pop
+ /* Dat: anode is the ->left pointer of the Sentinel node */
+ N 3 0 put % ASET(N,3,NULL); /* anode=NULL; */
+ % Stack: arg
+ 1 sub 0 exch 1 exch{ % SET(moo,0); WHILE(LT(moo,arg))
+ % Stack: moo
+ dup Z exch get dup 0 INT_NE{ % IF(NZ(AREF(Z,moo)))
+ % Stack: moo Z[moo]
+ % /* WORD o, f; */ /* struct node **f; */
+ dup Gary exch get /mQ exch def % SET(mQ,AREF(Gary,AREF(Z,moo)));
+ % Stack: moo Z[moo]
+ dup Gary exch 2 copy
+ % Stack: moo Z[moo] Gary Z[moo] Gary Z[moo]
+ get 1 add put % INCR(AREF(Gary,AREF(Z,moo)));
+ % Stack: moo Z[moo]
+ /mF 3 def % SET(mF,3); /* mF=&anode; */ % BUG fixed at Thu Dec 27 12:03:31 CET 2001
+ % SET(mo,AREF(Z,moo));
+ 1 sub -1 0
+ % Stack: moo Z[moo]-1 -1 0
+ { % WHILE(NZ(mo)); DECR(mo);
+ % Stack: moo mo
+ N mF get NULL INT_EQ{
+ N mF fvNalloc put
+ }if % IF(EQ(AREF(N,mF),NULL)); ASET(N,mF,fvNalloc NOARGS); ENDIF
+ 1 exch bitshift mQ and 0 INT_EQ{0}{1}ifelse
+ N mF get add
+ /mF exch def % SET(mF,AREF(N,mF)+TAND_P(mQ,SHL(1,mo)));
+ % Stack: moo
+ }for
+ N exch
+ % Stack: N moo
+ N mF 2 copy fvNalloc put % ASET(N,mF,fvNalloc NOARGS);
+ get 2 add
+ % Stack: N moo AREF(N,mF)+2
+ exch put % ASET(N,AREF(N,mF)+2,moo); /* (*f)->value=moo; */
+ % Stack: -
+ }{pop pop}ifelse % ENDIF
+ }for
+ % Stack: -
+ N 3 get
+}BIND_DEF
+
+
+#define FMT_ZLIB 120
+#define FMT_STOP 4 /* stop processing and flush STDIN */
+#if CFG_FMT_ZLIB_ONLYX
+#else
+#define FMT_ZIP_STORED 0 /* file is stored, not Deflated in ZIP file */
+#define FMT_GZIP 31
+#define FMT_NONE 3
+#define FMT_ZIP_DEFLATED 8
+#endif
+
+#define MODE_BOS 0 /* at beginning of (sub)file */
+#define MODE_MOB 1 /* at middle of a DEFLATE block */
+#define MODE_REP 2 /* printing a repeating string in a DEFLATE block */
+#define MODE_BOB 3 /* at the beginning of a block, just before BFINAL and BTYPE */
+#define MODE_COPY1 4 /* copying from input to output (a stored block) */
+#if CFG_FMT_ZLIB_ONLYX
+#else
+#define MODE_ZSTO 5 /* copying from input to output (FMT_ZIP_STORED) */
+#endif
+
+/**
+ * Root of the literal--length Huffman tree in <code>N</code>
+ * (see RFC 1951). Its length is at most 288 with values 0..287. Values
+ * 286 and 287 are invalid. A value in 0..255 means a literal byte, a
+ * value of 256 indicates end-of-block, and a
+ * value in 257..285 is a prefix (with 29 possible values) of a length
+ * in 3..258. See subsubsection 3.2.5 of RFC 1951.
+ */
+SLOCAL_VAR0(NODEN,v)
+/**
+ * Root of the distance Huffman tree in <code>N</code> (see RFC 1951).
+ * Its length is at most 32 with values 0..31. Values 30 and 31 are invalid.
+ * A value of 0..29 is a prefix (with 30 possible values) of a distance in
+ * 1..32768. See subsubsection 3.2.5 of RFC 1951.
+ */
+SLOCAL_VAR0(NODEN,h)
+
+
+#define SLIDEE dup 32767 INT_EQ{pop 0}{1 add}ifelse
+
+#if CFG_FMT_ZLIB_ONLY
+#define fvAFB \
+ DEBUG2((f0:__LINE__) ===only) DEBUG2(currentfile FP ===) \
+ /mode MODE_BOS def \
+ /tY FMT_STOP def /* force EOF */ \
+ fxSkip \
+ DEBUG2((f1:__LINE__) ===only) DEBUG2(currentfile FP ===) \
+ 4 fxIgnore8z \
+ DEBUG2((f2:__LINE__) ===only) DEBUG2(currentfile FP ===)
+#else
+% static void fvAFB(void) {
+% /fvAFB{ /* after final block (BFINAL) */
+#define fvAFB \
+ \
+ /mode MODE_BOS def /* SET(mode,MODE_BOS); */ \
+ fxSkip /* fxSkip(); */ \
+ /* ^^^ skip till we reach byte boundary. fvRead! 0..7 bits */ \
+ tY FMT_GZIP INT_EQ{ /* IF(EQ(tY,FMT_GZIP)) */ \
+ /* CRC32 and ISIZE remaining */ \
+ /* vvv IGNORE fxRead16(); IGNORE fxRead16(); IGNORE fxRead16(); IGNORE fxRead16(); */ \
+ 8 \
+ }{ \
+ tY FMT_ZLIB INT_EQ{ /* ELSE_IF(EQ(tY,FMT_ZLIB)) */ \
+ /* ADLER32 remaining */ \
+ 4 \
+ }{0}ifelse \
+ }ifelse \
+ fxIgnore8z
+% }BIND_DEF
+#endif /* CFG_FMT_ZLIB_ONLY */
+
+/** Reads data from input, uncompresses and saves it to Sbuf. Sbuf.length==32768.
+ * Saves 32768 bytes into Sbuf unless EOF prevents it. After return, the caller
+ * may read Sbuf, but it may not modify it.
+ * @return length to be saved to Sbuf
+ */
+% static WORD fvWork(void) {
+/fvWork{
+ % GLOBAL_REF(J)
+ % GLOBAL_REF(Y)
+ % GLOBAL_REF(Tvar)
+ % GLOBAL_REF(N)
+ % GLOBAL_REF(Dvar)
+ { % `{'': establish fake loop context for return
+ mode MODE_REP INT_EQ{ % IF(EQ(mode,MODE_REP))
+ ASSERT_TRUE(Tvar 0 INT_EQ,(Tvar==0))
+ ASSERT_TRUE(f 258 le,(f<=258))
+ % /* f==0 is OK now */
+ Tvar oO
+ 1 1 f{ % WHILE(NZ(f)) -- inverse for
+ pop
+ % Stack: Tvar oO
+ Sbuf 3 copy exch get
+ % Stack: Tvar oO Sbuf Tvar S[oO]
+ put % ASET_S(Tvar,AREF_S(oO));
+ SLIDEE % SLIDE(oO);
+ exch 1 add exch % INCR(Tvar);
+ % DECR(f);
+ }for % ENDWHILE
+ pop /Tvar exch def
+ /mode MODE_MOB def
+ }{
+ mode MODE_COPY1 INT_EQ{ % ELSE_IF(EQ(mode,MODE_COPY1))
+ % /* Now: f: copy count unsinged word16 */
+ ASSERT_TRUE(Tvar 0 INT_EQ,(Tvar==0))
+ % /* f==0 is OK now */
+ f 32767 gt{ /* _GT_ */ % IF((unsigned short)f>=32768)
+ ASSERT_TRUE(f 32768 sub f 32767 and eq,((f&32767)==f-32768))
+ /f f 32767 and def
+ 0 1 32767{ % WHILE(NE((unsigned short)Tvar,32768))
+ Sbuf exch fxRead8 put % ASET_S(Tvar,fxRead8());
+ % INCR(T);
+ % DECR(f);
+ }for % ENDWHILE
+ /Tvar 0 def % SET(Tvar,0);
+ % Stack: -
+ ASSERT_TRUE(mode MODE_COPY INT_EQ,(mode==MODE_COPY1))
+ % bbb111
+ 32768 exit % return (WORD)32768; outside loops
+ }{ % ELSE
+ Sbuf Tvar 1 1 f{ % WHILE(NZ(f)) -- inverse for
+ pop
+ % Stack: Sbuf Tvar
+ 2 copy fxRead8 put % ASET_S(Tvar,fxRead8());
+ 1 add % INCR(Tvar);
+ }for % ENDWHILE
+ /Tvar exch def pop
+ % /mode MODE_BOB def % SET(mode,MODE_BOB); % BUG fixed at Thu Dec 27 14:16:57 CET 2001
+ o 0 INT_NE{ % IF(NZ(o))
+ fvAFB % goto on_bos; SET(mode,MODE_BOS);
+ }{ % ELSE
+ /mode MODE_BOB def % SET(mode,MODE_BOB); % beginning of next block
+ }ifelse % ENDIF
+ }ifelse % ENDIF
+ }
+#if CFG_FMT_ZLIB_ONLY
+ if
+#else
+ {mode MODE_ZSTO INT_EQ{ % ELSE_IF(EQ(mode,MODE_ZSTO))
+ % /* Now: f: copy count low unsinged word16, oP: high unsigned word16 */
+ % /* Now: oo: 0..1 flag for decrementing oP */
+ ASSERT_TRUE(Tvar 0 INT_EQ,(Tvar==0))
+ % /* f==0 is OK now */
+ f 32767 gt{ /* _GT_ */ % IF((unsigned short)f>=32768)
+ ASSERT_TRUE(f 32768 sub f 32767 and eq,((f&32767)==f-32768))
+ /f f 32767 and def
+ 0 1 32767{ % WHILE(NE((unsigned short)Tvar,32768))
+ Sbuf exch fxRead8 put % ASET_S(Tvar,fxRead8());
+ % INCR(Tvar);
+ % DECR(f);
+ }for % ENDWHILE
+ /Tvar 0 def % SET(Tvar,0);
+ % Stack: -
+ ASSERT_TRUE(mode MODE_ZSTO INT_EQ,(mode==MODE_ZSTO))
+ % bbb222
+ 32768 exit % return (WORD)32768; outside loops
+ }{
+ oP 0 INT_NE{ % ELSE_IF(NZ(oP))
+ 0 1 32767{ % WHILE(NE((unsigned short)Tvar,32768))
+ Sbuf exch fxRead8 put % ASET_S(Tvar,fxRead8());
+ % INCR(Tvar);
+ % DECR(f);
+ }for % ENDWHILE
+ /Tvar 0 def % SET(Tvar,0);
+ % Stack: -
+ oO 0 INT_NE{ % IF(NZ(oO))
+ /oP oP 1 sub def % DECR(oP);
+ /oO 0 def % SET(oO,0);
+ }{ % ELSE
+ /oO 1 def % SET(oO,1);
+ }ifelse
+ ASSERT_TRUE(mode MODE_ZSTO INT_EQ,(mode==MODE_ZSTO))
+ % bbb333
+ 32768 exit % return (WORD)32768; outside loops
+ }{ % ELSE
+ Sbuf Tvar 1 1 f{ % WHILE(NZ(f)) -- inverse for
+ pop
+ % Stack: Sbuf Tvar
+ 2 copy fxRead8 put % ASET_S(Tvar,fxRead8());
+ 1 add % INCR(Tvar);
+ }for % ENDWHILE
+ /Tvar exch def pop
+ /mode MODE_BOS def % SET(mode,MODE_BOS);
+ }ifelse % oO!=0
+ }ifelse % f>=32768
+ }if % MODE==MODE_ZSTO
+ }ifelse % MODE==MODE_COPY1
+#endif /* CFG_FMT_ZLIB_ONLY */
+ }ifelse % MODE==MODE_REP
+ -1 exit % don''t return yet
+ }loop
+ % Stack: retval||-1
+
+ { % big-big MODE_MOB||MODE_BOB||MODE_BOS loop
+ #ifndef NDEBUG
+ % mode ===only ( big-big\n) print
+ #endif
+ ASSERT_TRUE(mode MODE_MOB INT_EQ mode MODE_BOB INT_EQ mode MODE_BOS INT_EQ or or,(MODE_MOB||MODE_BOB||MODE_BOS))
+
+ % Stack: retval||-1
+ dup -1 INT_NE{%ccc999
+ exit}if
+ mode MODE_MOB INT_EQ{ % IF(EQ(mode,MODE_MOB)); mode_mob:
+ ASSERT_TRUE(dup -1 INT_EQ,(was -1))
+ pop % -1
+ /**
+ * Uncompresses the data block with the Huffman codes set up.
+ *
+ * Reads at most 33 bits per entry. Unfortunately the block can be of
+ * arbitrary length (terminated by an entry of 256).
+ */
+ % /* vvv reads 0..15 bits, see subsubsection 3.2.7 of RFC 1951 */
+ {
+ % Dat: most of the time is spent inside fvDescend, fvRead and
+ % inside this loop
+ v fvDescend dup 256 INT_EQ{pop -1 exit}if % WHILE(NE(oo, 256))
+ dup 257 lt{ % IF(LT(oO,257))
+ % /* ^^^ BUG corrected */
+ Sbuf exch Tvar exch put % ASET_S(Tvar,oO);
+
+ % Stack: -
+ % vvv SLIDE(Tvar); /* Tvar++; Tvar&=32767; */
+ % vvv if (Tvar==0) return (WORD)32768; /* remain in MODE_MOB */
+ Tvar 32767 INT_EQ{
+ /Tvar 0 def
+ % bbb444
+ 32768 exit % return % in big-big-loop and MOB-loop
+ }if
+ /Tvar Tvar 1 add def
+ }{ % ELSE
+ 257 sub % SUB(oO,257);
+ % Stack: oO
+ dup constU exch get
+ exch constP exch get fvRead
+ add /f exch def % SET(f,AREF(constU,oO) + fvRead(AREF(constP,oO))); /* fvRead! 0..5 bits */
+ ASSERT_TRUE(3 f le f 258 le and,(3<=f && f<=258))
+ h fvDescend % SET(oO,fvDescend(h));
+ dup constQ exch get
+ exch constL exch get fvRead
+ add % SET(oO,AREF(constQ,oO) + fvRead(AREF(constL,oO))); /* fvRead! 0..13 bits */
+ Tvar exch sub 32767 and % /* oO = oO <= Tvar ? Tvar - oO : 32768 - oO + Tvar; */
+
+ f 32768 Tvar sub sub dup 0 lt{ % IF((unsigned short)f<32768-(unsigned short)Tvar)
+ pop
+ % Stack: oO
+ Tvar exch 1 1 f{ % WHILE(NZ(f)) -- inverse for
+ pop
+ % Stack: Tvar oO
+ Sbuf 3 copy exch get
+ % Stack: Tvar oO Sbuf Tvar S[oO]
+ put % ASET_S(Tvar,AREF_S(oO));
+ SLIDEE % SLIDE(oO);
+ exch 1 add exch % INCR(Tvar);
+ % DECR(f);
+ }for % ENDWHILE
+ % Dat: oO doesn''t have to be remembered here
+ pop /Tvar exch def
+ % Stack: -
+ ASSERT_TRUE(Tvar 32768 lt,(Tvar<32768))
+ }{ % ELSE
+ /f exch def % SUB(f,32768-Tvar);
+ % Stack: oO
+ Tvar 1 32767{ % WHILE(NE((unsigned short)Tvar,32768))
+ % Stack: oO Tvar
+ exch
+ % Stack: Tvar oO
+ Sbuf 3 copy exch get
+ % Stack: Tvar oO Sbuf Tvar S[oO]
+ put % ASET_S(Tvar,AREF_S(oO));
+ SLIDEE % SLIDE(oO);
+ exch pop % INCR(Tvar);
+ }for % ENDWHILE
+ /oO exch def
+ % Stack: -
+ /Tvar 0 def % SET(Tvar,0);
+ /mode MODE_REP def % SET(mode,MODE_REP);
+ % bbb555
+ 32768 exit % return (WORD)32768; % in big-big-loop and MOB-loop
+ }ifelse % ENDIF
+ }ifelse % ENDIF
+ }loop % ENDWHILE
+ % Stack: retval||-1
+ dup -1 INT_EQ{ % BUG fixed at Thu Dec 27 15:52:18 CET 2001
+ v fvFree % fvFree(v);
+ h fvFree % fvFree(h);
+ o 0 INT_NE{ % IF(NZ(o))
+ fvAFB % goto on_bos; SET(mode,MODE_BOS);
+ }{ % ELSE
+ /mode MODE_BOB def % SET(mode,MODE_BOB); % beginning of next block
+ }ifelse % ENDIF
+ }if
+ }if % ENDIF
+ % Stack: retval||-1
+ dup -1 INT_NE{%ccc888
+ exit}if pop
+
+ DEBUG2((;)===)
+
+ mode MODE_BOB INT_EQ{ % WHILE(EQ(mode,MODE_BOB)); mode_bob:
+ DEBUG(counttomark 42 string cvs)
+ DEBUG(( kope\n))
+ % assert(mode==MODE_BOB);
+ /o fxRead1 def % SET(o,fxRead1()); /* BFINAL: 1 iff this is the last data block */
+ /q 2 fvRead def % SET(q,fvRead(2)); /* BTYPE: block type; 0=stored, 1=fixed Huff, 2=dyn Huff */
+ % #if NDEBUG
+ % #else
+ % fprintf(stderr, "MODE_BOB o=%d q=%d %ld\n", o, q, ftell(stdin));
+ % #endif
+ DEBUG((MODE:BOB o=) o 42 string cvs
+ ( q=) q 42 string cvs
+ ( ) Stdin fileposition 42 string cvs
+ (\n) concatstrings concatstrings concatstrings
+ concatstrings concatstrings concatstrings)
+ ASSERT_TRUE(q 0 INT_EQ q 1 INT_EQ q 2 INT_EQ or or,(q==0 || q==1 || q==2))
+ q 0 INT_NE{ % IF(NZ(q))
+ /**
+ * Now: q==BTYPE, q==1 or q==2. (BTYPE==3 means error). Handles
+ * compressed data blocks, see subsubsection 3.2.5 of RFC 1951.
+ */
+ q 1 INT_EQ{ % IF(EQ(q,1))
+ /**
+ * Initializes the fixed Huffman codes for BTYPE==1.
+ */
+ % /* WORD oO; */
+ 287 -1 0{ % SET(oO,288); WHILE(NZ(oO)); DECR(oO);
+ Z exch dup 144 lt{8}{dup 256 lt{9}
+ {dup 280 lt{7}{8}ifelse}ifelse}ifelse put
+ /* ^^^ AREF(Z,oO) = oO < 144 ? 8
+ : oO < 256 ? 9
+ : oO < 280 ? 7
+ : 8; */
+ }for % ENDWHILE
+ /v 288 fvMktree def % SET(v,fvMktree(288));
+ 0 1 31{Z exch 5 put}for % SET(f,0); WHILE(LT(f,32)) ASET(Z,f,5); INCR(f); ENDWHILE
+ /h 32 fvMktree def % SET(h,fvMktree(32));
+ }{ % ELSE
+ /**
+ * Reads dynamic Huffman codes for BTYPE==2.
+ *
+ * Maximum read: 5+5+4+3*19+7*289 == 2094 bits
+ */
+ ASSERT_TRUE(q 2 INT_EQ,(q==2))
+ % /* WORD oO, oP, oPo, f, p, x, v; */
+ /p 5 fvRead 257 add def % SET(p, fvRead(5) + 257); /* HLIT: 257..286 (287--289 are unused) */
+ /oO 5 fvRead 1 add def % SET(oO, fvRead(5) + 1); /* HDIST: 1..32 */
+ /v 4 fvRead 4 add def % SET(v, fvRead(4) + 4); /* HCLEN: 4..19 */ /* small v */
+ constZ19 Z copy pop % WHILE(LT(oO,19)) ASET(Z,AREF(constW,oO), 0); INCR(oO); ENDWHILE
+ 0 1 v 1 sub{
+ Z exch constW exch get 3 fvRead put % WHILE(LT(oO,v)) ASET(Z,AREF(constW,oO), fvRead(3)); INCR(oO); ENDWHILE /* small v */
+ }for
+ % Stack: - (verified)
+ /v 19 fvMktree def % SET(v,fvMktree(19));
+ /oP 0 def % SET(oP,0);
+ % Stack: -
+ Z 0 { % SET(oO,0); WHILE(LT(oO,p + oO))
+ % Stack: Z oO
+ dup p oO add ge{exit}if
+ v fvDescend % SET(oPo,fvDescend(v));
+ % Stack: Z oO oPo
+ dup 16 INT_EQ{
+ pop oP /f 2 fvRead 3 add def % SET(oPo,oP); SET(f,3+fvRead(2));
+ }{
+ dup 17 INT_EQ{
+ pop 0 /f 3 fvRead 3 add def % SET(oPo,0); SET(f,3+fvRead(3));
+ }{
+ dup 18 INT_EQ{
+ pop 0 /f 7 fvRead 11 add def % SET(oPo,0); SET(f,11+fvRead(7));
+ }{
+ dup /oP exch def /f 1 def % SET(oP,oPo); SET(f,1);
+ }ifelse
+ }ifelse
+ }ifelse
+ % Stack: Z oO oPo
+ 1 1 f{ % SET(q,f); WHILE(NZ(q))
+ pop % BUG fixed at Thu Dec 27 12:17:58 CET 2001
+ 3 copy put % ASET(Z,oO,oPo);
+ exch 1 add exch % INCR(oO);
+ % DECR(q);
+ }for % ENDWHILE
+ pop % oPo, BUG fixed at Thu Dec 27 12:18:47 CET 2001
+ }loop % ENDWHILE
+ % Stack: Z oO''==p+oO
+ pop pop
+ v fvFree % fvFree(v);
+ /v p fvMktree def % SET(v,fvMktree(p));
+ % Stack: -
+ % /* vvv No need for array copy, just change/pass the pointer to Z... */
+ oO 1 sub -1 0{ % SET(oO'',oO); WHILE(NZ(oO'')) DECR(oO'');
+ Z exch dup
+ % Stack: Z oO'' oO''
+ p add Z exch get put % ASET(Z,oO'',AREF(Z,oO'' + p));
+ }for % ENDWHILE
+ /h oO fvMktree def % SET(h,fvMktree(x));
+ }ifelse % ENDIF
+ /mode MODE_MOB def % SET(mode,MODE_MOB);
+ % goto mode_mob;
+ }{ % ELSE /* inline: fv(..., 7); */
+
+ /**
+ * Copies a block of input to output (mostly) verbatim. This is for
+ * BTYPE==0, non-compressed block, subsubsection 3.2.4 of RFC 1951.
+ * (We need non-compressed because
+ * some blocks cannot be compressed effectively, so gzip inserts them
+ * as is.)
+ * @whichcode 7
+ */
+ fxSkip % fxSkip();
+ % /* ^^^ skip till we reach byte boundary. fvRead! 0..7 bits */
+ /f fxRead16 def % SET(f,fxRead16()); /* length of block: 0..65535 */
+ % #if NDEBUG
+ % #else
+ % fprintf(stderr, "COPY1_BLK=%d Tvar=%d\n", f, Tvar);
+ % #endif
+ 2 fxIgnore8 % IGNORE fxRead16(); /* one's complement of length; ignored */
+
+ f 32768 Tvar sub sub dup 0 lt{ % IF((unsigned short)f<32768-(unsigned short)Tvar)
+ pop
+ Sbuf Tvar 1 1 f{ % WHILE(NZ(f)) -- inverse for
+ pop
+ % Stack: Sbuf Tvar
+ 2 copy fxRead8 put % ASET_S(Tvar,fxRead8());
+ 1 add % INCR(Tvar);
+ }for % ENDWHILE
+ /Tvar exch def pop
+ ASSERT_TRUE(mode MODE_BOB INT_EQ,(mode==MODE_BOB))
+ ASSERT_TRUE(Tvar 32768 lt,(Tvar<32768))
+ }{ % ELSE
+ % /* Even if f>=32768 */
+ /f exch def % SUB(f,32768-Tvar);
+ Tvar 1 32767{ % WHILE(NE((unsigned short)Tvar,32768))
+ Sbuf exch fxRead8 put % ASET_S(Tvar,fxRead8());
+ % INCR(Tvar);
+ % DECR(f);
+ }for % ENDWHILE
+ /Tvar 0 def % SET(Tvar,0);
+ /mode MODE_COPY1 def % SET(mode,MODE_REP);
+ % bbb666
+ DEBUG(counttomark 42 string cvs)
+ DEBUG(( whata\n))
+ % trtr
+ ASSERT_TRUE(counttomark 0 eq,(seccounttomark==0))
+ DEBUG((whatb\n))
+ 32768 exit % return (WORD)32768; % exit from big-big loop
+ }ifelse % ENDIF
+ o 0 INT_NE{fvAFB}if % IF(NZ(o)); fvAFB(); ENDIF
+ DEBUG( counttomark 42 string cvs)
+ DEBUG((pikula\n))
+ }ifelse % ENDIF
+ }if % ENDWHILE /* MODE_BOB */
+ % Stack: -
+
+ mode MODE_BOS INT_EQ{
+ DEBUG(counttomark 42 string cvs)
+ DEBUG(( booski\n))
+ DEBUG2((boost)===only)
+ DEBUG2(currentfile FP ===)
+ {
+ DEBUG(counttomark 42 string cvs)
+ DEBUG(( boosbe\n))
+ tY FMT_STOP INT_EQ{ % WHILE(NE(tY,FMT_STOP))
+ Tvar 0 INT_NE{ % /* Flush unwritten buffer. */
+ Tvar% BUG fixed at Thu Dec 27 14:05:32 CET 2001
+ /Tvar 0 def
+ % Stack: Tvar_old
+ }{0}ifelse
+ % ccc777
+ exit % return % in big-big loop and BOS-loop
+ }if
+ % /* SET(oO,0); SET(oP,0); */ /* avoid GCC warnings */
+ % /* fxInit(); */ /* assert(Y==0); SET(J,0); SET(Y,0); */
+ /v NULL def /h NULL def % SET(v,NULL); SET(h,NULL);
+ % N 0 NULL put N 1 NULL put N 2 0 put % ASET(N,0,NULL); ASET(N,1,NULL); ASET(N,2,0); /* the NULL node is initially empty */
+ % N 3 NULL put N 4 NULL put N 5 0 put % ASET(N,3,NULL); ASET(N,4,NULL); ASET(N,5,0); /* the Sentinel node is initially empty */
+ constZ19 N copy pop % eliminate-NULLs trick: overwrites 1st >=6 elements of N
+ /Dvar 6 def % SET(Dvar,6); /* first free node is 6. `0' is NULL, `3' is Sentinel */
+ 6{ % SET(o,Dvar);
+ dup NODESIZE ge{pop exit}if % WHILE (LT(o,NODESIZE))
+ dup N exch dup 3 add put 1 add % ASET(N,o,o+3); INCR(o); /* next free node is next node */
+ dup N exch NULL put 1 add % ASET(N,o,NULL); INCR(o); /* empty RIGHT */
+ dup N exch 0 put 1 add % ASET(N,o,0); INCR(o); /* empty NVAL */
+ }loop % ENDWHILE
+ % Stack: -
+ fxRead8EOF dup /tY exch def % SET(tY,fxRead8EOF()); /* read first byte of the header */
+ % tY kkkkkkkkkk
+ dup 511 INT_EQ{ % IF(EQ(tY,511)) /* EOF */
+ /tY FMT_STOP def % SET(tY,FMT_STOP);
+ }{
+#if CFG_FMT_ZLIB_ONLY
+ 1 fxIgnore8 % IGNORE fxRead8(); /* skip second header byte: 0x01 or 0x5e or 0x9c or 0xda */
+#else
+ dup FMT_ZLIB INT_EQ{ % ELSE_IF(EQ(tY,120)) /* ZLIB format */
+ 1 fxIgnore8 % IGNORE fxRead8(); /* skip second header byte: 0x01 or 0x5e or 0x9c or 0xda */
+ % /* SET(tY,FMT_ZLIB); */
+ }{
+ dup 80 INT_EQ{ % ELSE_IF(EQ(tY,80)) /* ZIP format */
+ 1 fxIgnore8 % IGNORE fxRead8(); /* skip second header byte: 0x48 */
+ /tY FMT_NONE def % SET(tY,FMT_NONE);
+ fxRead8 % SET(o,fxRead8());
+ dup 3 INT_EQ{ % IF(EQ(o,3)) /* Local file header */
+ % fxRead8 pop % IGNORE fxRead8(); /* skip: 0x04 */
+ % fxRead16 pop % IGNORE fxRead16(); /* skip: version needed to extract file (0x0020) */
+ % fxRead16 pop % IGNORE fxRead16(); /* LOCFLG flags */
+ 5 fxIgnore8
+ /tY fxRead8 def % SET(tY,fxRead8()); /* lower half of compression method */
+ ASSERT_TRUE(tY FMT_ZIP_STORED INT_EQ tY FMT_ZIP_DEFLATED INT_EQ or,(ty==FMT_ZIP_STORED || ty==FMT_ZIP_DEFLATED))
+ % ^^^ BUG fixed at Thu Dec 27 20:55:52 CET 2001
+ % fxRead8 pop % IGNORE fxRead8(); /* upper half of compression method */
+ % fxRead16 pop fxRead16 pop % IGNORE fxRead16(); IGNORE fxRead16(); /* file modification time in MS-DOS format */
+ % fxRead16 pop fxRead16 pop % IGNORE fxRead16(); IGNORE fxRead16(); /* some kind of CRC-32 */
+ 9 fxIgnore8
+ /f fxRead16z def % SET(f, fxRead16z()); /* lower compressed file size */
+ /oP fxRead16z def % SET(oP,fxRead16z()); /* higher compressed file size */
+ 4 fxIgnore8 % fxRead16 pop fxRead16 pop % IGNORE fxRead16(); IGNORE fxRead16(); /* uncompressed file size */
+ fxRead16z % SET(oO,fxRead16z()); /* length of filename */
+ fxRead16z add % SET(q,fxRead16z()); /* length of extra field */
+ % WHILE(NZ(oO)) IGNORE fxRead8(); DECR(oO); ENDWHILE /* file name */
+ % WHILE(NZ(q)) IGNORE fxRead8(); DECR(q); ENDWHILE /* extra field */
+ % -1 1{fxRead8 pop}for
+ fxIgnore8z
+ }{
+ dup 7 INT_EQ{ % ELSE_IF(EQ(o,7)) /* Extended local header of previous file in ZIP */
+ % 1 1 13{fxRead8 pop}for % SET(o,0); WHILE(LT(o,13)) IGNORE fxRead8(); INCR(o); ENDWHILE /* BUGFIX: was 15 */
+ 13 fxIgnore8
+ }{
+ dup 5 INT_EQ{ % ELSE_IF(EQ(o,5)) /* End of Central Directory Structure in ZIP */
+ /* fprintf(stderr,"EOCDS\n"); */
+ % 1 1 17{fxRead8 pop}for % SET(o,0); WHILE(LT(o,17)) IGNORE fxRead8(); INCR(o); ENDWHILE
+ 17 fxIgnore8
+ fxRead16z % SET(o,fxRead16z()); /* CML: archive comment length */
+ % -1 1{fxRead8 pop}for % WHILE (NZ(o)) IGNORE fxRead8(); DECR(o); ENDWHILE
+ fxIgnore8z
+ }{
+ dup 1 INT_EQ{ % ELSE_IF(EQ(o,1)) /* Central Directory Structure */
+ /* fprintf(stderr,"CDS\n"); */
+ % 1 1 25{fxRead8 pop}for % SET(oO,0); WHILE(LT(oO,25)) IGNORE fxRead8(); INCR(oO); ENDWHILE
+ 25 fxIgnore8
+ fxRead16z % SET(f,fxRead16z()); /* LEN: length of file name */
+ fxRead16z add % SET(o,fxRead16z()); /* XLN: length of extra field */
+ fxRead16z add % SET(q,fxRead16z()); /* CML: length of file comment */
+ % fxRead16 pop fxRead16 pop fxRead16 pop
+ % fxRead16 pop fxRead16 pop fxRead16 pop
+ % ^^^ SET(oO,0); WHILE(LT(oO,12)) IGNORE fxRead8(); INCR(oO); ENDWHILE
+ 12 fxIgnore8
+ fxIgnore8z
+ % ^^^ WHILE(NZ(f)) IGNORE fxRead8(); DECR(f); ENDWHILE /* file name */
+ % WHILE(NZ(o)) IGNORE fxRead8(); DECR(o); ENDWHILE /* extra field */
+ % WHILE(NZ(q)) IGNORE fxRead8(); DECR(q); ENDWHILE /* file comment */
+ }if % o==1
+ }ifelse % o==5
+ }ifelse % o==7
+ }ifelse % o==3 % ENDIF /* IF ZIP structure sub-type */
+ % Stack: tY_old o
+ pop
+ }{
+ dup 31 INT_EQ{ % ELSE_IF(EQ(tY,31)) /* gzip/RFC 1952 format */
+ /* fprintf(stderr,"gzip!\n"); */
+ /* SET(tY,FMT_GZIP); */
+ /* The most simple gzip header (10 bytes):
+ * ID1 hex 0x1f == dec 31 == FMT_GZIP
+ * ID2 hex 0x8b
+ * CM hex 0x08
+ * FLG hex 0x00
+ * MTIME hex 0x00, 0x00, 0x00, 0x00 (1 Jan 1970, UNIX epoch)
+ * XFL hex 0x00
+ * OS hex 0xff
+ * After that comes the compressed data stream.
+ * After that comes the CRC32 and ISIZE (byte aligned? ?)
+ */
+ 2 fxIgnore8 % fxRead16 pop % IGNORE fxRead16(); /* ignore ID2 and CM */
+ % kkkkkkkkkl
+ fxRead8 % SET(o,fxRead8()); /* FLG */
+ % fxRead16 pop fxRead16 pop % IGNORE fxRead16(); IGNORE fxRead16(); /* ignore MTIME */
+ % fxRead16 pop % IGNORE fxRead16(); /* ignore XFL, OS */
+ 6 fxIgnore8
+ % Stack: o==FLG
+ dup 2 and 0 INT_NE{ % IF(TAND_P(o,2)) /* GCONT: skip part number of continuation */
+ %fxRead16 pop % IGNORE fxRead16();
+ 2 fxIgnore8
+ }if % ENDIF
+ dup 4 and 0 INT_NE{ % IF(TAND_P(o,4)) /* ignore FEXTRA */
+ fxRead16 fxIgnore8
+ % 1 1 fxRead16{fxRead8 pop}for
+ % SET(q,fxRead16());
+ % WHILE(NZ(q)) IGNORE fxRead8(); DECR(q); ENDWHILE
+ }if % ENDIF
+ dup 8 and 0 INT_NE{ % IF(TAND_P(o,8))
+ {fxRead8 0 INT_EQ{exit}if}loop % WHILE(NZ(fxRead8())); PASS; ENDWHILE
+ }if % ENDIF /* ignore FNAME */
+ dup 17 and 0 INT_NE{ % IF(TAND_P(o,16))
+ {fxRead8 0 INT_EQ{exit}if}loop % WHILE(NZ(fxRead8())); PASS; ENDWHILE
+ }if % ENDIF /* ignore FCOMMENT */
+ dup 32 and 0 INT_NE{ % IF(TAND_P(o,32)) /* skip encryption header */
+ % fxRead16 pop fxRead16 pop fxRead16 pop
+ % fxRead16 pop fxRead16 pop fxRead16 pop
+ % SET(f,0); WHILE(LT(f,12)) IGNORE fxRead8(); INCR(f); ENDWHILE
+ 12 fxIgnore8
+ }if % ENDIF
+ % Stack: tY o
+ pop
+ }if % tY==31 (gzip/RFC 1952 format)
+ }ifelse % tY==80 (ZIP format)
+ }ifelse % tY==FMT_ZLIB
+#endif /* CFG_FMT_ZLIB_ONLY */
+ }ifelse % tY==511 % ENDIF /* IF file format */
+ % Stack: tY_old
+ pop
+ % /* fprintf(stderr,"tY=%d\n", tY); */
+ % tY bbbbbc
+#if CFG_FMT_ZLIB_ONLYX
+ /* FMT_ZIP_STORED can become alive somehow... */
+ tY FMT_STOP INT_NE tY 3 INT_NE and{
+ /mode MODE_BOB def % SET(mode,MODE_BOB);
+ -1 exit % goto mode_bob;
+ }if
+#else
+ tY FMT_ZIP_STORED INT_EQ{ % IF(EQ(tY,FMT_ZIP_STORED))
+ % /* fprintf(stderr,"ZIP_STORED oO=%d oP=%d\n", oO, oP); */
+ /oO 0 def % SET(oO,0);
+ f 32768 Tvar sub sub dup 0 lt{ % IF((unsigned short)f<32768-(unsigned short)Tvar)
+ pop
+ Sbuf Tvar 1 1 f{ % WHILE(NZ(f)) -- inverse for
+ pop
+ % Stack: Sbuf Tvar
+ 2 copy fxRead8 put % ASET_S(Tvar,fxRead8());
+ 1 add % INCR(Tvar);
+ }for % ENDWHILE
+ /Tvar exch def pop
+ ASSERT_TRUE(Tvar 32768 lt,(Tvar<32768))
+ oP 0 INT_NE{
+ /mode MODE_ZSTO def
+ % ccc555
+ Tvar exit % in big-big loop and BOS-loop
+ }if
+ % ^^^ IF(NZ(oP)); mode=MODE_ZSTO; return Tvar; ENDIF
+ ASSERT_TRUE(mode MODE_BOS INT_EQ,(mode==MODE_BOS))
+ }{ % ELSE
+ % /* Even if f>=32768 */
+ /f exch def % SUB(f,32768-Tvar);
+ Tvar 1 32767{ % WHILE(NE((unsigned short)Tvar,32768))
+ Sbuf exch fxRead8 put % ASET_S(Tvar,fxRead8());
+ % INCR(Tvar);
+ % DECR(f);
+ }for % ENDWHILE
+ /Tvar 0 def % SET(Tvar,0);
+ /mode MODE_ZSTO def % SET(mode,MODE_REP);
+ % bbb777
+ 32768 exit % return (WORD)32768; % in big-big loop and BOS-loop
+ }ifelse % ENDIF
+ }{
+ tY FMT_STOP INT_NE tY FMT_NONE INT_NE and{
+ /mode MODE_BOB def % SET(mode,MODE_BOB);
+ -1 exit % goto mode_bob;
+ }if
+ }ifelse % ENDIF
+#endif /* CFG_FMT_ZLIB_ONLY */
+ }loop % ENDWHILE /* outermost WHILE(NE(tY,FMT_STOP)) */
+ % Stack: retval
+ }{-1}ifelse % mode==MODE_BOS
+ % Stack: retval
+ }loop % big-big MODE_MOB||MODE_BOB||MODE_BOS loop
+ % Stack: retval
+}BIND_DEF % ENDFUN
+
+% Stdin already set
+#if 0
+% /fvInitAll{
+#define fvInitAll \
+ fxInit \
+ /tY FMT_NONE def \
+ /mode MODE_BOS def \
+ /Tvar 0 def /* make the round buffer empty */ \
+ TE_init
+% }BIND_DEF
+#else
+/fvMain{
+ % /XXX
+ % STDIN read
+ % STDIN C readhexstring
+ % pop 0 get true_action
+ % TE_read(===)
+
+ TE_init % must be called _before_ fxInit
+ fxInit
+ /tY FMT_NONE def
+ /mode MODE_BOS def
+ /Tvar 0 def
+ % /Tvar 0 def Tvar === quit
+ { Sbuf 0 fvWork getinterval } /G load exec
+ TE_read_eod % make sure that mEOD has been read
+}BIND_DEF
+#endif
+
+} /* We close the brace of declared functions */
+%</Defs>
+
+%<Data>
+%%BeginData:
+exec
+`S
+%%EndData
+end restore showpage
+%%Trailer
+%%EOF
+%</Data>
+
+%%EOF