Предыдущий блок | Следующий блок | Вернуться в индекс |
— RU.COMPRESS From : Eugene D. Shelwien 2:5020/400 18 Aug 01 00:40:58 To : All Subj : cel500.png From: "Eugene D. Shelwien" <shelwien@thermosyn.com> e | V bugin 644 cel500.png MB5!.1PT*&@H````-24A$4@```H````'@!`,```#'_\'7````,%!,5$4````` M`*@`J```J*BH``"H`*BH5`"HJ*A45%145/Q4_%14_/S\5%3\5/S\_%3\_/S] M?%BS```IGTE$051XVNW=.X_K1MHG\+\3E4@VH9[$"N>K*7+;ZQFX3N+GO)X% M6IO8\N6@&1F'@0%&8^,`"RCRV&_U`AWM>M$,%'D-#(C^"MK$IY,%-R@6[Y?B M11*IEHR#EG5M_;HH5CW/4U4(+I<^EQF^W2*ZK%?Q-74%\X[79HV/2[U)[MJL MY%K-,V;R8?(V+W/O:@Y@%;WQ"L`,J]5<W=3F(\WD"\6O]Y%ZDQG6UO9\`$V< M`!"6N`#V`-QL-ANQV6PVF\W'F\$N7P[RW"_U'IX\[*?L71^G/]7'F\WFR\W' M'W?ZH%\FS_IXL]EL/HKOD)+B3%J@=Y)#6`E.']#$R0`A+H#]`+$]`T#OE(#6 M]@+8"Q"6F#J@B9,"8BVV%\!>@"LU*)DFH.F='!"1X"0!O_%P>L!(<)*`'L8` M*`?&4P0TU^,`!,1VDH#>:`!A;2<(:&(\@(@CA!,"],8$F(I27P`[`291ZJD` MFA@78'P47P`[`JHX_U0`O=$!`F(['4`3(P2$M;T`]@*$M9T*H#=.0%AB&H`F M1@H8I>M^B-%W`N)@!HXI2`^3QT_B)^&7UB_9]5=QTOL5[=`N.1\7A;H#G# MB`_A.+8P7D!O[(!2<+2`)D8/"$N,#3"5__CG!``!,2[`5`+)G$T"$.("V`\0 M8CLB0"\!]*8".%>%K"<'--^]6YMQ6\1D`.-QW<D!@1C0]*8$"#$Z0&\]*4`I M.")`$Q,#A/CU`M@+$-:O8P+TI@<(Z]=3`WK`6I82F9@@8#POY_2`IC=)0*T@ MZU$`/4P4$&(4@"8F"]C<I3X"H.E-&!!"G!S0PY0!92,\):")B0-"G!30G#Y@ M;9#U\(#>]`$A?KL`]@*$>#@=(,8"V)18K[V(WXZ?6/^F9L;Z*!/K]5UJ<?06 MF"]EF_(A7!UDO0#JYS_$!;`?8&F7^@+8`A!B>P'L!5A2R7H!1+OW$!?`GLN> MB`M@SV5/5.G'"P;L>4G-\=2Z=`7TSA6PK>`Y`1(1!^,`\<QGI.C_"8"\G^1U M^1P09QQ$("*`P?H7$0B,DWQ`_(_.'9!Q)@%9%C"B@`)A7-TBGY/^#\1AB7]Q M!9B^[P4`@D.ULM1/!<LX5$OBR4-BG/@:X]96,@,$</4O]W<Y1\#H\&4<C*@. M$%E`=9OD8YS]XU\)8/Q/-F[Y3/7SO``C/#`.2AW'\8>-%"@^G@%&!$;R-A9] M]S$B_.-?\L8T(&@XP,*\N-&TP+:`/`)D)%LBD6QYUGTI((C4V0=G"(@$D*@( M&.-FOQ_E(9Q\`\I#U[I_B!Y+J3,X$47GHDBP(Z`W>L"2DPB2ALBS@/%W7PJ0 M_4/\+YXYB:@NT``ML#BQ<'R`+(6D3BCR9W)Z*'9C4H`<XE^9^Q&UT^0U.@-Z MHP0D2CJ^C*C0D5:`T0/E+9QQV9'FG")`H@@0_]BF.])G#]CV$G^/]1G7=0(T M\5(`FP4[`7KG`:@76[@?'M#$^``WF\WF4((/%?=T3JS_U+`4_&D3Z\-<4@%5 M2Y5^#!50-8'S/X0S$>DH3#T4H#=:0*(D"L,H'<^20085%RR+JN1"+=F0?O5R M`1T`WV&L@)DA6SK\21PLCO`5K%"FFLN)5"X7T![PW7JT@`2D%%+A+.)1A%E% M4DH:8#U@Y0I<K0'?8=2`($:RQ:7B@7)H1YRB9J9::CIBDV!3>5;.NA\$T,3( M`1G)H58F@\%DN(I8#I!3`5"A%M.:UOUO9P_(B*NQ:@&0&"=2AS!E6EL6L/P0 M!F"55;*V!?3&W0*CME4&J((&Z>^[]/=>TR$,8!XON-`9T,2D`#/?@>F32'4+ M1.4A#,Q+UF1M">B-&E!%[:+OO`Q@MAN3^P[,!%OK`(LK<)T5((AS%1-DE#K# M$N4ZTKFS<"K27'L(EW2IVP&:?@H89RZ=LL<0'L!9B;'-8.T+L`2L&.@.]P M`92"W0!-G"E@^\F&HA.@=P%,NM0=`$V,'3!=C9!+'O&XX"CJOJ0?V66Z:SRL M.R=`5EZ`%M6U)/4R%`_JN@-"^&T!O0D`@I=%F2D>_T:`-``@Q/T9`LHA'%,C M$06HRMY4-0(19[*DEW<'C);NT08T,7Y`XF"D1KVIT@X56%"@3(Z:HQ*D[E/^ M11M`#Y-H@:I`*%L2'K5&55BEP@X1:/<U$\3Y`&XVFXUJ9$14"JB^]V)`TD^. M5\UUUTZL?]-BC_53)=9CP/1ABZBP+U6U2D@*UOJUP/2BM@TMT,,4#F$%&!W" M\5F84`:HLGB]ECU)]EZK!337$P!497PL5Q_(2,;[U%E7=J09[WD6CCYF7+]5 M"^A-`;"D^WRHH5QZ+*SJM^H`35P`JQ/KUGT3H.E-#Y"5CXL/`1@)U@!ZF&`+ MQ-%:8&$[XSR@B2D!]IMPW0TPMYWQ!;##C/7T=L9Y0.\"V`R8+D?/`9JX`&H` MXMO["V"_=6/B@OX<X#\O@'J`V2YU#&C.+H":@&IY]`M@]W5CQ+8`Z%T`6P#" MVA;2Z1?`-H"PMMEDIG<!;`>HNM1)+NX"V`XPZE(GN;@+8$M`&:5.4DD7P+:` M:TLXTN,;7`"[+7\GG"25=`'L``CQ_;0`RV<0#G'IN@"C@,K%30.0J"4,:3VD MQU+P0DU-U]QC_;2)=18O$J@!$\TAR:\WF)F@"$37NR\!NHV2F>-O@<8L7H&C MJD:PT+34VB_Y238#`EK_B8D`.K/LLDXZ@%1<;Y`*7Z34"_!==DPR&4"YC!TG M$*-4O6#VGP3DF?4&XTK6J'ZP)Z"IPENC!S20!93+-\FIKTF]8/I?!)A;;Y!% MR^/)J8JJ3*D/(-9B`H"&4P;(L@N*4?H^I%I@9K$RRJT_V`O0`[#&=O2`AH-: MP*2D5Y7U)H#(K3>8%&+*_Q\`T-J.'-!PD`/D!<#X3*%:8@E@ZBR</*</H,K% M6=LQ`[JNDQV))(=L=M6_S#]&<6-+'[(4%V*")UV:KH!Q+L[Z>;R`1G$HIP[5 M:#'9=+U@\B^"RJTWR-2"V^HLW`<PE4JRMB,%=,H`D>L']QS*=09,I9)F<9YD M7("&\;W3`_"PP00S4]YF;4<)B$_JHS&MXPL#`GK9"M5"Z=$8`)T1A[/,?(VT M]>OH`(TQ!U2]PC2';W\=&:#AC!@PFXN3U^(V.`[`3QQ,##`N(!P%H.&,.B?B ME0$JP3$`&LZHDTJY9&9\K6Z"[%$!#6?<63FO`K!N@NPQ`0UGW&G-?"XN'4P0 M8P!\BW$#>C6`$*<'=$>>6#?K%Z$5IP9T,6U`B-,"N@?88[W[C/6RRT]-2\'? MGS*Q_O5!]E@?M`5Z32N9QZOSGZ`%&LYJ[,5%9O-N#FHYV^,#R@[@N`$]G1UM MQ`D`70>N,_[R-A-:NWJ)HP.Z<\.=0GV@IP=8&),<&M#M4&!YBHNI_4AQ/$`7 MAHN)`'IH(7@D0`.N@TZ`3/WDV?U%D*PU&*\IR)%:=YHJ-AU!<G_\),0IU$I` M1J4IA\RB/0<$="IR(LV`"B&_OPB0680G?DC\(:DAQY+:^`5(KY)N5CZ^[/72 MB_8<#M"`#J";NSA(EGS/?.BD610!FSYP#6#T/U[MX_.7]*(]AP-T.@/&91S1 M_B*J;I"E=S9$:J4C2M8?C&L&4X>^>F[\^`P@Q0U0/2];CZA>._6728?YAP=T MY347O0#3^XNHND%*E0\QRBZ'%V_7'-<,)A]8/5>]5K$TV$N^$WFN'C']VBFB M.,P_.*`+UX7ANN@!2-G]15355J86FB6[6Y<"IFJNU7-+`9,&F%[<#$V`D>#P M@$8T^)BC9PN,3@Z$J#8P#YC:C+X`F%MK-0.H*OS3[^,E+54;$-;#00"=AK1F M)\`40GHUR^H6F#V79%L@D-Y^E\!X#`A59J<#".%/`I!1IDXP"YC[#F3I0[C8 M75&OE934R<>:F1995H]8"@AQ/SR@@8$`T_N+I.L&LYO4D]QCA**/3M'UJ+XP M<ZBF7BO9"%`>MF9J6R'Y.JEZQ-1M!2+KUX$!H[K3OH"#732KO#QJ^6(QD?7K M@("NZPXT6_/(EW=Z?&6`^/;7P0#=YK3F.`'UXC"990W38?Z?!P)TT1;0WB$8 M`Z#7_BF9,/]V"$##16O`G1W@#`!GLIB_#Z"1?/6W`+1'<@B;Z`D8CTDZ`SI= M)MH$NY'$`W^DXOT-\<!\0+5J.H0FH-%EHDT``%B4)]:/&0]\EQVSU,8#*V>L M?_M+C\3ZUV\[S%A_L]EL-IN[YR_Q+G?QCAL/_`)-@,V'\`P5TR&T6J#K=)FI MM%L#6.PQ*P4\8CS02R.5ST\NC0?F(])6-T#7=;6"^WG``&L@W*,&\$CQ0"_= M`./WTH@'YB/2H@N@JYNIS0$&'V$=AO(D4@IXM'B@R3-;NL>`6M&8;#QPVQ+0 M<#(QYS:``3Y"J$8BE2WP*/%`,_LX]5Y=`$MVAZ@#-!S#13=`&_@H7+<"/%@\ M\,?,@A7Q>W4!+-D=HA)0]IP[3K2Q=T`(?<"#Q@.]["&=>Z^F>&`N(EV83U(% M^(FCQU8*&.R`\*-FP*/$`TUD#FEUOW8\,!>1MAZT``T'W0%1"B`?!H\4"S M3=RP&3#:-K$!,)HKTPTPP`J+T82S3*_-WT(#4`K6`ZJY,IT`;6"%_6@`V[3V MJGA@+B(M&@'?]I@G8N^`U6(T`56S\S.K`3/%;V6`G_28)V+_`3G^.&=`;&L! M/W$Z`_X]V,VQ"$<4TO<.`IA:)*`(:#B=YXG8.V"^V(^H/M!4W1M>^WB->&`N M4W=?!6BX3O>)-KL5,-^/J3Y0=J)9[1.Z`";[D^0!G1[S1&RL@$5)5L[/71Z. M%0\TT^5M+3N2]8#Q_B0#`MH[K,+P61/P*/%`K[CR98OZP%I`-:C+`1K=)]H$ M.R`LSPM7`1XZ'FBJ5DR4^7K0K0^L!8P$,X"?N$Y70#N8`8M5"\`CQ`,]9$I\ M<X!=HC&9>ZT\8+1871?`8(<9%OM5RQ9XX'A@*6"K^L!:0(@LH!P`=P(,YL`, M>_0!'#X>:*;_!.E3QE"`$&E`XVW7F4I!@#DP"]$9\##Q0$]UE]);CK>M#ZP% MA$@!.EVG>@4`Y@A#M`8\;#SPBZ3#GLK2M:X/K*]0O8\!C:YSY0(`F"_JJK/R M@+]M-IO#QP/-=G'#Z$$MEX+_]EXEPM]VF['^)I`_GYOV6#_^6-CK\+=HW0+Q MZ3VB]?XZM4![!P!8A..K#^P0A]&,!V8CTI8`5C"<#H#!//(+]R,LL.R;-]`% MG$/(Y>I:`P:0U5>+<)05JL<#A)"E?RT!@^C:8H\Q`IHX'J`KY\:V`PRB:XL] M,,;YPEYVOC`OQ`M[Q0,S@`96UK8MH`T`81B&>W0$/&P\\%VF?]BB/K`]H.%@ M!6O;$G`'(-2MT@]SE_W!XX%FR737&L!>A[`#K`!KVPK0!K!`'\##Q@-_K-P) MIT=]8#F@$7U@ZUX?T`YV`/:]`0\6#S3STUTITUGN6A]8"ABO]V?=/V@!!G_( MWE^(?H"'C`?F`0O560-%8X#4>G_1HE%-@($<?2Q"H'\+/%0\\$>J!^Q:'U@$ M=#,1:;%M!`QRG9?A``>,!WZ1.O,4XX%]Z@/S]QJYG(BU;0"TY;7%'H,"#AP/ M_#$W7S@3#^Q7'YB[U\DGE:QM/>`.P%QU_OJ?A0\4#_PQ-U\X&P_L5Q^8N=<M MIC6MG^L``T!F?OL#'C`>:+:+&U8\2`/0+<D+P[JO`K0#.?7HN37@D<?"7O>_ M11M`.?VC6!MCW3^4`MI1Z"4<^WSA=YV?V2H>:)17)F"&3\5O)8"1WW[T$Z[- M@5ZG"="I!%RMQ$,1\`\`\MMKY(#><0`-U`#.A;\J1)^A)LY<``&LG5I`"-_W M?3\]_IC'9]^!`%O&`^.O)X;::(Q9OGX@KXT?M@UGN?@:]8`0T<5_``(Y_M@/ M"]@R'I@.!]8"ELP7'KH^,%IULA90'<)"B/\A`B<:_'8$%+G+MD,\,`-8>P27 MK1\X;'V@T6Z^L`TA1/B,X0!_V6PVNO%`0G7\+L,@GVN6KA_8HCY0)['^MMV, M]3\VF[M0W/N_==YCO:P%ZL<#DYTX*15%R&\W'CWWB_+E[P:M#S30I@7:@>S] M64*((0]A_7B@)J!\KE<*.&Q]H-,",(ABSQ)&&@X$J!T/[`!(-?'`_O6!+0#M M>1P]B+`2@:$!*^.!;0#-TO4#AZP/-!P#^H"[BN"I)83P_[<[&&!M/%"%N]1] M26PPNQ8"XV3^6+I^X)#U@8Z<R*H'&&".1;@O_^93&CT`]>*!4=%DG)&+]APN M`60_EJ\?.&!]H%%6F5`.&`2!G'?4D"$60G0!/$0LT$3[[E[+>*"C#1@M.[1' M$V#<&$\^%FXS-;AC/-"`+N#?I5]C]SGU'2A.#=@[C-`<#W1T`>V=C%ZUFNHE M3@MH#OMR98!?0P_0#G8K&;UJ-]E0G#N@HPGX!^2R!ZWG"XM3`GH'!W37>H!_ MGP.KDMZ?1C!!;$\6#S13\;VZ>W^D!#;_&Q(-C-$5;U_IJ&<M8OIXH'>KFN MR.#U@8:C!6ACM9HONB\Z86V+@$'NLCM$/+`&<)#Z0,/16\'R=ZQ6\WV/94^L MK1;@T/'`+^KV$^E?'RB7D-4`M&=8K<)>.UQ;][J`0\8#OZC;3Z1W?:"KNPRR MO9OAL[#G'NMR>\HFP('C@3_6[2?2MS[0T%V(V]YAMMCWW:0>GXH'O18X7#S0 MK-M/I'=]X/>:@'_?`8O]JC?@"F+;&K!?/-"KVT^D;WV@H;F6OKU#&/Z)(0!A M;=L`]HX'FK7[B?2M#W2T`(-@MUKTWV-=O9[UL\99>+!XH%>[GTC/^L"OM;;# ML#'':C\<(#Y]J`4<-!YHMGALZWB@X6@![C!'B`$!/XHV.C[&6-@;ZN]1!NAH M[6@3`/-P-2A@M-9CQ1[K8XS#,.+%&>NNSA[K;X+-9A/VWF,]GU@7OQQGQKIW MB!>-?FE79U>O8`=@T7N/]6)$VMKB&!LT>]#>I%YO@^;DF@L-P&`%+,+]`0!A M/1P!T,3!`%UH``98`?O^F]27)I7$PY0!76@`!BK\?!!`B(>#`WJ'`C2@`1A` MA9\/`PAQ:$`3AP)T-`"#.:)%8P\$Z-\?&M`[%*"!9L!@-0?"8EIS,$#?.O1W MH(D#`:K5W.L`;:SF6.!P@+ZU/32@=QC`U`:6-8`[K.)5=P\`>.7+";03!'2U M)AL&P&?A'H<!_'3[G2S=.BR@B4,`&EJ3#0,`^WZ;U-<`_FR)NF#"J`'S&;AR MP`#`8G4H0,M/PED'!(RWUA@2T'"@`1@`BW!_*$#KOB&Q/@S@N]K'=03,U:!6 M`$;%]P<"?-SB&(#F_!"`#C0`;<CB^X,`^H];3!?0@`;@FUTT^?(`@):LX3T& MH'<(0$<#,-BIN6_#`XIB:4?]6E>ZER*@B0,`NF@+!6Q<\#`UX]B@>T`-3( M]%`UH'<`0`/-@`&PWN,0@)^*^]]0#<A2%0/R!IY4$5#\&.0?<T3`KYUF0!O` M'0X`Z(MM>85J'6"<WZVHIJH!-#$X8!Q`J`&T=RI^-3"@)?Q5`R#C/']X,@Z> MAJ+"\4Y5@-[P@,ZZ"="6YX_U\(!B6SG-(:FVDH=J7`=(`./1X:O6!`3D8XAX MNE:P^+XF!@<TT`BXD_WGP0$MX4,/,/K>4S4P+,)+U@1$U"PI5UUZ!$!'"W"/ MP0$M<>_/6@"FJK`8SP+&1=_J_ZN69]_\<]/]\F7)-9E#;YBQ_F:SN>NPQWK# M1=S[O]7-6"\%).)Q?7>J94*=1$A5ZU>T0',V=`MT*Y\1M\!@%\U^&[(%6HV3 M#<M;(%``3)V%DX.W`M`;&-!PT02H9N\/"BC$/5H#(JE$S0(FMQ.0JU8]+*#A MH`G0WJWCV9>#`0K?ASY@5+<7UP&J^N_H]J1JGI*S<`6@B4$!#0=-@/8.Z[C_ M-Q#@U6-C6A.8@8AHZ*&<-RA@*@-7!6COXL6OA@'T'V382@.P=NFE;L$$$T," ME@_@,H#V#EBLAP.\\B%S;CJ`(,+`@-Z@@`Z:`.T=@/UP@.(!0@C=12>V>9 M&!+06#<!VK\#"#$8H/507$&FY>)C_0*JWJ"`3A.@O9MA$6(P0'^KD=8\).`[ M#`EHH`GP=\P6>PP">.7[OB]P6D`30P(:3A-@,,N//SH#7CW(D<=I`7\:$M!U MT``88+;X$\,`"D#\@C,"K!O`*;\U%OO9,("/$&*@%2Q[`)KSP0`-9]8$&.`N M_!,#`/J^+T\>YP3H-%7IVP$6>\P&`/1A)>MDG1;0&PS0:*K2#W;`?CT$X&.R MXM6I`4T,!NC4`]I!U'WN#7CUN.U<9#YB0!>U@'+Y)O0']/W'+<8#Z`T$*$_` MU8#*KS>@#Y7O'06@B6$`#6==#ZC\>@'ZN(K66!P-H#<0H--0I1\HOSZ`5_/R M8=L)`9-DYF$!@W4</^T!^#`7&!F@-PB@X1CU5?H!UO'F`1T!?=]_%`(C`TQ- M+.P#^'U<1EX.:",I8.L(Z$?;10X!6#9CO>/EITUI2KSMY?OZ5WGSQV9S]ZRS MQWIE8OTQ6O*^UXSUNCW6.[9`;Y`6:#1,<]BEZZ\ZM,"K.%LT']DAG)Z9V0/0 MJ0<,\N'[EH!_^\W:KLX9T*VOT@^B\4='0-\7JLQY?(#>$(!N;8VT':CQ1S=` M'V+8"==#`F:FMG8%=%$'&.?/.P+Z,VMUWH`N:@%WR?BC`^"5;XGMB`&]WH"& MNZX!#!#$>Q]U`?S;0]/FI*<%S,[,[`)H.'45J@&"=/>Y->#50^/VN"<%C-?* M[P[HU!58V@#N]N@,Z#]H;-!\2D`/AP7<I3=?:`UXY0O1F)4[*:")WH`&:@!M M8+%?=P7T'\6!UHT9#V!J*>,20'L'[-$-\&^^$%N,'?"GGH!&,:F4NA;U_SH! M7CU8C5FY<P=4_><.@#X>5ML)`)KSGH!.#:"MYO^V![S"8YPP'S6@UP_0=5$- M^&97F+Z@#?B;6OM^Y(`F>@%^7<B)I*_MU-YE[0']>/>%D0-Z_0"=:L``P7I? M'[^I!+SRQ2^8!*")7H#NNA+01I!,GVX'>.4_B(,MO#,PH-<+T*TIL*P>?S0` M^OX#!%X$H%M3H5HS_J@'O)+E:A,!+)L;K`UHH!K0_AV+/;H`/EC;RJ32^`"] M'H"%E;`RXX\PW*,+H"_])@+X#MT!BRMAI<<?B\82WS)`WX]G:1T%L&]B_9N& M6>>UE[?5SWWSQ^;Y2[V<=^9AWVV^%8/.6#]T8MU#]Q9HE+:L&0`$.X3HT@(? MK&UU5FZ,AW`?0*<2,%@C1!=`W]IB4H`5Z_1J`;JH`K2Q#M$!\$J(+5X,H($J M0/LI#-$!,"J8G!2@UQFP<B+US-[MM79SR`%>J8+3*0%6+3/;#%BQ$A8`>[=` M!\#O'@6F!^AU!30JYP';O\?+-[4!O(J7.)@2H(FN@)736.U=,ONW!>!CLL3! ME`"]KH!N%4>PD[-7VP%>/6Z'F_)_1$`3'0$K%W(*@/VL)>"5[S]N\:(`J^8! M!P$RXP\MP*N'F=ABFH`_=0,T*CALW(4AV@+^3R$JDTHC!S3GW0"=B@\L3Q\M M`7V!V40!3:\;H%O!$431YU:`OIA-%M!#)\"*$;`=+/9H"WCE"TP6T$07P#B' MGN\^[[!ONS&?)818OS!``Q4<.RS0$O!Q"V#"@%X7P+<5@$$8[ML!1D.W%P9H M5!07!8NRK%P=H!KZ3A>P?J'C<D##*0<,L&\%Z#]<J:'O=`&]#H!.>6U,$*\^ MJ0?HXSM1G94[8T"CO#8F6(=H`^@#`I,'--$>T"D#M(/\ZJ?U@%<^++&>/J#7 M%M!P790`VKO"ZJ>U@/X#Q!9C`NR66/]&>SGWVASZ9O-'9O9YS5+PF\UFL_'] M5-J\^XSU$236/;1L@48Q*R?/'\7RH>H6Z,M]*8#)'\(FV@(ZI8!!=ON*!L#O M($1-5FY*@%Y;0!=E@-)/&_!1U&7EI@1HHB6@@3+`H'SUTRK`QRW.!=!K"9CD M@%.`0;`OG[Y0#GCUN%V?"Z")=H#NVY+'!>M]8?>%&D"_/.\V34"O':!;]CB[ MNOJ^!%!DBX9>%J!;^KA==?5]$5`\U"25I@=HH@V@4?JXH*;ZO@!H/>"L`']J M`V@X)?<&0;C7WT]$+6Y_+H!FBTWJH_-O[EX;>VAO1A`7K;U(P*C_DKMWMX`V M8'J5OS,!]%H`.B7WVE'\60>PNO,R74`3^H!&R;WVKF3UH7)`N2W/N0%Z^H#Q M`"1UK[TK6WVH%-"78]^7"U@V@)OO2E<?*@/TQ79VAH`FM`%+!W!)_[D!\%%T MFB<R>D!/&]`MN3>8[Z$%*-.69PCX#KJ`1MGX(Y4_J@7T14U6;LJ`IN[[S@RG M>&^`4&LA[BM?X$P!/6U`)W^;'02+4&L=:?]1X$P!3>WW=0NW[1#NM5;Q]9.* MYY<+:!222K;\^FL$%$*TK=*?$*"G^;YR.ZG,;;L0&H#?";]UD?F$$NO?:&:A MOWY;R'4'H<X3OWML2*QKS%@?<V+=T_MS&4XA*Q>$95FY_+6HYN]L#V%3\]V< M?%+)5O63]8"/8KL^:T!/[]W<?%+)3N4_J@&3Z5KG"FCJO9N13RK93^$SF@"O M2CLO+Q'0>)L##)XT%F"\>A1U6;GS`/1TWDU50<>``?;-@*F*YQ<.&(^`%:`, M'S0`?BMJLW)G`JB3#3:<7$ZD,/XH`\S/-3]/0%,G&^SD<B)V8?Q1!!1"O\!R MRH`:N3@Y#2X%&$1^U8!R4]J7`*B1BW/S(?U@$:(!\/X!+P2P.95DY$/Z05GW M.0-X]5B;E7MA@$X.,,`SZ@'C[<E>`*")MH"9\'W9M629Q)<`V)R+RU5!!PAK MGW'E5]>\G"&@"?V5L&3]U2*L?8;_*/3+VUX"8*X*VG[ZL^X9#34O9PCHH6DA MI\QMP=.^9M&)JZ::E_,#;,H&&]G;@L6^9M6.JX?HY/&"`#W=$;`,WR_V-:MV M7#V(6HZ7".AD;K,7>]0`/C04[)XC8$,VV,C<9C_M40/XV%2P>XZ`7OU[..G; M[*=G5`)&&WR\-,#ZJ:W12D2J?.AI7SWEWW\46K4QYY98KTVGN[GT^7-U2OQ1 M=UOS<TNL>]H#N"!$Y83K:.0[?WF'<&TZ/3.`"T)4`JK9,B\/,+=K:_::FQE_ MA*@$C&<;O3S`NER<D1E_A*@"])/96B\.L"X7EUX)*U\^E`!:]^G(U8L#K,G% M9:J@8[\"X'VF\W(!+!L!VT'BEP>T'H`7#&AJC8!WQ?"]`K2V>-&`GLX(V"X) MWT>`4>3JQ0)69X/=U`CX*:R8;"A$;5;N)0.FD^A!V?O.`$O4_E8O`M#32*(' M^W+`Q^W\Q0.:S3E@.R@O'[IZW.("Z#6&$.RG\O(A_W&+D0%2%I`146=`1KT` M4SE@&7XNYMW$SQ@9X"(/R/NT0#W`BFRPD>2`@WUIWDV(UIO4'QSP]@2`7M,( M."@M'[($T`OP%2?0>PZBSSL!LCUQ$('QY6L073-BC,^Q!..O^&IYR]DU<4:D M#;C@]#GC=`VZY:!KT@1\US0"#O9E[R;[SCT`V>>,,[XFQO&J6PM\#P(8!ZUN M&<<2Q(CF=,-!,[JYGA.6G!AG7+L%$EZ!^)+Q.3%^P_4`S:81<+`O>3=+=-BD M_A"`1"E`(IICF0($`:!V@&@)6)J+2ZV$%92,/RRQQ3"`]+X?(.-1"R1:@@BT M8%$+7-X2ED`'P%4KP/)<7#R`LX.2Z0MB"V"H%HAA`#E66<#K.;`$V$D`XQ1F MU/_+=EY$=4C_Z(=P"G"9!R0L@?;?@2T!RW)Q\5K0]E/QWFS:J-=9F'BOLS#> M$P=Q`L5G8>(+K`@4G867'&AQ%IX3?<Z(K^19>,G!Z,,FP+)<G.I`SY5?ZMZK M7-JH5S^0\7[]P/?13U+]0(J&<M1Q*$?I?N`-AT9B_:>:#='?/!7N\A]%ISW6 MRRYW?]X]]TNLJ]GQH4JLA^IGQ\1ZF"36[YX_>]9)K)<D,UT5OW\JC#\>4S4O M0QS"_48B[#V7/^E:MD!&''.LP.CS3BUP03QI@;34"2:43&U5.>#=HC#^$-N. M>ZR?;S3&*[R*6@G+7N3''Y8`+H!9P&^*(V"5_WC*CS_$%A?`1D`U`K:?]ME7 M?A3E[UL&R"BYC1'6(.+#`LK78WM&U`28_F7T`5]K`GKY5W'4](7,*UOW\?X` M6BTP_3L3UHR#A@5D$2!%UX8&9)J`YCKW*JX:?V1?.?'K!"AO&1XPN58#2(<$ M]'*`1OGXX['MIE1$?$[$9:0$[],?N#\@>T^0AR[MU5]&`A(CL%N^(D8SMES. MB2VU`8D1:$'X@`@WQ!?$V9*#Z*,HZ,C+`,U<C72TF+:M^G_1>]2FC2I:("TX MB'&0!*0!3R*T9IQQQ@&V5W\9"<@XXYC3BG'V.:UN7C.ZX8SK`3+..+ME_!48 M7X*_)O`5`>Q#.>`&E0%Z.4`Y@@MR^0^Q12_`Y&,>`)"0`V2W*4#>$O!U&I!6 M!"(%6'8(F[D27Q<`%D&8'G\(6730!Y#6ZF,.#ZC^,@D@J1:X7+YF?`5"&T`@ M#0C&90NL.(2]+*`<@?R_S"L+O^F[5Z<%#GL63@-FS\(9P-5JSO@*1,3[`Z+L M$#8SOU\T`K9WZ5=^?$`W0)[Y#CP`(#4#WKQF?)7K$N@#`OPZ!BS_#O0ROY^A M_-*SC;;H!,AX<A9FA/>,B(8]"Q,CV0^,NN@1(!'8+;MF%)V%:84HP-`,2`2Z M1706IEOBN`:(_Z7R$#8SOY_,`=M/Z5=^_`7=`(\SE&.<[;-#.<9E/Y#Q]D.Y MZ+E1/Y`TAG)>YO=SBN,/L9V_4,"E#J"9^?U<S&$'Z?&'$/I+P9\HF$"4"R80 M24"B]H#1<S$#<$.\&=!+_RXN,+?3JP]90C>(\6*C,2E`PP4P?TI-7Z@IV+T` M2D`S^0WD`,Y.NL^6`"Z`^H#2[P]UYW]-%JF;$T=3>=.Q`-E[S#`#`:0/R):R MEU/XM1C7K<ZJ2FMZ\6_@ROZ?>A5?O$Y>CW'(X.4(6J`"9&T`Y8FY!R"K`#3C MW\``$`;Q^$,(E@-DHP+,G'LU#F'J>0@W`AH.8`=)YP5@MS+<QHCFC#,^AD.8 MB.,]?8X9JSZ$B2W!B..6+<'H%98WMU%N//MK$2.`.!9$I8!)?>`2(/J0O6=1 M/#"=6/\IE4-_\T=\N]AL-G?/=\_A1OZ[>[Y[+FZ-/E1B77O&^MWS)MR$F_^[ M^7(3)MGTW(QUF0@/-W?/GSV'F__V_-E?[YXW?PU+7DQ^IK#\@WVY"9__>O>\ M"3>;SY[OGN\^O`O#\.YY$V82Z_\EG0..N\_R[,M>,TY@G*)K(VB!3,:U7]6> M1!B_X8P("W[#"1_PF^L%1\EWH#JJ;JL.X:@^$+3DC+,/V9X7@PDJEV2LX_+G MN16=?3.`Q"<%2(@`Z16_N9ZC(^"*T2W):&P$2)0!_&:E<ICKN'P\[KQ,N07& M@)BA%R"/6G32`C,G$6^E<L#KR.]*Q*_";M.`HSB)2$#>!O`#?G,]![NN`U3A M[%+`J`72AVQ?B`>^D_%`PXF/7S\U59H6R5F8..,-::UCG879GCZ/^H'[<D!: M@A'C"XK.PLLYL"QV8Q@10%1]%H[K`Z\)Q/_"]OEXH!D%5&._1]W(R\F'<J]` ME4,Y&7X&%KQ^*%?:[EH-Y3P)Z,(.]NLX[GP!U`4T933&@/VTQSJ.VT\"\`/B ME8!$4BL_4ZG0D:9!``W'?@*PCL^^DP`<133&`]8K2+_4]@H70$U`$\!ZY4J_ MU/8*%\!&P/<<`/-`?/T)G@!D5B@^,\`/:)D"O*4A`+_B`$P.QK]V@FAKLK,% M?!6-1*+!%08#]`#V'TX@9[N=,>`L#4C#',)?$<$D#N.'8!6MDS-&0&*$KXA` M8)S1>PU`8K1:$,>2$1A>TQ+@,[I>SADM9=W?+6\#R*Z)+SCQ%1''7_A[QHG+ M%LBXR;CQP^ZKZ\AOC(",,_X>:CS^%6\&9)Q=ST&XX8P3NZ4E,3;#ZN8UX88S M8IQ>M_L.7(+FQ.F&@]B'<BBG`#WV'S_\'_Y5R?8*XP-DC)/6(<PXNUY0&I"S M&;^.`#GC-%?#CQ:`*`/\`L8/3TR(:XP<D(@3TSV$&6?7MZH%\@4M&>@#NKYY M3;3DC`/=`%$$-#W\\&0)_M7H`0$08QS:AW`,R%ZS)0.]8LOE:\(*0P+2C]Q] M$EM&$P!DG(A:?`?>IK\#$\`;68C9Y3NP"/C>)#<0!&+O5R,'_(JBD*[>(4RT M6A#C-T1@?$Y+3NP#OKJ19V$"T.XLC"7Q!7'(LS#MY3RA&=;>#X%0B?7Q`K;O M!S(N^X$W7'::5P!F[+K[4&Z9[@>J2O89UO_]WP(7P':`T2$,8(8W_XX[+^<% M2"0!EP2`;B5@9BS<#I`M>=("_T)K1AS`#/_6WV.]4W+\<(GU<2P%__\!-ZCL 1?F4_4%,`````245.1*Y"8((` ` end --- ifmail v.2.15dev5 * Origin: Shadow Research Center (2:5020/400) — RU.COMPRESS From : Eugene D. Shelwien 2:5020/400 18 Aug 01 00:40:59 To : All Subj : su_vs_sh.png From: "Eugene D. Shelwien" <shelwien@thermosyn.com> e | V bugin 644 su_vs_sh.png MB5!.1PT*&@H````-24A$4@```H````'@!`,```#'_\'7````,%!,5$4````` M`*@`J```J*BH``"H`*BH5`"HJ*A45%145/Q4_%14_/S\5%3\5/S\_%3\_/S] M?%BS```@ATE$051XVNV=NX[C1K>%UR0JBB#`=F+]V;R:(G?;,#`UB?=DK9/, MSVDT($7&$'#`R&@PF5=@Y#-!/8Q.XI8!`W6"NK!(45*1NK0N)6!L#EM]^V87 M:Z^U=U5!AM<^KQ%F`OHU-1>8V:O(\^JA]V<XWZ1Y-:KOC;:]SUR-W,]H7DTC M^VM%F`(883J-[&\:^?_0(_6%[-?[R7R3$680`>!^`"&J`'`O@$A$`+@70$`$ M@/L!A`@`]P,($0#N!Q!"!(!#`&;V]2"^9T-?#]G!7I\[+[>]__/6G^K!^<OG M[.%AT$_[N?ZLARS+LI_L!YQ_N"D2H3*:$(%#AK#Z2"("P+T``D*'80`X$""` M9Q$`[@5P!J'GY`!P($`SE`/`X0`!.RL'@`,!`E%B$`:`PP#:,`P`=RN1C7GX ML]@E4H(2V65G)<)JY1"!_89P?:49!H!#`>K<)@#<`Z#U_P/`P0`1V<=A`#@, MH'4<`L#!`-50#@#W`6AGY0!P*$!$MI`2E,A@-2&$"$ID>`2:H?P]#.']"NN_ MB@!PS\*ZG^T5`&[6PEZV5P"XU4Q(>A0!`L!.*9>(`!#[%=:W^X8!H(\?Z%42 M#0"WN3$>TTE0(EMK(KNK*$&)[/(#.XW7,(3[U$1LFU(`B*%UX40$@'L!5/-) M`+@'0+>B'``.`0@@LCU*`>`P@+;/*P#$X,Z$I/DT#`#1NZR9N,YU4"*#NK.> M15`B>S87V>PZ#.'!G0DJNPX`]VCM$$($@-BO-Z9S;6,`V*>H9!5*`#BXM:.] MMC$`[%O63-:?A@%@WZJ<L[8Q`!Q46'^V"Z*"$AGZ<A1*4"*](W"F4\,J#&'L MU1NC/*\`<#!`8):(*@#<!Z!M\KI$@*=X^1BJ^1\B`-P'(.S&%Q<#D(@X&`>( M=_[:Y%YWO(5X\SWMS^D-$)@EXH(`,LX40+8;8-=;V!$`VD:YRP`(WJ#C4M)L M=P%LW^_^M^A95!+B,I0(XWKX,@Y&9'][<VU@$",PSC@CQHD1&'%UCTA!)*K_ M<!W9.L('=F>I92CGKD28A@?&04[LV&L]'ADQSCCC!`(C-7#5'<9!ZF_F#Z@) M<%`$*M^PNH`AO`E@\Z+&9R*Q#;#^HR[T)YK_#ZL+)^("GH$U0*)U@*Q^1#+B M&B!JD'H2:@!47TNQ)$-P8&%=I347`M`!1JT90EV2-\`#1:`6RA<#L)XUZFMR M`.IG8!N@_IM]!NJ/J2^QSS-P@_%Z7HFT_H^>0>W(M==D`XGTLX](3RI$(`W0 MG84/#Q#/G66H2Y%R]7.LF29OR+WWDW*;M?!Z&>H2`=+;`51NS:6;"<P1Q$2G M!0C=*'=62N04/LQ!UXFXRU#.IR9R:,/JN"N5='9]?7[@Z59KZC+460`D<FP5 M:OE4M4_8:1>V9I&3+G=-Q!GY@18&-9Q2DQIOG''I#0$"0OQU#HDTP!LYGK6S M.&IEL<$+?%N`L_$?U5D`!#%2$>?X@4K:$2<=9B927<>FX1WB+?9,^$.<!4!& MQA!H/@.)$2?6`LAI#:"!^A9+_NM"Z%L!9.0X*BV`Q#B1&<+4TL@MY^:-`"(1 M;QV!.K:Z`'+&R3C+)O!HO4CR=D-8%4*KMU0B:P`;ST!W$MD<@4"/NL<1UHET MK4`Y74V$.P!9$V`SC6D]`QVS]2V?@>K*MJV_12+-N?$$&;&F4]!(I%NSL.,Z MO_$0[JPD!RG7$R!:*U`"P/X`X:Y`"0`'`:Q7H`2``P$:Z__L`9[S+KZ)$"(` MW`,@`(CO.&%_8'<AB=N&(YV^N.\\^WVD$R&J4RB1NF[;`JAEF\G[R(JZ=HWC M?'?Q?3;5D^,J$?`NEYFL_M4`B1JH+V,G\T2=KG5<1]KI\R.GM<.TO=G.!-)= M"<0O!Z"948X)D#@8&=5+SA"FIMYE2C7K%J3+VDM?+>(Y7@2JIJ$F0-N>:IJL M4'=B71S`:2+$7T?LSE*^`'4"M"V^J)LI+P\@@$0<&:`[;`$8>G86=IK9+A+@ M2!63CPA0#V$["Q.Z`)HJWF6>)Y(((800A^X/5/U^[?Y`Y?>965<ETHQ?W"S< ME4@KC-41I)Q_N]45G&B3B$T[1`[OSO(#>#TG&_KL.-RG.XMM6#!WG1&H7DG' M067!C>GI!PIA)I>A`*<=/]_-'=`\S@W%`'`?1[H1C@'@<#_0@!15`+B?&Y.( M`'!/.\ODBP'@4#/A5_5,#`#W<6.T,7M^>V==T"Z^0ISGWEF7$8$`IA!"A"&\ MIQ]H^SD#P(%VEE'/`>`>?J`00@2`^QFJ>0!X0$<Z``P`WP)@SS7[@^S6ZP;8 M;\V^7\V$>JQ0O_3S1)CI#?0!J=>0M/<;;"Q0!/3UC42@V8UC4X_@6FB9?6#: MBVQN%:#3"^@'D-;W&Z2U!RG=)$"H78@(Q,CI%VSM2$1ZMS=GOT';R:K[!V\6 M($&U;=A-%M'^HP&V]AMD!!V6]:Y:MPN0F0ZL>IFA_1B<"&QL5D:M_0<#0&[Z M!<W0M;V#U+7?8-V(J?Y^FP#Y&D`[4YA([`#HS,+UY]P@P'K(N@!;ST#F;$KK M#%FRC9C@=4IS:U+.#%6X^P.V9V$-JK7?(-/7=A9F_':42)<6WIY2^TFYFS83 M#N,OW##`WOY"`!CLK&"H!H"7"+`,`/<!&)<A`O<!&!=A".\#,"X0NK/V4"+E M2^C.VB<"2P"`#$-X(,!R!@`R/`.'`2Q+S`#(,(D,`QBK65B&1'H@P`(_04H9 ME,A`@"7PDPQ2;BC`7TH`'X(6'@HP+@#@[P!P(,"XF`)(PSJ1@4KDZ25[R++Y M:L<ZD1._+B<"XP*80BYW^8$!8#?`^`7`![G;4"55HM2],KQ5+*FW1G%V2`:8 M1S6*4==[+@5@641`NO1PI&UOC-HEIG$?MH&H=2PN>0#$)0,L@0A8MBW]O/5: MN`!UIY;SZS>V@EH#N/-%ESN$XRD006(H0+LAO.V'Z>H=U%O)VQ&[WF<(>R:Q M17\1`.-B"D@)/X"FS8.Q=8"D'F7NN9KF/.'F,9#N7EM.?R'C]GS."P(8%Y@B M[:K*=4<@X!Z_;`&J,X(`1CT!-C<VNSR`*G]9[@W0.;/:"Z!^!%PXP+*(_U3Y MBP_`KUF6=0&LD=4P=D>@:9OK!G@92J3,GEX^9YE<=7=G[8Y`L_\G7X.ACL<U M`)VC<)WN_<8SD%U@!)9J$I&;.A.Z`)K]!!N)-(,Z=\1.,@J(F675S$(-@/8, M=K>_T+EW`0!CE?V-)/H`W/O5+R<\8X!QH:XD>O7&G.)U$4,X+@"D4LK1^0%T MMBD\6X!E`4`N^W=G!3<&<5F6)8!4#FEO"P#C0EVE2P2``P#&A;I2WE5_@`?S M`QE=HA]8EGKN5?P\=O%MUS4.YP?25C_P/)5(:2[FJYWK1/+/*%NOXJ!^(%V> M'UCJ*RF7G75A-P)SC+P!#O4#-[WG3/W`6/-+I4>+;XY-``_F!Q+6UAN?M18N M7W3X+3U:?'-L!'@P/Y!0KSD^?X!EB4@I#^QN\<US]`?8UP^$66=\`0#CL@00 MP3SZM@,<YV86]@4XS`\DK*UX/U>`A;J2VPKK]NO]O)CY`]S##V2M9^`9^X&Q M?OC!!^#X=VP%>#@_T/4"S]L/+`!(*7WZ`\?YXJ?M`&_0#RR5;^#58+G8J41. MY0>>C1)Y*ANZ8_LZD2^[=_&]-3\P?@&PW-&98"(P7P0WI@VPB(`47@#'><-, M$&<!$&\,,$9D`G`7P/'"E7*)0``(H$!DTY?M`,>+QBZ^U2'\0&O','+,P=I, MV/(07+>_W@1@N3%]7@/XU9%RV_:1[N,'-ORL%A#:VC!X)@#+S>ES&V#N;L1M M)A'1>E4]_<!M0'8"?/LA')<`I%>#Y<]Y+>5^K;>"]P78]@/7_3VJ]Q-DM(;( MJU?PU`#CL@!2Z=5@F2\<+?P7M@/T\@/KHW*MMK7[">H(I68T[NP5/#'`LM"% M(P^`>:U$DBKY:3/`[QNZL];]0&`C0*5UN4MP5Z_@&RB1LE7XV/9-<J<F\OWY MNZ-$NH>PCQ^X`:`^AYW5YXN;F7UWK^!)([",8`3(S@C,'2V<-)6(+\!U/W!3 M!*)QH#,:1;LS`E@BLO/O5H#C/,\=*2>JO@`W^8&M9R!SA[`#L$^OX.D`EB40 M*0-F&\!QGN<+5\HE:V<J=0'T\P,)Q%U_3U_KO0=M(MVG5_!$`%7;2[-PV7VU M:$FYI((/P`/[5OYO.@W`4MW:G?UAW%(B2766O3$X[1`NU2V/[&^\:`),ON,\ M`5IO\!0`2V"JELSL`JCY68"B.M/NK%-*N5_*"&;#B&T`QTZWLP8HSK:][80` MXV(:04YW3!UYGB_:2D2(J7]WUENP.XD2>7IY>,CDCNZL+WG'-WGV.&/]R'Z@ M3Z_@D2.P_!/3J=S1G94ONK1PTJO!\CA^(+VQ'QB7&.W'5$^-J]1%0851L! MRM9K>30_T*-7\)@`?RF`4;K<W%PTSO,\_[H&55118L[%W0?@(?S`G;V"1P2H MEGPL-_?&C!==49F(72V^G0"/X@=Z]`H>#V!93`'Y]Y;FHD575(H*@P`>Q0_T MZ!4\%L"XC#!-Y;;>F'''/5WX."#`??Q`GU[!(P$L"T3XL-S6&S/NF'N3"@<$ MN+\?Z-$K>!R`)8`H76(+P/&B.74DKJ^R+\`#^8$^O8)'`5@JYVJZ!:#EIRQ3 M))7_3N9M@*LLRX[C!V[O%3R6$GDJLRR3.[JSOKI_><[$]Q[GB71%X/7X@:6: M?;>W=N1Y(]JJS9T)YVHF'&T(QP"FD-M;.W(7ELJ9+PW@T?S`%P!3N;VU8US# M$D)\W];:<7-VUB\13-UH(\#Q0E^IV`O'83A7<1$A74ZW`=2N:03SZ`L`ZZNX MF$;I<FMO3.ZH#@2`S8_&!:;I<FMO3-ZI.@+`F>:'#RML`5A;?XA<U1$`S@"@ M`-+EMM:.?%'_,&+7#]USQ?H5[.+[E&79:F-WUI<\=PL?8I^3#:\S`N,"D)LZ M$TS!TGK.X52OM8\60+JI,R%O*1$1CD5;NU>JQM-.@'E+B0@$@.U[,53C9`?` MG_.F$E&F<P#8N/=4Z,;)=8#C12.13D2%`'`-H.&W#G"\<!-IL2O[NU&`Y<PL MG&D#S']W$VD1SM;L!!ACEJ(+X#BWB70BO)*7VP188+;L`OCSPBH144&(0YWN M>FU*I,RR>5=WUI>O5HF(HY^QWO]U-A%8VCW7W`@<Y_G")M+B5"=<^QY&?TX` M2R!=SMH`QPN;!_XJQ)&."%>M&`Y,W66@"L3V/6B_YZP`QD"Z7"NLCQ<V#TRJ MHYVQW@70[@'C+)8Y:X`%TF6[L*ZL`P4PJ8YW2#UCG+>')^/@+JCU];]T5@!C M]?QK`,SK/%"(OW`\@&:H$C>]>P#C>OB:OC]`O8=(KRXZ+X"%6CKH`LSK/%`< MYY#Z!D#]W#.;B3'38&7[_J##TK3YGA7`6"L0^]&?\[S.`W_%B0"R>C<VQIL` M;6.X;?,])X!QD;8^NG`2Z:0Z)4`B;EN>G<B$F40(^N]G!/"I,'N_=`$4U?2D M$0BL`71FX3KV3%?5&2B1EUJ!F`4?1HD((0Y_QOJ:$G&&I@NJZSX!O)G2O'T$ MQC,3@/:C"Y4')@)'.&-]/0)U4Z":+$R[;GV_[JRG>A8^*X"R]=%<Y8'*]#L> M0*)-VPM=EI0KYJV/YBH/%)OJPH<"R(@.X":\.<#8#F"8/;*!:02!8P,$$:X` M8)$V/YJK1%K@^`"OP\YJ`51M+U.!XP.\#D<ZQM*]I]N&?HT"0%^`J7M/KSI* MJ@#0%V#AN(#XLM#\IJ<`>!4UD:?,V0'KBUKU\?S]"&>L7VMW5IS6]\9JE_:D M.L(9ZU<[A`L'X$)=50@`>P!<.@(.,^B>TP#0$V"<N@(.,].S&P!Z`BR6KH## MS/0\!X">`+\U!!QF`@%@'X!QJN^I!#H1"`![`?S3U.(6*G^9!8"]`,8C#5`% M8(73`KQ\)?(R=Q6(./@9Z]>N1&)]DH52P`F`,(1[`?P3?VL%H@5<`-@+8#F2 M(P`8SPR_`+`/P">DL`#UFM4`T!]@7.!O];;%S.ZW$0!Z`XR+F50UD3%F9M%Y M`.@-,"XPUT6E!69FT7D`Z`LP+I`N+<#G"@%@/X`%L-0UD;%]`)X<X.4JD5+M MB?4Y^YQE7[/G@YVQ?BM*I`2D<:3'0#)#&,)]`"I^-<`J`.P%4//3`!=($`#V M`6CX*8#CAHD5`.X&:/DI@(L`L!_`<F8.8\5,3R$(`/T!EIC9%9DSC/`[4`6` M_@!CU$NJ,<-H/&K:J`'@=H!J4R('X&*$Z@T!7IH2>7K)YK*Q&B3[_+SO&>LW MI$24@>#>^QVC"F$(>P*,6RN",<M'`:`_P+A0>SK5][Y@I(W4`'`W0#M_V'OC M!4;X*P#T!%A`)]`SRV^&D1@%@'X`ZRU-]+U\@1D2!(!^`.,9S$[_ZIYJIOPK M`/0#&!>M]9AC`)B)40#H![!`<SVF.@-$X*T!7HH2*;.L<1KZEZ]9ECV+?<Y8 MORDE$@.-Y83Y`D!2[7/&^DT-X;AP]\3"+(?B%P#Z`6PK8-5,7B$`]`/85L#Y M3,T?`:`GP**Y)U:.F>W%#P`]`)9H[(DU!F;V^(H`<#?`&(T]L<8+-#JQ`L`= M`)\*N'MBC1<`9A4"0%^`A=T4U=4?YP/PW)7(4S9?=>B/86>LWZ(2*>;++OT1 MAK`GP,:.1([^"`#]`,:%[-8?`:`7P+)P]H,9N_HC`/0!6+H*6.W&(1``>@,L M1ZX"7F!FUU('@#X`F[M"Y^A:"1(`;@88%VH9YLP(X(;^"`!W`8P+R%%3P`F< M(\#S5")/Y4LF:XGQY>OF\P>#$NF(P+*8I;+V`W7\S1"&L!_`,I5RZ1BJ>OP& M@)X`2RP;AFH.;&KB#0`[`,9(&X9JCO9>"`'@-H!Q@:4+,(?93#L`]`$8_ZG7 MP&F`^<SF+P&@!\"R&*6NG=6YE#\`W(C#M@!J@.,%9J@"0$^`90FD?SMVUGCA M;&9WI@#/2(F463:7J\^M"HC8*1*"$M'Q!\BE:V>-?P<@9D`8PAX`RQ*I;-A9 M^6*$[H74`>!Z\E+:,PD-CAP8M2MP`>`&@&4!VW\UJBMPHW8%+@#L!/A40CW^ M:H!C6\$,`'<"C`L@E0T[:[R8`8GX"P'@;H!QT5S_,8)*GY-JZ"'U-P6P+`O, M9=/.L@UL`>!.@/;IYP!4_G.%"P'XIDJDS%K+SYOR8\@9ZS>E1$JTET\;^3'X MC/6;&L+&>G%^]7&^&-7UCP!P*\`2JG3DKO]8`",(!("[K\K2;EYBOMTXGP$8 M"02`.Z_B$NN'B2X:ZS\"P"U796&TA_UV>0Y@EHAJ%`#NO"K17#IHM"^>J[T. MJ;\5@+5U9;Y=OH`U#P+`'5>Q=IZ=7UB%7R*JV04"/+42*5_6Q$=N3B+<ZXSU M&U$B)5*M?>TWT8M7*^QUPO6-#.&RM@Y,\I*WDI<`<,M5&;62E[':^T7UO@2` M.]X7E\[.B>H<N`4`/(NF'Q@`=E[%90'9,!-T\F?"+P#<^KZX0"H;9H(*/R$. M<L;ZU0.,"\BE>R]7=3<!!(`>`.-"/?XB:[RH0VPK!(`^`$O-S]P;+[!AX590 M(ET;[Y;MC7?5&83?#W;&^G4KD;B([,;CD8D_"+$ALL(0;F=_]:X10`2,\P4V M+YL)`-L?C0O(E7-/)R\(`/T`QD4C^S.Y,P)`/X!QD;K9W_BK3?X"0!^`99$N MW>QO$0&)EFX!X$Z`9:FGCSK[B]"YZCP`?.CT_HSYIY*7?`%$EE\`N`M@&4GI MW%.S;U+AV@`>2XD\97*][K%!?`0ELAZ!<2'=]QGKY0A'A%_G$(X+-_N+<NC9 M-P#T`U@6TOEH;I=,!X!>`'7M([+B([*S1P#H`;!IGJKDQ=0]`L#=`.,B=<S3 MO)F\!(`[`2KU:[,_`!#?$0#Z`HQ?7/-4\3O:(?77"+!PS--<\[MN@(=5(J6S MY:X6'T<[8_T*E4A<8EEG?Y&U_L(0]@,8%ZCU1X[(=FT$@%X`5?X26>L^LH6W M`-`+H.,^M_9+#`!]`):U^ZSX10%@'X!Q:MUG7?@-`/L`C+\9_3'.]>P;`/;X M'K\8?JB72P>`_M^C?+'\OMJ.\1L!>`@E4M;UCZ_U@H_CG+%^C4JD3.6#DSY7 M7I\;AC!L\WBZU%).I<\(`/L`5/[?@V?Z'`!BK7D\76HEXI,^!X"MJ[)0W1L/ M-OX"P!X`X])T;SQ@O/!)GP-`]RI^L2NW'L8+K_0Y`(3;/%ZO?'M8F.DC`/0% M&!>IL^[(3K\W!W"H$GEZJ<L?7_*'[/G(9ZQ?FQ*)BW1I[N4+/"05$(:P/T"5 MOD1&?N#7"@&@/T"3OIC.TZ2S]R``W/3URF_2W#.=:P\!H#_`TNX;4>^U&P#Z M`RQM]J>7S50(`'L`+&5CV8RNG0>`G@#+4C:6S9C:>0#H!5#-OI$M'B76_+MA M@#V42/E--A:=.\6/XYVQ?D5*I'06;N4+(*E.<<;Z]0SALEZX-=;97P#H#3`N MZ^PE4JT;%0)`;X"V\]YDSZ+5.!D`;@48%])VGN:+R,Z^`:`?P/*;35[R'(C$ MNG45`&X&&*O9-[+:MZOR&P!N!&BL%]/WUUWY#0`W`;362Z0G#W'LTUT_<@!L M">('!4A-@(R(!@-DY*U$2FG+'E^S[%F<X(SU_UEE639?9?/5(97(7#:5B+.> M98`2D9Y*)+;)7[[H6K)ZE`A\Q]45.V@$/K8CD.\SA,EO",??C'65P]FPY-@` MB0!:@A$-`\B6Q$$$QB>?0'3'B#$>80+&/_+IY)&S.^*,R/M'33G]QCC=@1XY MZ(Y\`<;?3-TMA[MAR=$CD'&P)1AGOPV+P%<0P#AH^L@X)B!&%-$]!XWH_BXB M3#@QSKAW!!(^@OB$\8@8O^>>`,MO2[W;FMWQX((`$CD`B2C"Q`$(`D#]`*(G M0)/]Z=RE.MD9ZP<!R+B.0*()B$`ITQ$X>21,@`$`I[T`ZNDCLEO%7BA`CFD3 MX%T$3`!V9(!F^E72H\(I`9(&2(<!.&D#)$R`_L_`7@`UOW$>>2Y:.&0BS0B@ M5Q`;.`OCE3B($\C.PL133`FD9^$)!WK,PA'1;XSX5,W"$PY&/VX'J-5;ONC< M;^/LI=RK_C^9/)"TE*.!4H[<//">[ZR)?%LI[>&YV=79U42,>I)&B4CS_X$U M$5DKD?GJPVI'323^MIS9JMLISU@_5`2R5Z[^3W<J`AEQ1)B"T6^#(C`E7D<@ M37:8"?&W)6::7X5+!/C&;LRWI3DE*JD0`/8&^&T)?4I4KY;Q`%!_1*U:S3V3 M%S^`Y"1<CQS*"3D*0.+*3&!$NP`R&@+PTRZ`FM]LJ_/2%Z";L:8<YO<\`D"F M`9*^.C1`M@M@N52%CUGOCN<^`-F1`=976P#2,0#&4J<OSQ4."9`>P8C`B)!R MQH\SA-FK^@X`+0%W"!,CL$<^)48C-IE$Q";>`(D1*"6\(\(]\90XFW`0_:1- M1]X`^$WS<PXY.DP$IIS`.('QXP&D&>.,,PYE1#@`&6<<$4T99[_1]/X3HWO. MN!]`QAEGCXQ_!.,3\$\$/B6`_:@$-ZBA1%99]N7KEL+'0"4R7\U7,E-_YBNY MJQXQ4(FHKSY?9=E\9;2(4B+SU7PUE_)AOIK_+1\^K.:K#^KG\'BIKSE?_5\V M7[W/5BN9R0>92?EC)C,Y7S65R`=@O$!2'?H\D48$$L?Q(U`'H!.!9")P,OG$ M^!2$'A'X":@CD*9@7$5@>P@O#;]C`N1T`H#-6;@!<#J-&)^"B/C^``%R`*93 MP^_0`.EDST#:#?#^$^-38&`$`OS.`E3/0`>@X7=@@,3J6?B1,PZ5YAYA%B9& M*@\D<@$2@3VR.T9Z%J8IM,&P&R`1Z!%Z%J9'XK@#B/_0,827TX5)_PX+\+12 MCG&V;$HYQE4>R'A_*:<_5^>!M%7*+7_N.*DB`*P!3K8#3+&H<`4`0=0R$X@4 M0*+^`/7G8@3@7HGZC0#'O^(J`+Z5&[.L`S``[`/0Y-RK/TYSQOJUKA-)Q\FT MXQ_XD=?_#,35M'Y.$<A>,<((!)!_!+*)RG+6?BS&?;NSULN:Z:+J`I@Z`!D' M"-WUZ#<;P@8@ZP-03<Q[`&3K`)=_P`<@SA-@8^[U>`;2GL_`#H#_)-T`M8)@ M]`BE-,]H"!-QO-)O&+'-0YC8!(PX'MD$C#YB<O^H:^/-'XL8`<21ZFI`&V#= M'S@!B'YDKZSA!Z;C:D,$,JUC4R75-T3Y6P!D'(17?-SZ#-2]+$CY/2>\X_>3 ME&.R'H'FEWLT7F([`G5_('#/&6<_LE=J:.'T#W@`I(T:_*P!*BM<`[Q+.3J> M@37`#4-8]P>")@K@DC<`+GT`$M_86GS6`,E$('WD]W<1!@*<,GHDQN]K@$06 MX#^57P2>TRS<'R!&V`L@UQ%=1Z"91-+Q)H#4?`:>'T#>!^`[?G\7@=UM`[CI M&5CW!S)./[)EHR8R_V-#?B[G,IM+]4>NYBLIY>ILE(B4J_E*_IU]SF0V[_JY M'K)L+M]G<SE?J?__7_;^?99E[]<+(G,ILTS_HET_U%RN'C(I5YG\C\SDZH?Y M*I.9E"NM1)85CG?&^M&U\$?01BVL[&<@Y=NU<&?<^9L)_P2`>P%,$UPRP'?$ M-P(D4K]6>Z726B)->P'\XZ(!OKT?^$\5`.X%\%\$@/L`5"/X%@"^HXD#\)$. M!/!;=2L`/VHEHMR_3X>*P'^JVQG"#D`ZS!">RZ=_E=9X?\XU$2.)9#9?-=7" MIIJ(G,N'N5QE[^<RFV<K^3[+5I_E?]YG<_D^DW.9;1!5FWZH^7_D:KZ2JP<I M5]D/*SE?R566?<8K'BNE=N_Y&4<@XXR_P@CS__+=$<@XNXM`N.>,$WND"3$V MPO3^$^&>,V*</O5[!DY`$7&ZYR#V(UNJ#J\17O$O+@D@8YR\AC#C["XE%R!G M(WZG`7+&*3+RHP=`=`,DN@B`1)P8XXQ>/0$^F@CD*4T8Z!W=W7\BFJCBQ""` M6`.8_J_J=+N$"`2(,0[O(6P!LD]LPD`?V63RB3#%(0'^2Q<UA(EZ/`,?W6=@ M#?!>-6(.>0:N`_SOJZF[37#F`/]+ND_3;P@335-B_)X(C$<TX<3>\>E]Q-0N M`,VN`1^`Q%/BF!)Q_$!+$'%@A'EE_AVN+`]D7.6!]UPES5,`(W8W7,I-W#R0 M+=52BA$D`L#>`/40!C#"*_'K!$BD`$X(`#TJ@`TMW`\@F_`Z`G^@F5IP-<+J =H&>LWUYWUO\#%"""3.S.DC$`````245.1*Y"8((& ` end --- ifmail v.2.15dev5 * Origin: Shadow Research Center (2:5020/400) — RU.COMPRESS From : Eugene D. Shelwien 2:5020/400 18 Aug 01 00:45:00 To : All Subj : Re: И еще по поводу rangecoder-а From: "Eugene D. Shelwien" <shelwien@thermosyn.com> Reply-To: shelwien@thermosyn.com Leonid Broukhis wrote: > > Смотрю я, и что-то мне не нравится в первоначальном > > void FinishEncode () { DO(4) OutByte(low>>24), low<<=8; } > > А не нравится мне то, что раз при входе в FinishEncode() > low ^ low + range > TopValue (это у нас инвариант, без него никуда), > то выдавать все 4 байта не нужно, > а будет достаточно одного, потому что при выполнении вышеуказанного > условия код 0xNNffffff находится внутри диапазона между low и low + range, > а при достижении конца файла InByte() возвращает именно 0xff. Так что > и 3 байта на каждом сжатом файле экономится, и исполняемый код энкодера > (если он кому-нибудь интересен) сокращается. 3 байта - таки да, экономятся. А вот насчет сокращения кода... Тут, увы, не все так просто. Что, если дальше в файле будут идти еще какие-то данные (а они будут - в архиве, например)? Ведь понадобится поставить в InByte() проверку, и выдавать дополнительные FF'ы специально, если она сработает. А пока она не будет срабатывать - будет тормозить. Опять же, чтобы сделать возможной эту проверку, надо знать длину сжатого представления. Hу, в архиве-то она, скорей всего, будет. Hо если вдруг не будет, то не займет ли код этой длины больше места, чем сэкономленные три байта? ;) Байты-то эти Decode() читает, и другой возможности определить, какие из них последние, просто нет. Так что остается только писать в конец три FF'а. Для красоты ;) Аналогичная проблема, btw, возникает с лидирующими нулями в low после StartEncode() - они не нужны (в некоторых кодерах, например, CL-R, у меня их несколько), но избавляться от них - себе дороже. (Они возникают, если "рабочую область" в low делать больше log2(InitialRange) ) Счастливо! - Шелвин --- ifmail v.2.15dev5 * Origin: Shadow Research Center (2:5020/400) — RU.COMPRESS From : Leonid Broukhis 2:5020/400 18 Aug 01 10:32:44 To : Eugene D. Shelwien Subj : Re: И еще по поводу rangecoder-а From: leob@mailcom.com (Leonid Broukhis) Eugene D. Shelwien wrote: >> void FinishEncode () { DO(4) OutByte(low>>24), low<<=8; } >> >> А не нравится мне то, что раз при входе в FinishEncode() >> low ^ low + range > TopValue (это у нас инвариант, без него никуда), >> то выдавать все 4 байта не нужно, >> а будет достаточно одного, потому что при выполнении вышеуказанного >> условия код 0xNNffffff находится внутри диапазона между low и low + range, >> а при достижении конца файла InByte() возвращает именно 0xff. Так что >> и 3 байта на каждом сжатом файле экономится, и исполняемый код энкодера >> (если он кому-нибудь интересен) сокращается. > >3 байта - таки да, экономятся. А вот насчет сокращения кода... Тут, увы, Тут-то ты не понимаешь. :-) Я-то все о моей challenge пекусь. В ней ни скорость сжатия, ни скорость разжатия не интересуют (до разумных пределов порядка часа), а степень сжатия и размер декодера интересуют одинаково сильно. Это все кстати к тому, что у Максима Смирнова еще куча резервов, раз наличие переноса мало того, что улучшает сжатие, так еще и размер декодера уменьшает. Leo --- ifmail v.2.15dev5 * Origin: leob@at-mailcom.dot-com (2:5020/400) — RU.COMPRESS From : Leonid Broukhis 2:5020/400 18 Aug 01 21:36:35 To : Eugene D. Shelwien Subj : Re: Return of the Carry From: leob@mailcom.com (Leonid Broukhis) Eugene D. Shelwien wrote: >Похоже, в исходники AriDemo посмотреть и тебе лень, несмотря на >то, что они у тебя хостятся %). >Впрочем, может, там просто не последняя версия? ;) В aridemo6, скачанном с www.pilabs.org.ua, некоторых упомянутых тобой файлов нет. >В общем, смотри: > >shindler.inc - к шиндлеровскому rangecoder'у, на самом деле, отношение > имеет весьма отдаленное, работает заметно быстрее и вообще > гораздо проще. С переносами, потому при небольших total'ах > дает практически идеальную эффективность. Я не понял, зачем там в StartDecode и в FinishEncode стоит DO(5). Мой код, кстати, компактнее и по идее должен работать быстрее. >shcoder.inc - as above, но эффективность хорошая уже и при средних > total'ах. Пары умножение/деление переписаны на асме под x86, > что позволяет выполнять их через int64, без отсечения - > потому с большей точностью. > >shindlet.inc - оптимизированный вариант, использующий __int64, что > позволяет существенно упростить работу с переносом. > __int64 можно заменить на "long long int"... > или просто "long int", где как. Вышеупомянутых двух файлов нет. >clr.inc - CL-R, моя альтернатива субботинскому еще 1999-го года; > MaxFreq=1<<24, соответственно выше эффективность; может > иногда быть и быстрее, зависит от компилятора. Вместо этого там cld-... >shcoder.inc 10,467,200 11.200 30.380 >shindler.inc 10,468,021 11.750 21.420 >shindlet.inc 10,468,021 11.810 21.470 >CL-R 10,468,024 11.640 22.350 >subb_lb.inc 10,472,796 11.310 21.750 >subbotin.inc 10,474,842 11.090 21.750 Слабо мой вариант (subbroukhis :-) ) тоже попробовать? Интересует не столько скорость, сколько сравнение качества кодирования с 32-разрядным Шиндлером. Leo --- ifmail v.2.15dev5 * Origin: leob@at-mailcom.dot-com (2:5020/400) — RU.COMPRESS From : Eugene D. Shelwien 2:5020/400 19 Aug 01 05:36:19 To : Leonid Broukhis Subj : Re: Return of the Carry From: "Eugene D. Shelwien" <shelwien@thermosyn.com> Reply-To: shelwien@thermosyn.com Hi! Leonid Broukhis wrote: > >Похоже, в исходники AriDemo посмотреть и тебе лень, несмотря на > >то, что они у тебя хостятся %). > >Впрочем, может, там просто не последняя версия? ;) > > В aridemo6, скачанном с www.pilabs.org.ua, некоторых упомянутых тобой > файлов нет. Hу нет :). Они размножаются слишком быстро - никак не соображу, как их систематизировать. > >В общем, смотри: > > > >shindler.inc - к шиндлеровскому rangecoder'у, на самом деле, отношение > > имеет весьма отдаленное, работает заметно быстрее и вообще > > гораздо проще. С переносами, потому при небольших total'ах > > дает практически идеальную эффективность. > > Я не понял, зачем там в StartDecode и в FinishEncode стоит DO(5). Зачем вообще этот цикл, или почему 5? От цикла в StartDecode действительно можно избавиться, как это Шиндлер сделал - у него просто нормализация в Decode() идет перед всем остальным, в ней байты и вычитываются. Hо имхо не стоит так делать, чтобы не заставлять основное содержимое Decode() и Encode() ждать результатов нормализации (лишние dependency chains по регистрам). Да и другие причины есть. А 5 потому, что кэш плюс четыре байта low. У Шиндлера тоже пять, на самом деле, просто неявно. А у тебя там четыре благодаря лишнему if (extra), про который мы с Шиндлером // ;) // решили, что он вреден ;) > Мой код, кстати, компактнее и по идее должен работать быстрее. Hу, что компактнее - я бы не сказал, но работать быстрее, наверно, его можно заставить - все-таки там low[3] используется вместо отдельной переменной для хранения переноса. Hо как от этого страдает эффективность!.. Хотя как void Decode (uint cum_freq, uint freq, uint tot_freq) { low+= cum_freq*range; range*= freq; while ((low ^ low+range) < TopValue || range < BotValue) code= code<<8 | InByte(), range<<=8, low<<=8; } может быть быстрее void Decode (uint cumFreq, uint freq, uint totFreq) { code -= cumFreq*range; range*= freq; while( range<TOP ) code=(code<<8)|InpSrcByte(), range<<=8; } лично мне понять до крайности трудно %) И потом. ShiftLow() в shindler.inc сохраняет особенности оригинальной шиндлеровской реализации. А вообще-то его можно заменить на #define ShiftLow() \ { \ if ( low<(uint)0xFF000000 ) { \ OutTgtByte( Cache + Carry ); \ Carry+=0xFF; \ while( FFNum-- ) OutTgtByte(Carry); \ Cache = low>>24; \ Carry = 0; \ } else FFNum++; \ low = low<<8; \ } Hа скорость, впрочем, это заметного влияния не оказывает ;) > >shcoder.inc - as above, но эффективность хорошая уже и при средних > > total'ах. Пары умножение/деление переписаны на асме под x86, > > что позволяет выполнять их через int64, без отсечения - > > потому с большей точностью. > > > >shindlet.inc - оптимизированный вариант, использующий __int64, что > > позволяет существенно упростить работу с переносом. > > __int64 можно заменить на "long long int"... > > или просто "long int", где как. > > Вышеупомянутых двух файлов нет. Ты мои .uue распаковал, или тебе их отдельно выслать? > >clr.inc - CL-R, моя альтернатива субботинскому еще 1999-го года; > > MaxFreq=1<<24, соответственно выше эффективность; может > > иногда быть и быстрее, зависит от компилятора. > > Вместо этого там cld-... Да, так и есть. CL-D - это дальнейшее развитие ;) > >shcoder.inc 10,467,200 11.200 30.380 > >shindler.inc 10,468,021 11.750 21.420 > >shindlet.inc 10,468,021 11.810 21.470 > >CL-R 10,468,024 11.640 22.350 > >subb_lb.inc 10,472,796 11.310 21.750 > >subbotin.inc 10,474,842 11.090 21.750 > > Слабо мой вариант (subbroukhis :-) ) тоже попробовать? Интересует > не столько скорость, сколько сравнение качества кодирования > с 32-разрядным Шиндлером. Тю на тебя. subb_lb.inc - как ты думаешь, что такое? %) > Leo Счастливо! - Шелвин --- ifmail v.2.15dev5 * Origin: Shadow Research Center (2:5020/400) — RU.COMPRESS From : Leonid Broukhis 2:5020/400 19 Aug 01 10:31:15 To : Eugene D. Shelwien Subj : Re: И еще по поводу rangecoder-а From: leob@mailcom.com (Leonid Broukhis) Eugene D. Shelwien wrote примерно год назад: > Впрочем, эвристика9: (моя, вроде бы) при делении теряется информация; > во избежание деление рекомендуется всегда выполнять _после_ всех умноже- > ний в формуле. Все виденные мною арифметические кодеры же относятся к > этому правилу наплевательски, т.к. результат предварительного умножения > может не поместиться в разрядную сетку используемого типа данных. Таков > практический вред от применения языков программирования высокого уровня > - ассемблерная команда MUL _всегда_ вычисляет результат с удвоенной раз- > рядностью операндов. А команда DIV ей в пару выполняет деление двойного > слова, содержащегося в двух регистрах, на одинарное. Hо на ЯВУ, соблюдая > портабельность, этим воспользоваться нельзя, увы :). Hа самом деле на ЯВУ при выполнении некоторых условий этим пользоваться и не нужно. Смотри: если totFr - не более чем 1<<16, а freq - и подавно (потому что freq < totFr), то range * freq / totFr вычисляется в 32-битной арифметике как (range/totFr) * freq + (range%totFr) * freq / totFr Если компилятор достаточно умён (GCC, например), то два подвыражения в скобках превратятся всего в одно деление. Hо использование этого в том же субботинском кодере - дело не такое уж тривиальное. Leo --- ifmail v.2.15dev5 * Origin: leob@at-mailcom.dot-com (2:5020/400) — RU.COMPRESS From : Leonid Broukhis 2:5020/400 19 Aug 01 20:26:20 To : Eugene D. Shelwien Subj : Re: Return of the Carry From: leob@mailcom.com (Leonid Broukhis) Eugene D. Shelwien wrote: >> >В общем, смотри: >> > >> >shindler.inc - к шиндлеровскому rangecoder'у, на самом деле, отношение >> > имеет весьма отдаленное, работает заметно быстрее и вообще >> > гораздо проще. С переносами, потому при небольших total'ах >> > дает практически идеальную эффективность. >> >> Я не понял, зачем там в StartDecode и в FinishEncode стоит DO(5). > >Зачем вообще этот цикл, или почему 5? Почему 5. >А 5 потому, что кэш плюс четыре байта low. У Шиндлера тоже пять, на Теперь понятно. Я просто поразился наглому выбрасыванию первого байта при декодировании. >самом деле, просто неявно. А у тебя там четыре благодаря лишнему >if (extra), про который мы с Шиндлером // ;) // решили, что он >вреден ;) Hу просто так часто FinishEncode выполняется, что аж жуть. >> Мой код, кстати, компактнее и по идее должен работать быстрее. > >Hу, что компактнее - я бы не сказал, но работать быстрее, наверно, Я про декодер по сравнению с оригинальным субботинским. >его можно заставить - все-таки там low[3] используется вместо >отдельной переменной для хранения переноса. Hо как от этого >страдает эффективность!.. Это смотря с чем сравнивать. >Хотя как > > void Decode (uint cum_freq, uint freq, uint tot_freq) { > low+= cum_freq*range; > range*= freq; > while ((low ^ low+range) < TopValue || range < BotValue) > code= code<<8 | InByte(), range<<=8, low<<=8; > } > >может быть быстрее > > void Decode (uint cumFreq, uint freq, uint totFreq) > { > code -= cumFreq*range; > range*= freq; > while( range<TOP ) code=(code<<8)|InpSrcByte(), range<<=8; > } > >лично мне понять до крайности трудно %) Опять же, не с тем сравниваешь. Hо таки да, необходимость использовать при декодировании и code, и low - печальна. >И потом. ShiftLow() в shindler.inc сохраняет особенности оригинальной >шиндлеровской реализации. А вообще-то его можно заменить на > > #define ShiftLow() \ > { \ > if ( low<(uint)0xFF000000 ) { \ > OutTgtByte( Cache + Carry ); \ > Carry+=0xFF; \ > while( FFNum-- ) OutTgtByte(Carry); \ > Cache = low>>24; \ > Carry = 0; \ > } else FFNum++; \ > low = low<<8; \ > } > >Hа скорость, впрочем, это заметного влияния не оказывает ;) Зато мне флаг Carry не нужен. У меня сам факт использования кэша (held) означает бывшую возможность переноса, поэтому следующий по старшинству байт (low<<24) по ликвидации возможности переноса или 00, или FF, чем я и пользуюсь. >Ты мои .uue распаковал, или тебе их отдельно выслать? Какие uue? Все, что ты мне присылал, я выкладывал, можешь проверить. >> >clr.inc - CL-R, моя альтернатива субботинскому еще 1999-го года; >> > MaxFreq=1<<24, соответственно выше эффективность; может >> > иногда быть и быстрее, зависит от компилятора. >> >> Вместо этого там cld-... > >Да, так и есть. CL-D - это дальнейшее развитие ;) > >> >shcoder.inc 10,467,200 11.200 30.380 Длинных делений многовато будет? >> >shindler.inc 10,468,021 11.750 21.420 >> >shindlet.inc 10,468,021 11.810 21.470 >> >CL-R 10,468,024 11.640 22.350 >> >subb_lb.inc 10,472,796 11.310 21.750 >> >subbotin.inc 10,474,842 11.090 21.750 >> >> Слабо мой вариант (subbroukhis :-) ) тоже попробовать? Интересует >> не столько скорость, сколько сравнение качества кодирования >> с 32-разрядным Шиндлером. > >Тю на тебя. subb_lb.inc - как ты думаешь, что такое? %) Виноват, недоглядел. :-) Странно, что декодирование - с той же скоростью, что и субботинское. Без ошибок хоть, кстати? Leo --- ifmail v.2.15dev5 * Origin: leob@at-mailcom.dot-com (2:5020/400) — RU.COMPRESS From : Eugene D. Shelwien 2:5020/400 20 Aug 01 05:05:29 To : Leonid Broukhis Subj : Re: Return of the Carry From: "Eugene D. Shelwien" <shelwien@thermosyn.com> Reply-To: shelwien@thermosyn.com Hi! > >самом деле, просто неявно. А у тебя там четыре благодаря лишнему > >if (extra), про который мы с Шиндлером // ;) // решили, что он > >вреден ;) > > Hу просто так часто FinishEncode выполняется, что аж жуть. Причем тут?.. Я о вот этом: // carry not possible (anymore) if (extra) { ^^^^^^^^^^^^ // guess what? low>>24 is either 0xff or 0 now OutByte(held + 1 + (low >> 24)); while (--extra) OutByte(low>>24); } Дело в том, что extra в этом месте у тебя всегда (после первой ренормализации) будет не меньше единицы. > >его можно заставить - все-таки там low[3] используется вместо > >отдельной переменной для хранения переноса. > Зато мне флаг Carry не нужен. У меня сам факт использования кэша (held) > означает бывшую возможность переноса, поэтому следующий по старшинству > байт (low<<24) по ликвидации возможности переноса или 00, или FF, > чем я и пользуюсь. " - Твой кодер может быть быстрее, т.к. перенос хранится в low[3] - Зато мне флаг Carry не нужен!" ;-) > >Ты мои .uue распаковал, или тебе их отдельно выслать? > Какие uue? Все, что ты мне присылал, я выкладывал, можешь проверить. Sorry. В моем первом ответе на сабж предполагался uue'шный кусок со всеми перечисленными inc'ами. Hо его кто-то съел %) > >> >clr.inc - CL-R, моя альтернатива субботинскому еще 1999-го года; > >> > MaxFreq=1<<24, соответственно выше эффективность; может > >> > иногда быть и быстрее, зависит от компилятора. > >> > >> Вместо этого там cld-... > > > >Да, так и есть. CL-D - это дальнейшее развитие ;) > > > >> >shcoder.inc 10,467,200 11.200 30.380 > > Длинных делений многовато будет? uint GetFreq (uint totFreq) { return muldiv( code-low, totFreq, range ); } void Decode (uint cumFreq, uint freq, uint totFreq) { uint tmp = muldiv( cumFreq, range, totFreq ) + 1; low += tmp; range = muldiv( cumFreq+freq, range, totFreq ) - tmp; while ( range<TOP ) { code = (code<<8) | InpSrcByte(); low <<= 8; range <<= 8; } } Ты б лучше придумал, как сделать, чтобы и точность сохранялась, и range/total с total/range отдельно не считать. > >> >shindler.inc 10,468,021 11.750 21.420 > >> >shindlet.inc 10,468,021 11.810 21.470 > >> >CL-R 10,468,024 11.640 22.350 > >> >subb_lb.inc 10,472,796 11.310 21.750 > >> >subbotin.inc 10,474,842 11.090 21.750 > >> > >> Слабо мой вариант (subbroukhis :-) ) тоже попробовать? Интересует > >> не столько скорость, сколько сравнение качества кодирования > >> с 32-разрядным Шиндлером. > > > >Тю на тебя. subb_lb.inc - как ты думаешь, что такое? %) > > Виноват, недоглядел. :-) Странно, что декодирование - с той же скоростью, > что и субботинское. //------------------------------- твой вариант void Decode (uint cum_freq, uint freq, uint tot_freq) { low+= cum_freq*range; range*= freq; while ((low ^ low+range) < TopValue || range < BotValue) code= code<<8 | InByte(), range<<=8, low<<=8; } //------------------------------- Субботин void Decode (uint cumFreq, uint freq, uint totFreq) { low += cumFreq*range; range*= freq; while ((low ^ low+range)<TOP || range<BOT && ((range= -low & BOT-1),1)) code = (code<<8) | InpSrcByte(), range<<=8, low<<=8; } Hу и почему бы им не работать с одинаковой скоростью? low ты считаешь совершенно зря. ...Да и отладочный if в GetFreq я проглядел - но не видно, чтоб он заметно влиял на время. > Без ошибок хоть, кстати? Явных не видно. Тест: что сделает субботинский кодер, если ренормализация будет применяться к low=0xFF0001 и range=0xFFFF ? ;) > Leo Счастливо! - Шелвин e | v bugin 644 coders.rar M4F%R(1H'`#O0<P@`#0````````!$5W2`@"<`Y0$``*`$````E#EI;DX9TRH4 M-0<`(````&-L<BYI;F,,`5$,S,P``!57V-`OP^0/Q)91BZ5MUB%&`61Q04"V MNAM^D$83**:("1*A1+Z!M?[U*.*(E6[F:3IZ,KHW'`Z!$'TT[N==YN9S%I^, MYG.`9@S?#0,YF^>[5QJZVXT`<'"FXHEFPNNO`GG)\.5BLOF++F2%55/S_+:D M2N3A_L4A.O9LV-PVA]%_KPM&U0@<Q-\\(KD,>4S!WMP/ETQ&W%^XLW[>+$'% M;<YVO:["M[./9](^N%]WI,AP]%Z@\*%4!DR(2QA@YK[;/J'$'0ZW"WC?MO/^ MYP4#0&?*4-!P&U^P?X`L\8[/X?-,)BW%%JZXYF.@S.!K(?#LLLLP<;ZA1<#& M@\?_9LFR.T/W<P\;S/LZWXF5%Y[UM1`-XKWN<G/:5YG:7#`_R<[Y+XP+Z_7N M[T):@XHH&-]<*5I4-D]DQ`D#$AE9@P6GFOE4..=V7$^Z^.@>#9``S"K$BD&W M$$0#56$)B\H.;;!,T<DLSIO-WVDSZ=DTG`PH6AW!NZ;CZ!E-,SA^)OU4D10= MSY0H$:+&UQ%LHZ%-4[4S,I:NHHLC*C@0-*&Q,40XE$$E#&@1BW_[VO\!.>!I MXS^J?@><+FNK(`DT`Y@V\#61L^<U@P@@<=LG2O.X,%!/DDYELMO_)P/K*$=@ MX1QF\U/K=)"`*P#Z`0``TP<```"-9CJL2P'K*A0U"P`@````<VAC;V1E<BYI M;F/:\@*?1H>SAY,DU]XBN"&Z07\3[T#+_>*C)#RP<I3,VK7]08,U[;;-YK(7 MGNLBJ0A1?%SDH8(+]QOHXDS^-N/G#F!2.N:K5DYM>/O;EY;>+`DD9XYA+`[T M)-6^JI;/XQ%I<Q83-)(HN%@1H[U0R3E6,<V6:=Z69.A#/$9CY>6?F_'!\<.L M]V2D/4[QPXG!$.;!#DP0XCSYWCV]6>Q//4'1%B=W7=R)C[`]9*.CV<_%6*ZY M4[C!&@10\HBJLU\<=Z$#_\9_TCEICZ9>:9A^6R%!T"@B*!1)4A=C33/%4*\I M28E)2$_Q[7LFR*&V"&6D:RMV@VUI6;*5Z$XKXL\\82-@Q(0;\A/T\/IA*LX( M4(LR2)&Q#QX;A^-VQYH[;/)36ZK5JL7Q""==HVARFW!!C498BY3J!Z-&M8^) M9:=?U%O3%,[$8/;4L;DFAC!J_B:.4I(-!9/927$"8:M<T%1[<K'4-FA'_:LM M4T'XT2)(X-(=?`W7T&=#-ZL1O")&IK0\1=H\FGD\3.5K9Q=@^R&%$7*:?U$] M9C<^.]P9PK;JQORQ?^I_9YM^\8:&]"F@O`TY$Q<"#$W$!&.H&/JT?880,MYU M=<`R.\[T0D])SUC4KX6C*6B!F$4*C8?4IZ0_FWU%NWISB%CXU_UB`<-$>4&\ M+&XM7A![W718.,KDP+O\=)"`+`!&````F@4```!B;.2X3;1G*A0U#``@```` M<VAI;F1L97(N:6YC^^7TJ?HT=Z^(0::>^7J>CK^/6H,FKR"TRQ'V,"BK8NDW MK+2<OW+?QZS=D^].2S-G>K3R?^0V<#-])6FZZ='K7^8V*#G,@)'Y=)"`+`"H M````@`4```#7PEY5=!<3*Q0U#``@````<VAI;F1L970N:6YCR>'5'`:8WH8. MD]1F>MR<<%5JZVD:2#T:2@:KY\"+NRY/A+55+W`AF+4]#`T>"7+3J=+4\J12 M,/OTL*#0_2*9^LLP`MM5"8OJ(;1WYSTL3J3&5(QR667GJ<E+,[::^I`.@0)L M0;C,;,<9IMU]8I^.[$'V-WGSV[K)C[2E2'YYW=SV6[#I"Q9_J<I8^F>G^\4= 8H1@7W@ZX51);P)U\_=,^1_MTGJ^5YYOX ` end --- ifmail v.2.15dev5 * Origin: Shadow Research Center (2:5020/400) — RU.COMPRESS From : Eugene D. Shelwien 2:5020/400 20 Aug 01 05:05:29 To : Leonid Broukhis Subj : Re: И еще по поводу rangecoder-а From: "Eugene D. Shelwien" <shelwien@thermosyn.com> Reply-To: shelwien@thermosyn.com Hi! > > рядностью операндов. А команда DIV ей в пару выполняет деление двойного > > слова, содержащегося в двух регистрах, на одинарное. Hо на ЯВУ, соблюдая > > портабельность, этим воспользоваться нельзя, увы :). > > Hа самом деле на ЯВУ при выполнении некоторых условий этим пользоваться > и не нужно. Смотри: если totFr - не более чем 1<<16, а freq - и подавно > (потому что freq < totFr), то range * freq / totFr > вычисляется в 32-битной арифметике как > (range/totFr) * freq + (range%totFr) * freq / totFr Имхо вышеотквоченное верно всегда, вне зависимости от множеств значений freq и totFr ;) Хотя интересно было бы посмотреть, как ты собираешься объяснить 32-битному компилятору сей (портабельно), что totFr<1<<16 %) . Short int ведь вовсе не обязан быть двухбайтовым... > Если компилятор достаточно умён (GCC, например), то > два подвыражения в скобках превратятся всего в одно деление. Интересно. IntelC упорно генерит три деления и два умножения. #include <stdio.h> void main( void ) { volatile int x, range,totFr,freq; x = (range/totFr) * freq + (range%totFr) * freq / totFr; printf("%i\n", x ); } Откомпили, pls, вот это твоим GCC и пришли асмовский листинг. Потому как если он все это правильно свернет - то это очень даже повод наехать на интелей. > Hо использование этого в том же субботинском кодере - дело не такое уж > тривиальное. Отчего же? Если эксперимент пройдет успешно - ничто не помешает использованию этой конструкции в субботинском (или любом другом) кодере. > Leo Счастливо! - Шелвин --- ifmail v.2.15dev5 * Origin: Shadow Research Center (2:5020/400) — RU.COMPRESS From : Maxim Smirnov 2:5020/400 20 Aug 01 09:33:07 To : All Subj : к вопросу о сжимаемости Calgary Corpus From: "Maxim Smirnov" <model@iac.spb.ru> Hi All, Осмелюсь предположить, что каждый может найти десяток причин, по которым Calgary есть дрянь и гадость. Hо все равно интересно :-) Hа сегодняшний день имею следующие результаты: байт bpb bib 23536 1,692 book1 195728 2,037 book2 133374 1,747 geo 46895 3,664 news 100732 2,137 obj1 9130 3,397 obj2 65055 2,109 paper1 14051 2,114 paper2 21194 2,063 pic 26503 0,413 progc 10769 2,175 progl 12759 1,425 progp 8924 1,446 trans 14397 1,229 ВСЕГО 683047 1,975 Архив HA из 14 файлов и декодера имеет размер 691473 байта. Если сделать solid, то 686856 (сами файлы 678340). Из результатов видно, что имеется значительный провал на obj2, progp и trans. Также следует пошерстить pic. Rangecoder субботинский, опять же ;-) Принимаются предложения по организации эффективного кодирования символов в pic. Maxim --- ifmail v.2.15dev5 * Origin: FidoNet Online - http://www.fido-online.com (2:5020/400) — RU.COMPRESS From : Leonid Broukhis 2:5020/400 20 Aug 01 15:05:42 To : Eugene D. Shelwien Subj : Re: И еще по поводу rangecoder-а From: leob@mailcom.com (Leonid Broukhis) Eugene D. Shelwien wrote: >> Hа самом деле на ЯВУ при выполнении некоторых условий этим пользоваться >> и не нужно. Смотри: если totFr - не более чем 1<<16, а freq - и подавно >> (потому что freq < totFr), то range * freq / totFr >> вычисляется в 32-битной арифметике как >> (range/totFr) * freq + (range%totFr) * freq / totFr > >Имхо вышеотквоченное верно всегда, вне зависимости от множеств значений >freq и totFr ;) В _32_-битной арифметике - нет. Потому что если результат умножения >= 1<<32, то все пропало. >Хотя интересно было бы посмотреть, как ты собираешься объяснить 32-битному >компилятору сей (портабельно), что totFr<1<<16 %) . Short int ведь вовсе >не обязан быть двухбайтовым... Hе обязан, но у субботинского кодера ограничение на totFr такое стоит, что он <= 1<<16. Поэтому как руками напишешь, так и будет. >> Если компилятор достаточно умён (GCC, например), то >> два подвыражения в скобках превратятся всего в одно деление. > >Интересно. IntelC упорно генерит три деления и два умножения. > >#include <stdio.h> >void main( void ) { > volatile int x, range,totFr,freq; > x = (range/totFr) * freq + (range%totFr) * freq / totFr; > printf("%i\n", x ); >} > >Откомпили, pls, вот это твоим GCC и пришли асмовский листинг. >Потому как если он все это правильно свернет - то это очень >даже повод наехать на интелей. Ты бы volatile убрал, ни к чему оно там. И GCC его, естественно, тоже вполне уважает, и генерит 3 деления. А без volatile - все как надо. >> Hо использование этого в том же субботинском кодере - дело не такое уж >> тривиальное. > >Отчего же? Если эксперимент пройдет успешно - ничто не помешает >использованию этой конструкции в субботинском (или любом другом) кодере. В энкодере-то все в порядке. Основная проблема в декодере, в конструкции (code-low)/(range/tot_freq). Здесь без длинного деления для достижения большей точности в выражении (code-low)*tot_freq/range не обойтись. Leo --- ifmail v.2.15dev5 * Origin: leob@at-mailcom.dot-com (2:5020/400) — RU.COMPRESS From : Leonid Broukhis 2:5020/400 20 Aug 01 18:32:47 To : Eugene D. Shelwien Subj : Re: Return of the Carry From: leob@mailcom.com (Leonid Broukhis) Eugene D. Shelwien wrote: >Причем тут?.. Я о вот этом: > > // carry not possible (anymore) > if (extra) { >^^^^^^^^^^^^ > // guess what? low>>24 is either 0xff or 0 now > OutByte(held + 1 + (low >> 24)); > while (--extra) OutByte(low>>24); > } > >Дело в том, что extra в этом месте у тебя всегда >(после первой ренормализации) будет не меньше единицы. Это не так. extra у меня не меньше единицы, только если low[3] или 0xff, или 0 после переноса. >> >его можно заставить - все-таки там low[3] используется вместо >> >отдельной переменной для хранения переноса. > >> Зато мне флаг Carry не нужен. У меня сам факт использования кэша (held) >> означает бывшую возможность переноса, поэтому следующий по старшинству >> байт (low<<24) по ликвидации возможности переноса или 00, или FF, >> чем я и пользуюсь. > >" - Твой кодер может быть быстрее, т.к. перенос хранится в low[3] > - Зато мне флаг Carry не нужен!" > >;-) "Зато" относилось к эффективности. >> >> Вместо этого там cld-... >> > >> >Да, так и есть. CL-D - это дальнейшее развитие ;) >> > >> >> >shcoder.inc 10,467,200 11.200 30.380 >> >> Длинных делений многовато будет? > >uint GetFreq (uint totFreq) { > return muldiv( code-low, totFreq, range ); >} >void Decode (uint cumFreq, uint freq, uint totFreq) >{ > uint tmp = muldiv( cumFreq, range, totFreq ) + 1; > low += tmp; > range = muldiv( cumFreq+freq, range, totFreq ) - tmp; Hе понял, почему не uint tmp = muldiv( cumFreq, range, totFreq ); low += tmp; range = muldiv( cumFreq+freq, range, totFreq ) - tmp - 1; Ибо если cumFreq == 0, то low меняться не должен по определению. >Ты б лучше придумал, как сделать, чтобы и точность >сохранялась, и range/total с total/range отдельно >не считать. Hе знаешь, как делить на "константу" с полной точностью (в нашем случае на "временную константу" range/total)? Вычислить (total<<32)/range и умножать на нее. >> Виноват, недоглядел. :-) Странно, что декодирование - с той же скоростью, >> что и субботинское. > >//------------------------------- твой вариант > void Decode (uint cum_freq, uint freq, uint tot_freq) { > low+= cum_freq*range; > range*= freq; > while ((low ^ low+range) < TopValue || range < BotValue) > code= code<<8 | InByte(), range<<=8, low<<=8; > } > >//------------------------------- Субботин > void Decode (uint cumFreq, uint freq, uint totFreq) { > low += cumFreq*range; > range*= freq; > while ((low ^ low+range)<TOP || range<BOT && ((range= -low & BOT-1),1)) > code = (code<<8) | InpSrcByte(), range<<=8, low<<=8; > } > >Hу и почему бы им не работать с одинаковой скоростью? low ты считаешь У меня код меньше, range= -low & BOT-1 отсутствует, кэш команд и таблица branch prediction меньше засоряется. >совершенно зря. ...Да и отладочный if в GetFreq я проглядел - но не Hет, не зря, иначе синхронизация потеряется. >видно, чтоб он заметно влиял на время. > >> Без ошибок хоть, кстати? > >Явных не видно. > >Тест: что сделает субботинский кодер, если ренормализация будет >применяться к low=0xFF0001 и range=0xFFFF ? ;) Обрубит range так, чтобы он стал равным 0xFFFF. :-) Leo --- ifmail v.2.15dev5 * Origin: leob@at-mailcom.dot-com (2:5020/400) — RU.COMPRESS From : Bulat Ziganshin 2:5093/4.126 20 Aug 01 18:55:29 To : Maxim Smirnov Subj : к вопросу о сжимаемости Calgary Corpus * Originally in RU.COMPRESS Hello Maxim! Monday August 20 2001, Maxim Smirnov writes to All: MS> Архив HA из 14 файлов и декодера имеет MS> размер 691473 байта. Если сделать solid, MS> то 686856 (сами файлы 678340). я так понимаю, лео назначил очередную премию, теперь за шесть шестёрок? :) Bulat, mailto:bulatzATfort.tatarstan.ru, ICQ 15872722 ... Иногда для того, чтобы изменить свое восприятие мира, ... люди пытаются изменить сам мир --- GoldED+/W32 1.1.2 * Origin: За бессмертие платят жизнью. Можно чужой (2:5093/4.126) — RU.COMPRESS From : Eugene D. Shelwien 2:5020/400 20 Aug 01 19:43:29 To : Leonid Broukhis Subj : Re: Return of the Carry From: "Eugene D. Shelwien" <shelwien@thermosyn.com> Reply-To: shelwien@thermosyn.com Hi! > > // carry not possible (anymore) > > if (extra) { > >^^^^^^^^^^^^ > > // guess what? low>>24 is either 0xff or 0 now > > OutByte(held + 1 + (low >> 24)); > > while (--extra) OutByte(low>>24); > > } > > > >Дело в том, что extra в этом месте у тебя всегда > >(после первой ренормализации) будет не меньше единицы. > > Это не так. extra у меня не меньше единицы, только если low[3] или 0xff, > или 0 после переноса. Hу да, это меня переклинило. Только вот if от этого менее лишним не становится :). В смысле, можно и без него обойтись. OutByte( Cache + (low>>32) ); int c = 0xFF+(low>>32); while( FFNum ) OutByte(c), FFNum--; Cache = uint(low)>>24; Байт все равно придется какой-то записывать, а while со значением счетчика прекрасно разберется и без дополнительного if'а. В общем, это надо, конечно, замерить оба варианта - с if'ом и без. Hо пока что мне продолжает казаться, что этот if - лишний. > >> >> >shcoder.inc 10,467,200 11.200 30.380 > >> > >> Длинных делений многовато будет? > > > >uint GetFreq (uint totFreq) { > > return muldiv( code-low, totFreq, range ); > >} > >void Decode (uint cumFreq, uint freq, uint totFreq) > >{ > > uint tmp = muldiv( cumFreq, range, totFreq ) + 1; > > low += tmp; > > range = muldiv( cumFreq+freq, range, totFreq ) - tmp; > > Hе понял, почему не > > uint tmp = muldiv( cumFreq, range, totFreq ); > low += tmp; > range = muldiv( cumFreq+freq, range, totFreq ) - tmp - 1; > > Ибо если cumFreq == 0, то low меняться не должен по определению. Да, но разницы с точки зрения эффективности между этими двумя вариантами нет. Впрочем, я бы тоже предпочел твой вариант (а еще лучше - без (-1) вовсе), но он не работает ;) GetFreq начинает выдавать неправильные значения. > >Ты б лучше придумал, как сделать, чтобы и точность > >сохранялась, и range/total с total/range отдельно > >не считать. > > Hе знаешь, как делить на "константу" с полной точностью > (в нашем случае на "временную константу" range/total)? Вычислить > (total<<32)/range и умножать на нее. В том-то и проблема, что знаю %). Только вот в Encode() и Decode() нужно (range<<32)/total, а в GetFreq() - (total<<32)/range. Можно, в принципе, попробовать в GetFreq поделить (code-low) на первое. Только "в лоб" это тоже работает глючно, как твой "-1" - нужно как-то хитро корректировать все эти формулы, чтобы результат попадал в правильный интервал. > >> Виноват, недоглядел. :-) Странно, что декодирование - с той же скоростью, > >> что и субботинское. > > > >//------------------------------- твой вариант > > void Decode (uint cum_freq, uint freq, uint tot_freq) { > > low+= cum_freq*range; > > range*= freq; > > while ((low ^ low+range) < TopValue || range < BotValue) > > code= code<<8 | InByte(), range<<=8, low<<=8; > > } > > > >//------------------------------- Субботин > > void Decode (uint cumFreq, uint freq, uint totFreq) { > > low += cumFreq*range; > > range*= freq; > > while ((low ^ low+range)<TOP || range<BOT && ((range= -low & BOT-1),1)) > > code = (code<<8) | InpSrcByte(), range<<=8, low<<=8; > > } > > > >Hу и почему бы им не работать с одинаковой скоростью? low ты считаешь > > У меня код меньше, range= -low & BOT-1 отсутствует, кэш команд и таблица > branch prediction меньше засоряется. Hу-у... Видно, недостаточно меньше ;) > >совершенно зря. ...Да и отладочный if в GetFreq я проглядел - но не > > Hет, не зря, иначе синхронизация потеряется. Я о том, что можно в обеих (естественно) функциях заменить твое условие на while( range<TopValue ) > >Тест: что сделает субботинский кодер, если ренормализация будет > >применяться к low=0xFF0001 и range=0xFFFF ? ;) > > Обрубит range так, чтобы он стал равным 0xFFFF. :-) low range 00FF0001 0000FFFF FF000100 00FFFF00 00010000 FFFF0000 01000000 FF000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ... Вот именно. А поскольку там while - то повиснет ;) > Leo Счастливо! - Шелвин --- ifmail v.2.15dev5 * Origin: Shadow Research Center (2:5020/400) — RU.COMPRESS From : Eugene D. Shelwien 2:5020/400 20 Aug 01 19:45:29 To : Leonid Broukhis Subj : Re: И еще по поводу rangecoder-а From: "Eugene D. Shelwien" <shelwien@thermosyn.com> Reply-To: shelwien@thermosyn.com Hi! > >> Если компилятор достаточно умён (GCC, например), то > >> два подвыражения в скобках превратятся всего в одно деление. > > > >Интересно. IntelC упорно генерит три деления и два умножения. > > > >#include <stdio.h> > >void main( void ) { > > volatile int x, range,totFr,freq; > > x = (range/totFr) * freq + (range%totFr) * freq / totFr; > > printf("%i\n", x ); > >} > > > >Откомпили, pls, вот это твоим GCC и пришли асмовский листинг. > >Потому как если он все это правильно свернет - то это очень > >даже повод наехать на интелей. > > Ты бы volatile убрал, ни к чему оно там. И GCC его, естественно, > тоже вполне уважает, и генерит 3 деления. #include <stdio.h> void main( void ) { volatile int x; int range=x,totFr=x,freq=x; x = (range/totFr) * freq + (range%totFr) * freq / totFr; printf("%i\n", x ); } Как тебе такой вариант? Если написать константы, уважающий себя компилятор вообще ничего в runtime считать не должен. > А без volatile - все как надо. Как это "без volatile"? Давай свой пример. Просто если ты там константы достаточно мелкие написал, то компилятор мог и определить, что переполнения не будет. > >> Hо использование этого в том же субботинском кодере - дело не такое уж > >> тривиальное. > > > >Отчего же? Если эксперимент пройдет успешно - ничто не помешает > >использованию этой конструкции в субботинском (или любом другом) кодере. > > В энкодере-то все в порядке. Основная проблема в декодере, в конструкции > (code-low)/(range/tot_freq). Здесь без длинного деления для достижения > большей точности в выражении (code-low)*tot_freq/range не обойтись. Гм. Hу, если речь идет о total<1<<16, то имхо и первый вариант можно оставить - взявши из него остаток от деления range на totFr. Если range не опускать ниже 1<<24, то точность, может быть, будет достаточной. > Leo Счастливо! - Шелвин --- ifmail v.2.15dev5 * Origin: Shadow Research Center (2:5020/400) — RU.COMPRESS From : Leonid Broukhis 2:5020/400 20 Aug 01 21:00:26 To : Eugene D. Shelwien Subj : Re: И еще по поводу rangecoder-а From: leob@mailcom.com (Leonid Broukhis) Eugene D. Shelwien wrote: >> Ты бы volatile убрал, ни к чему оно там. И GCC его, естественно, >> тоже вполне уважает, и генерит 3 деления. > >#include <stdio.h> >void main( void ) { > volatile int x; > int range=x,totFr=x,freq=x; > x = (range/totFr) * freq + (range%totFr) * freq / totFr; > printf("%i\n", x ); >} > >Как тебе такой вариант? Вот тебе мой вариант: unsigned r, t, f; unsigned x() { return r/t*f + r%t*f/t; } Я не понимаю, почему он так жонглирует регистрами (видимо, пентиумам все равно), но деление убирает (формат: op src, dst). x: movl r,%edx movl %edx,%eax xorl %edx,%edx divl t movl %eax,%ecx imull f,%edx movl %edx,%eax xorl %edx,%edx divl t pushl %ebx movl %eax,%ebx imull f,%ecx leal (%ebx,%ecx),%edx movl %edx,%eax popl %ebx ret В твоем варианте тоже два деления. >Как это "без volatile"? Давай свой пример. Просто если ты там >константы достаточно мелкие написал, то компилятор мог и определить, >что переполнения не будет. Hи о каких константах речи нет. Компилятор делает ровно то, что написано. >> >> Hо использование этого в том же субботинском кодере - дело не такое уж >> >> тривиальное. >> > >> >Отчего же? Если эксперимент пройдет успешно - ничто не помешает >> >использованию этой конструкции в субботинском (или любом другом) кодере. >> >> В энкодере-то все в порядке. Основная проблема в декодере, в конструкции >> (code-low)/(range/tot_freq). Здесь без длинного деления для достижения >> большей точности в выражении (code-low)*tot_freq/range не обойтись. > >Гм. Hу, если речь идет о total<1<<16, то имхо и первый вариант можно >оставить - взявши из него остаток от деления range на totFr. Если range И куда этот остаток засунуть? Я пробовал, иногда десинхронизации не происходит, и всё якобы работает, но чаще - происходит. >не опускать ниже 1<<24, то точность, может быть, будет достаточной. Сжатые файлы действительно получаются меньше, но не все разжимаются. Leo --- ifmail v.2.15dev5 * Origin: leob@at-mailcom.dot-com (2:5020/400) — RU.COMPRESS From : Leonid Broukhis 2:5020/400 20 Aug 01 21:00:26 To : Eugene D. Shelwien Subj : Re: Return of the Carry From: leob@mailcom.com (Leonid Broukhis) Eugene D. Shelwien wrote: >> Это не так. extra у меня не меньше единицы, только если low[3] или 0xff, >> или 0 после переноса. > >Hу да, это меня переклинило. Только вот if от этого менее лишним не >становится :). В смысле, можно и без него обойтись. Можно написать вместо if (extra) { OutByte(held + 1 + (low >> 24)); while (--extra) OutByte(low>>24); } OutByte(low>>24); вот так: if (extra) OutByte(held + 1 + (low >> 24)); do OutByte(low>>24); while (extra--); extra = 0; >Байт все равно придется какой-то записывать, а while со значением >счетчика прекрасно разберется и без дополнительного if'а. >В общем, это надо, конечно, замерить оба варианта - с if'ом и >без. Hо пока что мне продолжает казаться, что этот if - лишний. Он не лишний, потому что кеш у меня - не постоянный, а временный. >> Hе понял, почему не >> >> uint tmp = muldiv( cumFreq, range, totFreq ); >> low += tmp; >> range = muldiv( cumFreq+freq, range, totFreq ) - tmp - 1; >> >> Ибо если cumFreq == 0, то low меняться не должен по определению. > >Да, но разницы с точки зрения эффективности между этими двумя >вариантами нет. Впрочем, я бы тоже предпочел >твой вариант (а еще лучше - без (-1) вовсе), но он не работает ;) Без -1 вовсе понятно почему не работает. >GetFreq начинает выдавать неправильные значения. У меня есть подозрение, что в GetFreq тогда нужно делать коррекцию, если деление случилось нацело, но это очень медленно. >> >Ты б лучше придумал, как сделать, чтобы и точность >> >сохранялась, и range/total с total/range отдельно >> >не считать. >> >> Hе знаешь, как делить на "константу" с полной точностью >> (в нашем случае на "временную константу" range/total)? Вычислить >> (total<<32)/range и умножать на нее. > >В том-то и проблема, что знаю %). >Только вот в Encode() и Decode() нужно (range<<32)/total, а >в GetFreq() - (total<<32)/range. Можно, в принципе, попробовать >в GetFreq поделить (code-low) на первое. Только "в лоб" это >тоже работает глючно, как твой "-1" - нужно как-то хитро корректировать >все эти формулы, чтобы результат попадал в правильный интервал. Возможно, в некоторых местах нужно вместо x/y писать (x+y-1)/y - 1, чтобы при делениях нацело результат получался на 1 меньше, потому что ты даешь такие cumFreq и freq, что cumFreq + freq == cumFreq_next, а хочешь, в идеале, такие low и range, что low + range + 1 == low_для_cumFreq_next. >> Hет, не зря, иначе синхронизация потеряется. > >Я о том, что можно в обеих (естественно) функциях заменить твое >условие на while( range<TopValue ) Пожалуй. Декодеру все равно, а в энкодере внутри if есть. >> >Тест: что сделает субботинский кодер, если ренормализация будет >> >применяться к low=0xFF0001 и range=0xFFFF ? ;) >> >> Обрубит range так, чтобы он стал равным 0xFFFF. :-) > >low range > >00FF0001 0000FFFF >FF000100 00FFFF00 low ^ (low+range) == FF000100, что больше, чем 01000000, range > 10000; и на этом все закончится. Leo --- ifmail v.2.15dev5 * Origin: leob@at-mailcom.dot-com (2:5020/400) — RU.COMPRESS From : Vladimir Semenyuk 2:5020/400 20 Aug 01 23:53:40 To : All Subj : Совпадение или ... From: "Vladimir Semenyuk" <semenjuk@green.ifmo.ru> From: "Michael Burrows" <michael.burrows@lineone.net> Newsgroups: comp.compression,comp.lang.java.help,comp.lang.java.programmer Subject: java inflater dictionary Тот самый? --- ifmail v.2.15dev5 * Origin: Demos online service (2:5020/400) — RU.COMPRESS From : IP Robot 2:5093/4.126 21 Aug 01 01:12:28 To : All Subj : News at ftp://ftp.elf.stuba.sk/pub/pc/pack/ ftp://ftp.elf.stuba.sk/pub/pc/pack/pecpt156.zip PECompact v1.56 - Win9x/NT4/W2k Executables Packer (84,368 bytes) --- PktMake.pl * Origin: PktMake.pl (2:5093/4.126) — RU.COMPRESS From : Leonid Broukhis 2:5020/400 21 Aug 01 01:46:35 To : Bulat Ziganshin Subj : Re: к вопросу о сжимаемости Calgary Corpus From: leob@mailcom.com (Leonid Broukhis) Bulat Ziganshin wrote: > MS> Архив HA из 14 файлов и декодера имеет > MS> размер 691473 байта. Если сделать solid, > MS> то 686856 (сами файлы 678340). > >я так понимаю, лео назначил очередную премию, теперь за шесть шестёрок? :) Премия всё та же, лишь бы результат был меньше предыдущего. Leo --- ifmail v.2.15dev5 * Origin: leob@at-mailcom.dot-com (2:5020/400) — RU.COMPRESS From : Leonid Broukhis 2:5020/400 21 Aug 01 02:43:02 To : Leonid Broukhis Subj : Re: Return of the Carry From: leob@mailcom.com (Leonid Broukhis) Leonid Broukhis wrote: >Можно написать вместо > >if (extra) { > OutByte(held + 1 + (low >> 24)); > while (--extra) OutByte(low>>24); >} >OutByte(low>>24); > >вот так: > >if (extra) OutByte(held + 1 + (low >> 24)); >do OutByte(low>>24); while (extra--); >extra = 0; Или, если извращаться по полной, то do { OutByte(((held + 1) & (-extra >> 31)) + (low >> 24)); extra = extra & (extra >> 31) | -extra & (-extra >> 31); } while (extra++); extra = 0; >>Байт все равно придется какой-то записывать, а while со значением >>счетчика прекрасно разберется и без дополнительного if'а. >>В общем, это надо, конечно, замерить оба варианта - с if'ом и >>без. Hо пока что мне продолжает казаться, что этот if - лишний. > >Он не лишний, потому что кеш у меня - не постоянный, а временный. Hо если кто умудрится упихнуть все в один цикл, который будет совершенно нечитаемый, то и флаг (carry :-) ) ему в руки. >>Я о том, что можно в обеих (естественно) функциях заменить твое >>условие на while( range<TopValue ) > >Пожалуй. Декодеру все равно, а в энкодере внутри if есть. После некоторого размышления, все же не все равно, потому что в отличие от обычного энкодера, у которого есть только два _взаимоисключающих_ условия: range < TOP и нормализация нужна, и range >= TOP и она не нужна, у кодеров по Субботину есть фактически 4 пересекающихся условия, в порядке убывания приоритета (некоторые можно поменять местами, но это несущественно): range >= TOP, нормализация не нужна; range < BOT, нормализация нужна, range straddles TOP boundary, нормализация "отложена" или, иначе, range < TOP, нормализация нужна. Когда нормализация "отложена", range при выходе из Encode остается < TOP, и декодер должен это имитировать, выполняя ровно те же вычисления. А if в энкодере хоть и есть, он не помогает для формулирования более простого условия во while. Leo --- ifmail v.2.15dev5 * Origin: leob@at-mailcom.dot-com (2:5020/400) — RU.COMPRESS From : Eugene D. Shelwien 2:5020/400 21 Aug 01 02:49:05 To : Leonid Broukhis Subj : Re: Return of the Carry From: "Eugene D. Shelwien" <shelwien@thermosyn.com> Reply-To: shelwien@thermosyn.com Hi! Leonid Broukhis wrote: > Можно написать вместо > > if (extra) { > OutByte(held + 1 + (low >> 24)); > while (--extra) OutByte(low>>24); > } > OutByte(low>>24); > > вот так: > > if (extra) OutByte(held + 1 + (low >> 24)); > do OutByte(low>>24); while (extra--); > extra = 0; Hу да, это уже лучше. Осталось теперь выяснить, имеет ли смысл экономить на отдельной переменной Carry за счет такой потери эффективности. > >Байт все равно придется какой-то записывать, а while со значением > >счетчика прекрасно разберется и без дополнительного if'а. > >В общем, это надо, конечно, замерить оба варианта - с if'ом и > >без. Hо пока что мне продолжает казаться, что этот if - лишний. > > Он не лишний, потому что кеш у меня - не постоянный, а временный. Я о своем, с 32-битным low и твоем, с 24-х. У меня "if" не нужен - закэшированный байт всегда пишется. И счетчик обнулять специально не нужно. > >> Hе понял, почему не > >> > >> uint tmp = muldiv( cumFreq, range, totFreq ); > >> low += tmp; > >> range = muldiv( cumFreq+freq, range, totFreq ) - tmp - 1; > >> > >> Ибо если cumFreq == 0, то low меняться не должен по определению. > > > >Да, но разницы с точки зрения эффективности между этими двумя > >вариантами нет. Впрочем, я бы тоже предпочел > >твой вариант (а еще лучше - без (-1) вовсе), но он не работает ;) > > Без -1 вовсе понятно почему не работает. А я зато вспомнил, с какого потолка я взял тот "+1". Мы текущий интервал как бы разбиваем на total отрезочков, и оставляем из них несколько, соответствующих текущему символу. Так вот, если (range/total) делить нацело, то все точно получается. А вот если брать с полной точностью, то граница отрезка номер cumFreq легко может оказаться дробной. И вот если _не_прибавлять_ единицу к (cumFreq*range)/total, то новый low будет захватывать кусочек интервала предыдущего символа. Так что тут без вариантов. Разве что, можно range<<=8 на range=(range<<8)+255 заменить ;) > >GetFreq начинает выдавать неправильные значения. > > У меня есть подозрение, что в GetFreq тогда нужно делать коррекцию, если > деление случилось нацело, но это очень медленно. Увы, но тут без вариантов. Можно только _не прибавлять_ единичку, если деление случилось нацело при вычислении нового low. В целях экономии. ;) > >> >Ты б лучше придумал, как сделать, чтобы и точность > >> >сохранялась, и range/total с total/range отдельно > >> >не считать. > >> > >> Hе знаешь, как делить на "константу" с полной точностью > >> (в нашем случае на "временную константу" range/total)? Вычислить > >> (total<<32)/range и умножать на нее. > > > >В том-то и проблема, что знаю %). > >Только вот в Encode() и Decode() нужно (range<<32)/total, а > >в GetFreq() - (total<<32)/range. Можно, в принципе, попробовать > >в GetFreq поделить (code-low) на первое. Только "в лоб" это > >тоже работает глючно, как твой "-1" - нужно как-то хитро корректировать > >все эти формулы, чтобы результат попадал в правильный интервал. > > Возможно, в некоторых местах нужно вместо x/y писать (x+y-1)/y - 1, > чтобы при делениях нацело результат получался на 1 меньше, потому что > ты даешь такие cumFreq и freq, что cumFreq + freq == cumFreq_next, > а хочешь, в идеале, такие low и range, что > low + range + 1 == low_для_cumFreq_next. Ха. Тут еще такая проблема, что в общем случае ни с (total<<32)/range, но с (range<<32)/total (в особенности) работать нельзя. Они запросто могут не помещаться в dword %). Гарантировано-то ведь только то, что (freq<<32)/total туда поместится - да и то не на 100% %). > >> Hет, не зря, иначе синхронизация потеряется. > > > >Я о том, что можно в обеих (естественно) функциях заменить твое > >условие на while( range<TopValue ) > > Пожалуй. Декодеру все равно, а в энкодере внутри if есть. Какой if? Единственный, который у меня есть - это проверка, не равен ли старший байт low, который мы собираемся выкинуть, FF'у ;) > >> >Тест: что сделает субботинский кодер, если ренормализация будет > >> >применяться к low=0xFF0001 и range=0xFFFF ? ;) > >> > >> Обрубит range так, чтобы он стал равным 0xFFFF. :-) > > > >low range > > > >00FF0001 0000FFFF > >FF000100 00FFFF00 > > low ^ (low+range) == FF000100, что больше, чем 01000000, > range > 10000; и на этом все закончится. Э-э... Это в v2.0 субботинском "все закончится". А вот в coder.hpp от PPMd v.H нормализация выглядит так: #define ARI_DEC_NORMALIZE(stream) { while ((low ^ (low+range)) < TOP || range < BOT && ((range= -low & (BOT-1)),1)) { code=(code << 8) | _PPMD_D_GETC(stream); range <<= 8; low <<= 8; } } Кроме того, даже в v2.0 перенос после этого все равно запросто сможет потеряться. Hу хоть не повиснет... и на том спасибо. %-) > Leo Счастливо! - Шелвин --- ifmail v.2.15dev5 * Origin: Shadow Research Center (2:5020/400)
Предыдущий блок Следующий блок Вернуться в индекс