# Data Compression, 4th Edition.

Program and Pseudo-Code Listings

Chapter 1 % Returns the run lengths of % a matrix of 0s and 1s function R=runlengths(M) [c,r]=size(M); for i=1:c; x(r*(i-1)+1:r*i)=M(i,:); end N=r*c; y=x(2:N); u=x(1:N-1); z=y+u; j=find(z==1); i1=[j N]; i2=[0 j]; R=i1-i2; the test M=[0 0 0 1; 1 1 1 0; 1 1 1 0] runlengths(M) produces 3 4

1

3

1

Figure 1.9a. Matlab Code To Compute Run Lengths.

Chapter 2 Frequencies[list_]:=Map[{Count[list,#],#}&, Union[list]]; Entropy[list_]:=-Plus @@ N[# Log[2,#]]& @ (First[Transpose[Frequencies[list]]]/Length[list]); Characters["swiss miss"] Entropy[%]
Mathematica code to compute the entropy of a string (page 51).

L = 0; % initialize N = 0; m = 1; % or ask user for m % main loop for each run of r zeros do construct Golomb code for r using current m. write it on compressed stream. L = L + r: % update L, N , and m N = N + 1; p = L/(L + N ); m = −1/ log2 p + 0.5 ; endfor; —1—

Data Compression (4th Edition): Verbatim Listings
Figure 2.13. Simple Adaptive Golomb RLE Encoding.

F[i]:=F[i]+1; repeat forever j:=P[i]; if j=1 then exit; j:=Q[j-1]; if F[i]<=F[j] then exit else tmp:=P[i]; P[i]:=P[j]; P[j]:=tmp; tmp:=Q[P[i]]; Q[P[i]]:=Q[P[j]]; Q[P[j]]:=tmp endif; end repeat
Figure 2.37. Swapping Pointers in MNP5.

lowRange={0.998162,0.023162,0.}; highRange={1.,0.998162,0.023162}; low=0.; high=1.; enc[i_]:=Module[{nlow,nhigh,range}, range=high-low; nhigh=low+range highRange[[i]]; nlow=low+range lowRange[[i]]; low=nlow; high=nhigh; Print["r=",N[range,25]," l=",N[low,17]," h=",N[high,17]]] enc[2] enc[2] enc[1] enc[3] enc[3]
Figure 2.49. Mathematica Code for Table 2.52.

After MPS: C is unchanged A ← A − Qe; % The MPS subinterval if A < 800016 then % if renormalization needed if A < Qe then % if inversion needed C ← C + A; % point to bottom of LPS A ← Qe % Set A to LPS subinterval endif; renormalize A and C; endif; After LPS: A ← A − Qe; % The MPS subinterval if A ≥ Qe then % if interval sizes not inverted C ← C + A; % point to bottom of LPS A ← Qe % Set A to LPS subinterval endif; renormalize A and C;
Figure 2.69. QM-Encoder Rules With Interval Inversion.

—2—

Figure 3. if <<di.Data Compression (4th Edition): Verbatim Listings Chapter 3 (QIC-122 BNF Description) <Compressed-Stream>::=[<Compressed-String>] <End-Marker> <Compressed-String>::= 0<Raw-Byte> | 1<Compressed-Bytes> <Raw-Byte> ::=<b><b><b><b><b><b><b><b> (8-bit byte) <Compressed-Bytes> ::=<offset><length> <offset> ::= 1<b><b><b><b><b><b><b> (a 7-bit offset) | 0<b><b><b><b><b><b><b><b><b><b><b> (an 11-bit offset) <length> ::= (as per length table) <End-Marker> ::=110000000 (Compressed bytes with offset=0) <b> ::=0|1 Figure 3.7. delete the first character of M. repeat read(ch). i:=i+length(S).21. until end-of-input. each mapped to a unique integer. di:=dictionary index of ch. endif. while i <= input size k:=longest match of Input[i] to Dict.ch>>. The LZW Algorithm. S:=Phrase k of Dict. M:=empty string. for i:=0 to 255 do append i as a 1-symbol string to the dictionary. append λ to the dictionary. BNF Deﬁnition of QIC-122. —3— . Repeat Append the next symbol C of the input stream to M. If M is not in the dictionary. Output(k). Start with a dictionary containing all the symbols of the alphabet. S’:=S. Initialize Dict to all the symbols of alphabet A. If phrase S’S is not in Dict. endwhile. append it to Dict. S’:=null. add it to the dictionary. else output(di). append <<di. and repeat this step.ch>> is in the dictionary then di:=dictionary index of <<di. Pseudo-code algorithm for LZMW. i:=1.ch>> to the dictionary. di:=dictionary index of λ.

b. next_code[len]++. M:=empty string. bits++) { code = (code + bl_count[bits-1]) << 1. function PaethPredictor (a. compute distances pb := abs(p-b) . n++) { len = tree[n].. Until end-of-input. if (len != 0) { tree[n]. set M:=MC.M) as above. code = 0. to a. Repeat Input the next symbol C. After M is short enough so that MC is in the dict. Pseudo-code algorithm for LZY encoder.initial estimate pa := abs(p-a) . c) begin . and update (D. Also output C and chop it off from the front of O. add T to S. add MC to T (mapping to the next available integer). and remove everything from T. While MC is not in S or T. and chop off the first character of M.Data Compression (4th Edition): Verbatim Listings Until end-of-input. } } Fragments of C code by Peter Deutsch (after RFC1951). If OC is in S. set O:=C.Len. Repeat Read D(O) from the input and take the inverse under D to find O. Pseudo-code algorithm for LZY. for (bits = 1.Code = next_code[len]. bl_count[0] = 0. bits <= MAX_BITS. As long as O is not the empty string. next code[bits] = code. } for (n = 0. a=left. Start with a dictionary containing all the symbols of the alphabet. Start with S mapping each single character to a unique integer. c pc := abs(p-c) —4— . Pseudo-code algorithm for LZY decoder. M empty. n <= max code. and O empty. Output S(O) and quit. each mapped to a unique integer. b. Until end-of-input. find the first character C of O. c=upper left p:=a+b-c . otherwise output S(O). b=above. set O:=OC. set T empty.

i) [r. colormap(gray) Figure 4.a. function PSNR(A. img=fread(fid.</title> <email>mschwa@monster. fid=fopen(filename.com</email> <phone>(212)555-1414</phone> <logo url="widget. breaking ties in order a.b). dim=128.’r’).mask). filename=’parrots128’. mask=1. % between 1 and 8 nimg=bitget(img.b.5.[dim. colormap(gray) clear. dim=128.7. img=fread(fid.org"> <name>Melvin Schwartzkopf</name> <title>Chief person. Code For Table 4. nimg=bitget(b.[dim. imagesc(b) Matlab Code for Figure 4.a).i-1). b=[zeros(r. b=bitxor(img. imagesc(nimg). b=rgc(b. filename=’parrots128’.6. b=bitshift(a.dim])’.flipud(a)].-1).Data Compression (4th Edition): Verbatim Listings . . <card xmlns="http://businesscard.mask). imagesc(nimg).8. mask=1 % between 1 and 8 a=bitshift(img.c. dec2bin(b) Code for Table 4. clear.’r’). Matlab Code to Separate Image Bitplanes.c]=size(a). fid=fopen(filename. ones(r. end. a=rand(n). Chapter 4 n=32.B) if A==B error(’Images are identical. a=linspace(0. colormap(gray) b=inv(a).gif"/> <red_backgrnd/> </card> A business card in XML. if pa<=pb AND pa<=pc then return a else if pb<=pc then return b else return c end Pseudo-code for the PaethPredictor function.dim])’. imagesc(a).31.c.b.1). if i>1. Monster Inc. function b=rgc(a.1). return nearest of a. b=bitxor(a.-1). PSNR is undefined’) end —5— .32).

{150}]]].1]]p[[i.{23. rot={{0. h[k_.Table[Random[Real. (* h_0(x) *) p=0. q=k-2^p+1.{250}]]].2}]] Mathematica code for Figure 4.2}].{250}].1]]q[[i.1). 7}.17. max2_B=max(max(B)). colormap(gray) %after rotation Figure 4. p=Flatten[Append[p.x_]:=Module[{p. A Matlab Function to Compute PSNR. (* if k>0.col+1))*0.1. p=Flatten[Append[p. end end figure(1). colormap(gray) %dist of x&y values figure(4). fid=fopen(filename. img=fread(fid.{250}]]]. end end figure(3). min2_B=min(min(B)). plot(xdist).7071}.2]].7071.Table[Random[Real.p++].Data Compression (4th Edition): Verbatim Listings max2_A=max(max(A)).Table[Random[Real. calc. {i.2}.^2))))).7071)+101. p=Flatten[Append[p. for col=1:2:dim-1 for row=1:dim x=round((img(row. Code For Rotating Five Points.Table[Random[Real. xdist=zeros(256. colormap(gray) %before rotation xdist=zeros(325. If[k==0.7071. plot(ydist).5}] q=p.0.{0.25}.{0. ListPlot[Table[{p[[i]].1]’) end differ=A-B. q *) —6— . 1/Sqrt[n]. plot(xdist). y=img(row.1).decib)) Figure 4. p={{5.13.{2.col)+img(row.{250}]]].{3.7071}}.{6.{1.col)+1.3}]. colormap(gray) %dist of x&y values figure(2). min2_A=min(min(A)). plot(ydist).5}. % clear arrays ydist=zeros(256.p[[i+1]]}.Table[Random[Real.13.rot Sum[q[[i.5}].dim])’.29}}.1399.col+1)+1.6}]. Distribution of Image Pixels Before and After Rotation. filename=’lena128’.q}.{i.{4.15. While[2^p<=k .1). disp(sprintf(’PSNR = +%5.col+1))*0.2]]. decib=20*log10(1/(sqrt(mean(mean(differ. dim=128.{250}]]]. xdist(x)=xdist(x)+1.1).16.’r’). p--. Needs["GraphicsImage‘"] (* Draws 2D Haar Coefficients *) n=8.col)+img(row. y=round((-img(row.{12.{0. ydist(y)=ydist(y)+1. p=Table[Random[Real. Sum[p[[i.1.5}] Figure 4. p=Flatten[Append[p. xdist(x)=xdist(x)+1.{32. if max2_A>1 | max2_B>1 | min2_A<0 | min2_B<0 error(’pixels must be in [0. ydist(y)=ydist(y)+1.7071). p=Flatten[Append[p. {i.4}].[dim. ydist=zeros(256.-0.2f dB’. for col=1:2:dim-1 for row=1:dim x=img(row. p.6}].

.0.0.{t.y+1)*cos((2*y+1)*j*pi/16)*cos((2*x+1)*i*pi/16). else ci=1.0.0.7}.2^(p/2).50.7071.20.. idct(x+1.50. .0.0. p={12..3.40.0. dct quant=[239.0.n}].0.0.n-1}] Figure 4.10. imagesc(idct).0. HaarTensor.50.j+1)*cos((2*y+1)*j*pi/16)*cos((2*x+1)*i*pi/16).60. If[(q-.30.0.8. {-2.. 20.20.0. HaarMatrix=Table[h[k. 00. axis off Figure 4. 0.Pi/8}] dctp[0] dctp[1] .0.1/n}] //N.30. end.0.30. 1].0.{t.0.50.21.30.Pi/8}] dctp[pw_]:=Table[N[Cos[pw t]].0. 0.40.0.20.33.{j. dct(:.40.00.1. colormap(gray).n).n}]. ci*cj*quant(i+1.40. Code for Highly Correlated Pattern. end. axis square. Experiments with the One-Dimensional DCT.7/n.}. 30.0.0.n-1}].10.{t. for j=0:7 if j==0 cj=0.30.30.j+1)+p(x+1. (* or use quantized DCT coefficients *) idct[t_]:=Sqrt[2/n]Sum[c[[j+1]]q[[j+1]]Cos[(2t+1)j Pi/16]. {t.00].0. HaarMatrix[[#1]].0.30.8.30. q=Table[dct[i].0. p=[00. axis off dct=zeros(n.15Pi/16. .0. ip=Table[idct[t].0.0.60.. idct figure(2).7071. 10. 0.50.7071.0.HaarMatrix[[#2]]]&.20.0. end.60. c=Table[If[t==1.2}]&. colormap(gray).40.0. else cj=1.0.0. {k. {x.-2^(p/2). Show[GraphicsArray[Map[GraphicsImage[#.1)*0.0]]]].Data Compression (4th Edition): Verbatim Listings If[(q-1)/(2^p)<=x && x<(q-.:)*0. 20.40.n-1}] (* use precise DCT coefficients *) q={28. 30.10..0.0.0.40.40. figure(1).15Pi/16.20. idct=zeros(n. {n. -90.0.40.0.:)=dct(1.0.0. idct=idct/4. end.0.0.0.0. % 8x8 correlated values n=8..10.0.40.50. 10.. HaarTensor=Array[Outer[Times. 0.{t.n).0.20.1)=dct(:.n-1}].7071. end..0.10.30.y+1)+ ..{2}]]] Code for Figure 4.0.20.20.5)/(2^p).0.10.10. dct[i_]:=Sqrt[2/n]c[[i+1]]Sum[p[[t+1]]Cos[(2t+1)i Pi/16].40.30. dct=dct/4. .0.30.50.0.0.0. n=8...30.0}.1. dct(1.-90. axis square.0.0. end.0.0.. 0. 0. end.30. imagesc(p). end.12..0.-2.11.. for x=0:7 for y=0:7 for i=0:7 if i==0 ci=0..{i.12..y+1)=idct(x+1.0. for j=0:7 for i=0:7 for x=0:7 for y=0:7 dct(i+1.j+1)=dct(i+1. 0.0.0. —7— .50.0.0].10.60.20.10.2.30. end.5)/(2^p)<=x && x<q/(2^p).Pi/16.x].0.7071.20. Table[N[t].Pi/16.40. end.

img={{1.25}]&.0.0.Sqrt[1/8].1.0. dcdot[pw_]:=ListPlot[Table[{t.0.1}.15Pi/16.Sqrt[1/4]Cos[Pi(2j+1)k/16]]. DCTMatrix[[#1]].0.1.37. {1.1.0}.1.1. {8.0.1. Prolog->AbsolutePointSize[4]...dcdot[7].0.DCTMatrix[[#2]]]&.0.{0.7}.1}.ft_]:=Table[SetAccuracy[N[(1. DCTMatrix=Table[If[k==0. {s.0}.1}.1.0}. DCTMatrix[[#1]].1.Sqrt[1/8].1.0.7}.0}}.25.Pi}.0.0.40.{0.1] . DCTTensor=Array[Outer[Times. DCTMatrix[[#1]]. DCTMatrix=Table[If[k==0.1.{2}]]] Alternative Code for Figure 4.{1. Needs["GraphicsImage‘"] (* Draws 2D DCT Coefficients *) DCTMatrix=Table[If[k==0. DCTTensor.001]. Show[GraphicsArray[Map[GraphicsImage[#. DisplayFunction->Identity. Show[dct[7].1}.DCTMatrix[[#2]]]&.8}].Cos[pw t]}.0. img={{0.0.{8.0.4]. DisplayFunction->Identity] Show[dct[0]. {k.39.-Cos[fs s]Cos[ft t])/2].8}].Pi/8}. DisplayFunction->\$DisplayFunction] .{t.Pi/8}]//TableForm dctp[0.0.1}. {0..15Pi/16.3]. {j. {8.36. dctcoeff=Chop[dctcoeff.7}] //N.0.Pi/16. dctp[fs_. AspectRatio->Automatic].1. {j.Sqrt[1/8].1. DCTTensor=Array[Outer[Times. {-. {8.. ShowImage[Reverse[img]] dctcoeff=Array[(Plus @@ Flatten[DCTTensor[[#1.0. {0.Pi/16.0.0.0.1.0. dctp[7.1. {t.Pi/16.0.DCTMatrix[[#2]]]&.1.0.1. —8— .#2]] img])&. {k.1.1. Prolog->AbsolutePointSize[4]..0.7}] //N.0.8}].0.1.1.0.8}].0.{t.{1.0.1}.dcdot[0].Pi/8}]..1.1.{0.1.15Pi/16. {j.0.1. DisplayFunction->\$DisplayFunction] Code for Figure 4.7}.7}] //N.39.0.1.7] Code for Figure 4.Sqrt[1/4]Cos[Pi(2j+1)k/16]].0.1.1.1. MatrixForm[dctcoeff] ShowImage[Reverse[dctcoeff]] Code for Figure 4. DCTTensor=Array[Outer[Times.Sqrt[1/4]Cos[Pi(2j+1)k/16]].1.0.0. dct[pw_]:=Plot[Cos[pw t].Data Compression (4th Edition): Verbatim Listings dctp[7] Code for Table 4. {k. dctcoeff=SetAccuracy[dctcoeff.0.0.0.0] dctp[0.1.

0.n-1}] T3=Table[DCT3[k].4].1. DCT1[k_]:=Table[nor kj[j] kj[k] Cos[j k Pi/n].n-1}] T4=Table[DCT4[k]. nor. nor.41. {j. kj. (* DCT-1. Code for Four DCT Types.n}.n}]] (* DCT-3.n}.1. 1/Sqrt[2].T4[[j]]]].001]. nor. kj.#2]] img])&.{8. {i. n=8.1. {k.0. {j. kj[i_]:=If[i==0 || i==n.Data Compression (4th Edition): Verbatim Listings {0.n-1}]. {j. This is the transpose of DCT-2 *) Clear[n.0.0.1.1.1. nor=Sqrt[2/n].n-1}]. (* Compute nxn cosines *) MatrixForm[T1] (* display as a matrix *) (* multiply rows to show orthonormality *) MatrixForm[Table[Chop[N[T1[[i]]. function [Q. nor. dctcoeff=Chop[dctcoeff.0. {k.0.1.1.0.1}.1}. T3].0.1.1.T1[[j]]]]. {i. {k.1.1.n-1}] T2=Table[DCT2[k].1.0. n=8. dctcoeff=SetAccuracy[dctcoeff.0.{0.1. DCT3.n}] T1=Table[DCT1[k]. kj.R]=QRdecompose(A).1..8}]. 1].1. DCT2.0.n-1}]. {i.1.1.44.{0.1}. (* Compute nxn cosines *) MatrixForm[T2] (* display as a matrix *) (* multiply rows to show orthonormality *) MatrixForm[Table[Chop[N[T2[[i]].0.{0. DCT1.1.0.1}. Notice (n+1)x(n+1) *) Clear[n. DCT2[k_]:=Table[nor kj[k] Cos[(j+1/2)k Pi/n].n}]] (* DCT-2 *) Clear[n. {j. MatrixForm[dctcoeff] ShowImage[Reverse[dctcoeff]] Code for Figure 4. DCT4. DCT4[k_]:=Table[nor Cos[(k+1/2)(j+1/2) Pi/n].{0. kj[i_]:=If[i==0 || i==n. 1]. nor=Sqrt[2/n]. 1/Sqrt[2]. {j.n}]] Figure 4. T1].0. {j. nor=Sqrt[2/n].n}.0.n}. 1].0.0. {j.0. This is DCT-1 shifted *) Clear[n. kj[i_]:=If[i==0 || i==n. {0.1. {i. DCT3[k_]:=Table[nor kj[j] Cos[(k+1/2)j Pi/n].1.T3[[j]]]]. (* Compute nxn cosines *) MatrixForm[T4] (* display as a matrix *) (* multiply rows to show orthonormality *) MatrixForm[Table[Chop[N[T4[[i]].0.1}.1. {j.T2[[j]]]]. T4].0. 1/Sqrt[2].0. % Computes the QR decomposition of matrix A —9— . nor=Sqrt[2/n]. n=8.n}].0.1}}.0.0. n=8.0. ShowImage[Reverse[img]] dctcoeff=Array[(Plus @@ Flatten[DCTTensor[[#1.1.0.n}]] (* DCT-4.1. {k. T2]. (* Compute nxn cosines *) MatrixForm[T3] (* display as a matrix *) (* multiply rows to show orthonormality *) MatrixForm[Table[Chop[N[T3[[i]].1.1.

’.row)*C(:.Rb). s=-R(q.Rb)) Px=min(Ra. else if(Rc<=min(Ra. B[Q]=B[Q]+Errval*(2*NEAR+1). if(Rc>=max(Ra. if(SIGN=+1) Px=Px+C[Q] else Px=Px-C[Q] endif. n=m’. endif.Data Compression (4th Edition): Verbatim Listings % R is an upper triangular matrix and Q % an orthogonal matrix such that A=Q*R. Figure 4. N=8. U(p. % one Givens rotation Q=Q*U.Rb)) Px=max(Ra.52.*(m-1)/(2*N)).N.*(m-1)/(2*N)). endif. end end Figure 4.col). — 10 — .p)/w.n]=size(A). A Matlab Function for the QR Decomposition of a Matrix.72. for row=1:N for col=1:N B=C(:.Rb) else Px=Ra+Rb-Rc.p)=c. % determine the dimens of A Q=eye(m). Figure 4. U(q. % Construct a U matrix for Givens rotation U(p. A=sqrt(2/N)*sin(pi*(2*(n-1)+1). U(q. endif. U=eye(m).49.Prediction Correcting.71. The 64 Basis Images of the DST in Two Dimensions.:)=sqrt(1/N).p)/w.p)^2). R=U’*R. for p=1:n for q=(1+p):m w=sqrt(R(p. if(Px>MAXVAL) Px=MAXVAL else if(Px<0) Px=0 endif.q)=c.p)=-s. [m. %tensor product subplot(N.N).(row-1)*N+col) imagesc(B) drawnow end end Figure 4. % Q starts as the mxm identity matrix R=A. C=A’. % can also use cos instead of sin %A=sqrt(2/N)*cos(pi*(2*(n-1)+1).q)=s. c=R(p. m=[1:N]’*ones(1. A(1. Edge Detecting.p)^2+R(q.

1).J[RUNindex]).76. endwhile. and N . AppendToBitStream (RUNcnt. while(RUNcnt>=(1<<J[RUNindex])) AppendToBitStream(1. if(N[Q]=RESET) then A[Q]=A[Q]>>1. Quantize V and use it as an index to select a Laplace table LV.75. Figure 4. if(EOLine=0) then AppendToBitStream(0. Updating Arrays A.Data Compression (4th Edition): Verbatim Listings A[Q]=A[Q]+abs(Errval). while(abs(Ix-RUNval)<=NEAR) RUNcnt=RUNcnt+1. endwhile. for each level L do for every pixel P in level L do Compute a prediction R for P using a group from level L-1. Use E as an index to table LV and retrieve LV[E]. endfor. — 11 — . if(RUNindex<31) RUNindex=RUNindex+1.129. if(RUNindex>0) RUNindex=RUNindex-1.74. RUNcnt=0. N[Q]=N[Q]+1. N[Q]=N[Q]>>1 endif. Estimate the variance V to be used in encoding E. Run Encoding: II.1). endfor. RUNval=Ra. Figure 4.1). B . RUNcnt=RUNcnt-(1<<J[RUNindex]). Figure 4. Use LV[E] as the probability to arithmetically encode E. MLP Encoding. Determine the pixels of the next level (rotate & scale). if(EOLine=1) break else GetNextSample() endif. else if(RUNcnt>0) AppendToBitStream(1. Table 4. Compute E=R-P. Run Scanning. Rx=RUNval. B[Q]=B[Q]>>1. Figure 4. Run Encoding: I. endif.77.

PARAMETERS: ak and wk are assigned their values.1}. t) := S(d. d).p21. Nh={{-4.p22. t) := N (d.95.-13.1. t) + .95.p02.-22. b2. .90.91}.5. if digit(k)=2 or 3 then x := x + 2k endfor. a={90. ˆ n 1: Δ = k=1 wk (xk − x).Data Compression (4th Edition): Verbatim Listings Clear[Nh. for all pixels x in the current pass do n 0: x = k=1 ak ·xk . For all passes INITIALIZATION: N(d. . Expand[U...p32.128.95. t). end.90}.. t) := S(d. 5: x = x + ¯.80.0}}.5. ˙ ˆ 6: = x − x.85.2n .102. d) else encode( .w^2.90.90.W].96}.U.1. {i. Solving for Three Weights.5}. N (d..18.95. b3.150.p30}.{1.90.0. S=Table[N[Sin[t Degree]].5.75.80.100.9.5.108.(a-w1 b1-w2 b2-w3 b3)==0. {p13.5.5}.100.p00}}.80.w3}] Figure 4.80. W={w^3. t) := N (d.Transpose[W]] Code to predict the value of a pixel as a polynomial interpolation of 16 of its near neighbors.t):=1. ˆ 2: d = Quantize(Δ).{p03.360. u:=0.. x:=0.{w1.(a-w1 b1-w2 b2-w3 b3)==0.p01.108.1.0. 4: ¯ = S(d.u^2.P. w:=0. Figure 4.110. b2={101.w.0. ˙ 7: S(d. 3: Compute t = tn .13. S(d.90.75. endfor.139.Nh. t=0. t)/2. Solve[{b1.p11.5. Pseudo-Code to Locate a Pixel in an Image.136. {t..t2 t1 .85}.p20}.105. 9: if S(d.90. y:=0.Transpose[Nh].102. N (d.. — 12 — .t):=0.-4.{9. P={{p33. t)/N (d.u.1}.15}] Table[S[[i+1]]-S[[i]]. t)/2.w2. U={u^3.4. b3={128.p31. t) + 1.5. 8: if N (d.-4.100.p12. t) ≥ 128 then S(d. b1={100. {-5.5.24}] Code for Figure 4.p10}. The CALIC encoder.(a-w1 b1-w2 b2-w3 b3)==0}. d=0.L.96.{p23. for k:= n − 1 step −1 to 0 do if digit(k)=1 or 3 then y := y + 2k . t) < 0 encode(− ..P.1}..

min<=value<=max.depth of pixel level of quadtree. */ Compact_quadtree (knot_descriptor *knot. encode((knot->square[ 2 ])->pix.max).min. min . knot_descriptor *square[4].min.max) .0. min . case 1: if ((knot->square[2])->pix==max) { encode(1.max) .recursive procedure of quadtree compression. max= knot->max .1).min. max ). max ). return . } return . Log2(N) . encode((knot->square[ 3 ])->pix.. } else { // knot->depth == Log2(N) e pixel level int slc = 0 .max). max ).max of the whole sub-plane int pix .1).max). max ) . Compact_quadtree (. } return .//children’s sub-planes } .1). min . int min. min . Compact_quadtree(knot->square[ 1 ]. encode((knot->square[ 2 ])->pix. Compact_quadtree(knot->square[ 3 ].min. if ( knot->min == knot->max ) return .max.min. //min.function of encoding of value (output bits stream).min. encode((knot->square[ 3 ])->pix. } } } — 13 — .max) . // value of pixel (in case of pixel level) int depth . if ((knot->square[ 0 ])->pix == min) slc=1.max). // depth of knot. encode( (knot->square[ 1 ])->pix .1). encode( knot->max .0.1).min.) . struct knot_descriptor { int min..Data Compression (4th Edition): Verbatim Listings /* Definitions: encode( value .max) . int max) { encode( knot->min .max). } else { encode(0. encode((knot->square[ 3 ])->pix. if ( knot->depth < Log2(N) ) { Compact_quadtree(knot->square[ 0 ]. . if ((knot->square[ 1 ])->pix == min) slc |= 1. else if ((knot->square[ 0 ])->pix==max) slc=2.max). Compact_quadtree(knot->square[ 2 ]. max ) .min.0. the length of code is Log2(max-min+1) bits.0.min. encode( (knot->square[ 0 ])->pix .0. else if ((knot->square[ 1 ])->pix==max) slc |= 2. } else { encode(0. min = knot->min . switch( slc ) { case 0: encode(((knot->square[2])->pix==max).min. min . case 2: if ((knot->square[2])->pix==min) { encode(1. case 3: encode((knot->square[ 2 ])->pix.

Params:TEXT. if metric(R. PROGRAM IFS.834 % (50+1) 2. x0:=x1.1.x1. else partition R into smaller ranges and push them — 14 — . Readln(filename).6. Graphics.k]+y0*Transf[4. REPEAT k:=RandomInt(1.i].995. match all domains to R. Reset(Params).Transf[5.i]).y0.NumTransf). MathLib.. Figure 4.i]. find the one (D) that’s closest to R. BEGIN (* main *) Write(’params file=’). [stack contains ranges to be matched] repeat R:=pop(). y1:=Round((x0*Transf[3.Width. v[n+1] d[n+1] v[1] = d[1] = v[2] = d[2] = v[3] = d[3] = v[4] = d[4] = = d[n] % r = d[n] / r 2.’IFS shape’).10] OF INTEGER.k]. Transf[4. USES ScreenIO.i]. END. Transf: ARRAY[1. CONST LB = 5. FOR i:=1 TO NumTransf DO Readln(Params.k].Transf[3. y0:=y1.741 / (123+1) = 473 % (199+1) = 73 473 / (199+1) = 2 2 % (9+1) = 2 2 / (9+1) = 0 = 43 = 58.Transf[2. SetMode(paint).NumTransf+1). [t is the tolerance] push(entire image).741 % (123+1) = 58. ScBOL.Height.k. filename:STRING.Transf[1. ScWriteStr(’Hit a key & close this window to quit’).NumTransf: INTEGER. Width = 490.741 89 473 Decoding of N -Trees.k])/100)+Transf[6. Assign(Params.y1.184. (* LB=left bottom corner of window *) VAR i.y1). t:=some default value.i].i]. ScFreeze. y0:=100.Data Compression (4th Edition): Verbatim Listings Compression of N -Tree Structures. x1:=Round((x0*Transf[1.Transf[6.k])/100)+Transf[5. x0:=100.x0. Height = 285.D)<t then compute transformation w from D to R and output it. UNTIL Button()=TRUE.filename). Dot(x1.LB. OpenGraphicWindow(LB.834 / (50+1) 58. Calculate and Display IFS Attractors.. Readln(Params.k]+y0*Transf[2.995. pop(R).

comment move entire array end. endwhile. j:int). into the stack. √ b[j/2+i]:=(a[2i-1]-a[2i])/ 2. — 15 — . Computing the Normalized Wavelet Transform.Data Compression (4th Edition): Verbatim Listings into the stack.12. Figure 5.Y]=meshgrid(x. while j≥ 2 do NWTstep(a. endif. n:int). endfor.10.187. Chapter 5 t=linspace(0.256).y). and push D and w into the stack. Figure 4. if the number of ranges in the stack is <T then find range R with largest metric (worst match) pop R. procedure NWTstep(a:array of real.256). output all transformations w from the stack.9. plot(t.188. compute the transformation w. Figure 4. comment n is the array size (a power of 2) √ a:=a/ n comment divide entire array j:=n. axis(’ij’). [X. y=1:30. as unmatched.sinwav) cwt=CWT(sinwav. push(entire image). j). [stack contains ranges to be matched] repeat for every unmatched R in the stack find the best matching domain D. t=linspace(-10. endif until all ranges in the stack are matched. IFS Encoding: Version I.’Sombrero’). for i=1 to j/2 do √ b[i]:=(a[2i-1]+a[2i])/ 2. until stack is empty. sombr=(1-2*t. a:=b.^2).*exp(-t. IFS Encoding: Version II. plot(t.sombr) procedure NWTcalc(a:array of real.cwt’. contour(X.^2). imagesc(cwt’) x=1:256. colormap(gray). D and w from the stack partition R into smaller ranges and push them.10) Code For Figure 5.10. j:=j/2. sinwav=sin(t). end. input T from user.6*pi.Y.

√ a:=a/ n comment divide entire array j:=n. n). The Standard Image Wavelet Transform and Decomposition. n:int). n). procedure NWTRstep(a:array of real. comment array size is nxn (n = power of 2) for r=1 to n do NWTcalc(row r of a. procedure NStdReconst(a:array of real. endfor. j:=2. j:=2j. procedure StdReconst(a:array of real. j). endfor. j). comment multiply entire array end. endwhile. a:=b.Data Compression (4th Edition): Verbatim Listings procedure NWTreconst(a:array of real. n:int). end. n:int). j:=j/2. √ b[2i]:=(a[i]-a[j/2+i])/ 2. for i=1 to j/2 do √ b[2i-1]:=(a[i]+a[j/2+i])/ 2. n). while j≤n do NWTRstep(a. end. n:int). n:int). while j≤n do for c=j to 1 do comment loop backwards — 16 — . n). endfor. j:=2. Restoring From a Normalized Wavelet Transform.15. endfor. Figure 5. j:int). endfor. j). endwhile √ a:=a n. for c=n to 1 do comment loop backwards NWTcalc(col c of a. procedure NStdCalc(a:array of real.13. for c=n to 1 do comment loop backwards NWTreconst(col c of a. for c=j to 1 do comment loop backwards NWTstep(col c of a. end. comment move entire array end. procedure StdCalc(a:array of real. while j≥ 2 do for r=1 to j do NWTstep(row r of a. endfor. Figure 5. endfor. for r=1 to n do NWTreconst(row r of a.

dimg=sparse(i. end thresh=0.max(size(x))). % main program filename=’lena128’. Figure 5. [i. function f=individ(n) x=[1. y].[dim. end x=sparse(p). colormap(gray). end while min(size(y)) < n/2 y=[y. i=2*i. % inverse Haar transform density = nnz(dimg). p=p*q.0. comment multiply entire array end. colormap(gray). clear. The Pyramid Image Wavelet Transform.dim). imagesc(img). image(dimg). spy(dimg). zeros(min(size(x)).’]) disp([num2str(density) ’ coefficients remain out of ’ .22. axis square w=harmatt(dim). axis off. endwhile √ a:=a n.dim])’. x].-1]/sqrt(2). endfor. % percent of transform coefficients deleted figure(1). 1]/sqrt(2). dim=128.s.dim. y=[1. j). if fid==-1 disp(’file not found’) else img=fread(fid. zeros(min(size(y)). j:=2j. Figure 5.max(size(y))).max(size(y))). i=1. Matlab Code for the Haar Transform of An Image. for r=1 to j do NWTRstep(row r of a. colormap(gray).s]=find(cim). axis square File harmatt.. num2str(dim) ’x’ num2str(dim) ’. colormap(gray).Data Compression (4th Edition): Verbatim Listings NWTRstep(col c of a. while min(size(x)) < n/2 x=[x.y].m with two functions function x = harmatt(dim) num=log2(dim). axis off. imagesc(cimg).. q(1:2*i.. disp([num2str(100*thresh) ’% of smallest coefficients deleted. end f=[x. axis square cimg=full(w’*sparse(dimg)*w). % forward Haar transform tsort=sort(abs(timg(:))). fid=fopen(filename.’]) figure(3). — 17 — ..’r’).16. fclose(fid).. axis square figure(2). zeros(min(size(y)). zeros(min(size(x)). while i<=dim/2. tthresh=tsort(floor(max(thresh*dim*dim. % compute the Haar dim x dim transform matrix timg=w*img*w’..j.j. % figure(2) displays the remaining transform coefficients %figure(2). cim=timg. endfor. q = p.max(size(x))). j)..1:2*i) = sparse(individ(2*i)). p = sparse(eye(dim)).1))).*(abs(timg) > tthresh)..

j=log2(n). f(1:2:(n-1))=dt.AltrntZro(dt)). function d=LoPass(dt. end function f=ILoPass(dt. beta=dat. d=d(1:2:(n-1)).^(1:length(filt))). Figure 5.filter) % The 2D Forward Wavelet Transform — 18 — .filter) % The 1D Forward Wavelet Transform % dat must be a 1D row vector of size 2^n. for i=coarse:j-1 dat=ILoPass(dat.coarse. f =zeros(1. Code for Function fwt1. function dat=iwt1(wc. wc1((2^(i)+1):(2^(i+1)))=alfa. function f=IHiPass(dt.coarse.filter) . % coarse is the coarsest level of the transform % (note that coarse should be <<n) % filter is an orthonormal quadrature mirror filter % whose length should be <2^(coarse+1) n=length(dat).filter) f=iconv(filter.filter) % highpass downsampling d=iconv(mirror(filter).filter) % Inverse Discrete Wavelet Transform dat=wc(1:2^coarse). for i=j-1:-1:coarse alfa=HiPass(beta. n=length(wc).^(1:length(filt))). wc1=zeros(1. function f=AltrntZro(dt) % returns a vector of length 2*n with zeros % placed between consecutive values n =length(dt)*2.filter)+ . end wc1(1:(2^coarse))=beta.32: Code for the One-Dimensional Inverse Discrete Wavelet Transform.coarse.filter) % lowpass downsampling d=aconv(filter. d=d(1:2:(n-1)).filter) f=aconv(mirror(filter). IHiPass(wc((2^(i)+1):(2^(i+1))).filter).*filt.rshift(AltrntZro(dt))).lshift(dt)).Data Compression (4th Edition): Verbatim Listings function wc1=fwt1(dat. % aconv is matlab convolution tool with time% reversal of filter n=length(d). function sgn=mirror(filt) % return filter coefficients with alternating signs sgn=-((-1)..filter). function sgn=mirror(filt) % return filter coefficients with alternating signs sgn=-((-1).n).*filt. % iconv is matlab convolution tool n=length(d). j=log2(n). function wc=fwt2(dat. function d=HiPass(dt. beta=LoPass(beta.n).dt)..

if fid==-1 disp(’file not found’) else img=fread(fid. end for ir=1:nc. % aconv is matlab convolution tool with time% reversal of filter n=length(d). Function fwt2..ir)=LoPass(row. end function d=HiPass(dt. imagesc(rec). bot = 1:(nc/2).lshift(dt)).4. for ic=1:nc. fclose(fid). axis off.filter)’ +IHiPass(dat(top. nc=2^(coarse+1). if q(1)~=q(2)..filt). wc(top. bot=1:(nc/2). fwim=fwt2(img. row = wc(ic.ic)=ILoPass(dat(bot.filt). axis square rec=iwt2(fwim. for i=j-1:-1:coarse. function dat=iwt2(wc.[dim. % iconv is matlab convolution tool n=length(d). wc(ic. wc(ic. end nc = nc/2. n = q(1).filter).^(1:length(filt))). top=(nc/2+1):nc.dim])’.Data Compression (4th Edition): Verbatim Listings % dat must be a 2D matrix of size (2^n:2^n). wc(bot. nc = n.ic)’. axis square Test of Function fwt2.filter) % highpass downsampling d=iconv(mirror(filter).filter) % lowpass downsampling d=aconv(filter. function d=LoPass(dt. % "coarse" is the coarsest level of the transform % (note that coarse should be <<n) % filter is an orthonormal qmf of length<2^(coarse+1) q=size(dat).filter)’.dt).’r’). end. j=log2(n).*filt. dat(all.ic)’.filter)’.ir)’. imagesc(fwim). for ic=1:nc. all=1:nc. wc = dat. d=d(1:2:(n-1)). . axis off.8365 0.filter)’.1:nc). end filt=[0.bot)=LoPass(row. d=d(1:2:(n-1)). top = (nc/2+1):nc.coarse.filter) % Inverse Discrete 2D Wavelet Transform n=length(wc).2241 -0. function sgn=mirror(filt) % return filter coefficients with alternating signs sgn=-((-1).4. fid=fopen(filename.ir)=HiPass(row. dim=128. figure(2). disp(’Nonsquare image!’).top)=HiPass(row. dat=wc. figure(1). for i=coarse:j-1. filename=’house128’.filter). — 19 — .4830 0.1294]. j=log2(n). row = wc(1:nc.

end % i function f=ILoPass(dt. filename=’lena128’.1:32)/2. — 20 — ..0. function f=IHiPass(dt.[dim.54.AltrntZro(dt)).filter) f=iconv(filter. if fid==-1 disp(’file not found’) else img=fread(fid.03084. colormap(gray).1294]. . figure(3).3. fclose(fid).0. dim=128.*filt.filter) f=aconv(mirror(filter). n=length(wc).-0.filter). . dim=128.dim])’..4. imagesc(rec). function multres(wc.63088.33:128)=0. -0. axis square fwim(1:16.:)=0.^(1:length(filt))).-0. function sgn=mirror(filt) % return filter coefficients with alternating signs sgn=-((-1).1:32)=fwim(17:32. figure(1).01059].bot).coarse. function f=AltrntZro(dt) % returns a vector of length 2*n with zeros % placed between consecutive values n =length(dt)*2. img=fread(fid.3.0. colormap(gray).2241 -0. fwim(17:32.5:(n-.top). dat(ir. end % ir nc=2*nc.18703. clear.5))/n. fwim(33:128. Figure 5. fwim=fwt2(img. t=(. Function iwt2 filename=’house128’.all)=ILoPass(dat(ir.23037.17:32)/2. figure(2). imagesc(fwim)./max(abs(wc)). axis square A test of fwt2 and iwt2. fwim(1:16. figure(1).0.[dim. fid=fopen(filename.03288. fwim(17:32. colormap(gray). f =zeros(1.17:32)=fwim(1:16. imagesc(rec) Code For Figure Ans.33:128)=0.n). f(1:2:(n-1))=dt..4.. imagesc(fwim) rec=iwt2(fwim.Data Compression (4th Edition): Verbatim Listings end % ic for ir=1:nc.filter) % A multi resolution plot of a 1D wavelet transform scale=1.filter) +IHiPass(dat(ir. imagesc(fwim).filt). filt=[0.’r’). axis off. fwim=fwt2(img.02798.filt). end filt=[0.8365 0.rshift(AltrntZro(dt))). figure(2).34. fid=fopen(filename. axis square rec=iwt2(fwim.filt).4830 0. j=log2(n).’r’).71484. axis off.dim])’. LockAxes([0 1 -(j) (-coarse+2)]).filt).

z((2^(i)+1):(2^(i+1)))=wc((2^(i)+1):(2^(i+1))). dat=spikes(t).i. dat=iwt1(z. Quantization: For each element in LP./n. Figure 5.01 . 2. Go to step 2.filt). wc=fwt1(dat.005 .filt).82].01 . dat=zeros(size(t)).(-(coarse-1))+scale. Chapter 7 — 21 — .6 1. quantize and encode using ACTCQ.5 5 3.77 .^4./(1+abs((t-pos(i)).2. Sorting: for each node k in LIS do output ST (k) if ST (k) = 1 then for each child of k do move coefficients to LP add to LIS as a new node endfor remove k from LIS endif endfor 3.j in LFS. for i=1:length(pos) dat=dat+hgt(i). Update: Remove all elements in LP.*dat).3 4.coarse.01 . QTCQ Encoding. z(1:2^(coarse))=wc(1:2^(coarse)).005 .2.*dat). Output n = log2 (max |Ci.008 . 1. % one spike figure(1).64 .22 .8365 0.2241 -0. end z=zeros(1.41 . wth=[.filter).005 . plot(t. Set T = T /2. figure(2).006 ./abs(t-(p+. end. Matlab Code for the Multiresolution Decomposition of a One-Dimensional Row Vector.26 .61. Initialize LIS with all parent nodes. function dat=spikes(t) pos=[.Data Compression (4th Edition): Verbatim Listings for i=(j-1):-1:coarse z=zeros(1. (use TCQ step size Δ = α · q). plot(t.4830 0.11 . dat=1.n).n)./wth(i))).filter). dat=iwt1(z.39. hgt=[5 5 4 4.37). Set the threshold T = q2n .01 . % several spikes %p=floor(n*.05 .9 3. plot(t.wc) figure(3) multres(wc.79 . Initialization: Initialize LP with all Ci.dat) filt=[0.j |/q) .44 . plot(t. UnlockAxes. t=(1:n).14 . where q is a quality factor.1 5 4].5)/n).03 .-(i)+scale.1294]. a test routine n=1024.005]. 4. Figure 5.

ddist=zeros(512.12.m’ filename=’a8.Data Compression (4th Edition): Verbatim Listings % File ’LaplaceWav. Q[t_] := Plus @@ { ((t-t1)(t-t2)(t-t3))/((t0-t1)(t0-t2)(t0-t3))P4.wav file header x=buf(i)+1. for each subsequent audio frame: if layer=I then dif:=(12 × bitrate) modulo (sampling-frequency) else dif:=(144 × bitrate) modulo (sampling-frequency). Matlab code for Figure 7. end figure(1). plot(ddist).1). plot(dat*8159. ((t-t0)(t-t1)(t-t3))/((t2-t0)(t2-t1)(t2-t3))P2. rest:=rest+(sampling-frequency) else padding:=no.dim.1). t2=2. t0=0.t].1).wav’. plot(dist). ((t-t0)(t-t2)(t-t3))/((t1-t0)(t1-t2)(t1-t3))P3. buf=fread(fid. dist(x)=dist(x)+1. if (unsigned) { mod = lav + 1.’r’). for first audio frame: rest:=0. t1=1. ((t-t0)(t-t1)(t-t2))/((t3-t0)(t3-t1)(t3-t2))P1} Figure 7.’uint8’).128*log(1+mu*dat)/log(1+mu)).wav dist=zeros(256. } else { — 22 — . % many random numbers for i=2:dim x=buf(i)+1.1. plot(ddist). colormap(gray) %dist of differences Code For Figure 7.1000). dist(x)=dist(x)+1. ddist=zeros(512. colormap(gray) %dist of audio samples figure(2). mu=255. colormap(gray) %dist of differences dist=zeros(256. %input unsigned integers for i=46:dim % skip . ddist(dif)=ddist(dif)+1.1). t3=3. rest:=rest−dif. dif=buf(i)-buf(i-1)+256. plot(dist). % size of file a8.1. end figure(3). off = 0. dif=buf(i)-buf(i-1)+256. Algorithm used by the mp3 encoder to determine whether or not padding is necessary. colormap(gray) %dist of random numbers figure(4). ddist(dif)=ddist(dif)+1. % clear buffers buf=randint(dim. fid=fopen(filename.30. padding:=no. Code For a Lagrange Polynomial. (* Uniform Cubic Lagrange polynomial for 4th-order prediction in FLAC *) Clear[Q. dim=2950. dat=linspace(0.[0 255]). if rest<0 then padding:=yes.4.

1: R2:=(R1+R2)÷2. C1:=0. 2n ].R2. 2: R1:=((R1+R2)÷2) + 1.5 Log[2. off = lav. bit array M[2n .81. C1. } Figure 7. This is the rank of a symbol. The Decoding Algorithm of Section 8.27.R1. case ind of 0: R2:=(R1+R2)÷2.C2: integer). If this rank is > the total number of distinct symbols seen so far then Input the next item.R1. endcase.4^n/(n t)].N[0. C2. idx -= (w+off)*(mod*mod*mod) x = INT(idx/(mod*mod)) . C1:=((C1+C2)÷2) + 1. R2:=2n − 1. C2:=(C1+C2)÷2.off. integer array id[10]. This is a raw symbol.3]}. C2:=2n − 1.off.17. C2:=(C1+C2)÷2. } else { y = INT(idx/mod) . else Translate the rank into a symbol using the current context ranking. Clear[t]. Output this symbol.1. Decoding Frequency Coeﬃcients in AAC.off.C2). ind:=0.off.R2. This is a raw symbol.4. C1:=((C1+C2)÷2) + 1. (* natural log *) Table[{n. 3: R1:=((R1+R2)÷2) + 1.C1. {n. R2. — 23 — . Chapter 8 Input the first item. if ind≤n then RowCol(ind+1. Insert it into the table of sorted contexts.12}]//TableForm Mathematica Code for Table 8. idx -= (y+off)*mod z = idx . Output it.C1. procedure RowCol(ind. idx -= (x+off)*(mod*mod) y = INT(idx/mod) . R1. idx -= (y+off)*mod z = idx . endwhile Figure 8. R1:=0. endif The string that has been output so far is the current context. main program integer ind.off. } if (dim == 4) { w = INT(idx/(mod*mod*mod)) .off. end RowCol. t=Log[4]. while not end-of-file Input the next item. Output it.Data Compression (4th Edition): Verbatim Listings mod = 2*lav + 1.

main program integer ind. else output an A-escape. output W (perhaps coded). Figure 8.5.29. increment count of W. 1: R2:=(R1+R2)÷2. if ind≤n then RowCol(ind+1.R2. C2. 2: R1:=((R1+R2)÷2) + 1. Increment the escape count endif.. R1:=0. endif..C1]:=1. R2.R1. procedure RowCol(ind.C2).Data Compression (4th Edition): Verbatim Listings RowCol(ind. S:=empty string.. C2). M[R1. C1. integer array id[10].. case ind of 0: R2:=(R1+R2)÷2. until end-of-file. RowCol(ind.C1. repeat if currentIsAlph then input alphanumeric word W else input non-alphanumeric word W. . R2. R1. Figure 8. bit array M[2n ... end. 2n ]. C2:=(C1+C2)÷2.C2: integer). C2:=(C1+C2)÷2. R2. end RowCol. C2:=2n − 1. if W is in the A-tree then output code of W. code similar to the above . input an ‘‘other’’ word P. rearrange the A-tree if necessary. M[R1. end. Recursive Procedure RowCol (Section 8.28. C2). C1:=0. 3: R1:=((R1+R2)÷2) + 1. Figure 8. repeat input an alphanumeric word W. ind:=0. Word-Based Adaptive Huﬀman Algorithm.5).C1.R2. if W is a new word then — 24 — .R1. C1. R1. if P is in the P-tree then .C1]:=1. C1:=((C1+C2)÷2) + 1. C1. R1. R2:=2n − 1. Recursive Procedure RowCol. endcase. C1:=((C1+C2)÷2) + 1. add W to the A-tree with a count of 1.28.

n.% start on next region endif Figure 8.m=0.30. g. % append v to P g.p. H=H|E. endif.m=0. g. g=StackTop.WA).WA) to 1.o.o.m=1.31.o.o.n.N=g. set frequency of pair (prevW. g.N. input next alphanumeric word WA. % ﬁx link 1 g. output an escape followed by the text of W. endif. % unmark edges if StackEmpty then stop else PopStack.m=1. Word-Based Order-1 Predictor.W was found then S:=S.P. endif.P=g. H=H|C. Figure 8. % update ﬂags g.n.p.W else search P-dictionary for string S. add S to either the A. add AW to list of words. % ﬁx link 3 g=g. % ﬁx link 2 g. g.W else output string numer of S.o.escape) by 1.v. endif. if S.v.m=0.P=g. S:=empty string. until end-of-file. endif.o. repeat input next punctuation word WP and output its text.W.o.N. if WA is new then output an escape.N=g. g. % advance gate — 25 — .o. increment frequency of the pair (prevW. % append C to history P=P|g.n.P.Data Compression (4th Edition): Verbatim Listings if S is not the empty string then output string # of S. prevW:=WA. startIsAlph:=currentIsAlph.P=g.o. Word-Based LZW. Handling Case E of Edgebreaker. % append E to history g.n.45. StackTop=g.or the P-dictionary.o. currentIsAlph:=not currentIsAlph.m=0. S:=W. g. until end-of-file.p. output WA arithmetically encoded by characters.p.n.m=1. Figure 8. g.o.N=g.n. else output WA arithmetically encoded. prevW:=escape.p. g. increment frequency of the pair (prevW. else if startIsAlph then search A-dictionary for string S.p.