mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-05-31 11:44:36 +00:00
trunk contents moved to root
This commit is contained in:
39
libsrc/FlashPlayer/FlashPlayer.cfg
Normal file
39
libsrc/FlashPlayer/FlashPlayer.cfg
Normal file
@@ -0,0 +1,39 @@
|
||||
-$A8
|
||||
-$B-
|
||||
-$C+
|
||||
-$D+
|
||||
-$E-
|
||||
-$F-
|
||||
-$G+
|
||||
-$H+
|
||||
-$I+
|
||||
-$J-
|
||||
-$K-
|
||||
-$L+
|
||||
-$M-
|
||||
-$N+
|
||||
-$O+
|
||||
-$P+
|
||||
-$Q-
|
||||
-$R-
|
||||
-$S-
|
||||
-$T-
|
||||
-$U-
|
||||
-$V+
|
||||
-$W-
|
||||
-$X+
|
||||
-$YD
|
||||
-$Z1
|
||||
-cg
|
||||
-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
|
||||
-H+
|
||||
-W+
|
||||
-M
|
||||
-$M16384,1048576
|
||||
-K$00400000
|
||||
-E"..\..\lib\"
|
||||
-LE"c:\program files (x86)\borland\delphi7\Projects\Bpl"
|
||||
-LN"c:\program files (x86)\borland\delphi7\Projects\Bpl"
|
||||
-w-UNSAFE_TYPE
|
||||
-w-UNSAFE_CODE
|
||||
-w-UNSAFE_CAST
|
||||
138
libsrc/FlashPlayer/FlashPlayer.dof
Normal file
138
libsrc/FlashPlayer/FlashPlayer.dof
Normal file
@@ -0,0 +1,138 @@
|
||||
[FileVersion]
|
||||
Version=7.0
|
||||
[Compiler]
|
||||
A=8
|
||||
B=0
|
||||
C=1
|
||||
D=1
|
||||
E=0
|
||||
F=0
|
||||
G=1
|
||||
H=1
|
||||
I=1
|
||||
J=0
|
||||
K=0
|
||||
L=1
|
||||
M=0
|
||||
N=1
|
||||
O=1
|
||||
P=1
|
||||
Q=0
|
||||
R=0
|
||||
S=0
|
||||
T=0
|
||||
U=0
|
||||
V=1
|
||||
W=0
|
||||
X=1
|
||||
Y=1
|
||||
Z=1
|
||||
ShowHints=1
|
||||
ShowWarnings=1
|
||||
UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
|
||||
NamespacePrefix=
|
||||
SymbolDeprecated=1
|
||||
SymbolLibrary=1
|
||||
SymbolPlatform=1
|
||||
UnitLibrary=1
|
||||
UnitPlatform=1
|
||||
UnitDeprecated=1
|
||||
HResultCompat=1
|
||||
HidingMember=1
|
||||
HiddenVirtual=1
|
||||
Garbage=1
|
||||
BoundsError=1
|
||||
ZeroNilCompat=1
|
||||
StringConstTruncated=1
|
||||
ForLoopVarVarPar=1
|
||||
TypedConstVarPar=1
|
||||
AsgToTypedConst=1
|
||||
CaseLabelRange=1
|
||||
ForVariable=1
|
||||
ConstructingAbstract=1
|
||||
ComparisonFalse=1
|
||||
ComparisonTrue=1
|
||||
ComparingSignedUnsigned=1
|
||||
CombiningSignedUnsigned=1
|
||||
UnsupportedConstruct=1
|
||||
FileOpen=1
|
||||
FileOpenUnitSrc=1
|
||||
BadGlobalSymbol=1
|
||||
DuplicateConstructorDestructor=1
|
||||
InvalidDirective=1
|
||||
PackageNoLink=1
|
||||
PackageThreadVar=1
|
||||
ImplicitImport=1
|
||||
HPPEMITIgnored=1
|
||||
NoRetVal=1
|
||||
UseBeforeDef=1
|
||||
ForLoopVarUndef=1
|
||||
UnitNameMismatch=1
|
||||
NoCFGFileFound=1
|
||||
MessageDirective=1
|
||||
ImplicitVariants=1
|
||||
UnicodeToLocale=1
|
||||
LocaleToUnicode=1
|
||||
ImagebaseMultiple=1
|
||||
SuspiciousTypecast=1
|
||||
PrivatePropAccessor=1
|
||||
UnsafeType=0
|
||||
UnsafeCode=0
|
||||
UnsafeCast=0
|
||||
[Linker]
|
||||
MapFile=0
|
||||
OutputObjs=0
|
||||
ConsoleApp=1
|
||||
DebugInfo=0
|
||||
RemoteSymbols=0
|
||||
MinStackSize=16384
|
||||
MaxStackSize=1048576
|
||||
ImageBase=4194304
|
||||
ExeDescription=
|
||||
[Directories]
|
||||
OutputDir=..\..\lib\
|
||||
UnitOutputDir=
|
||||
PackageDLLOutputDir=
|
||||
PackageDCPOutputDir=
|
||||
SearchPath=
|
||||
Packages=vcl;rtl;vclx;VclSmp;vclshlctrls
|
||||
Conditionals=
|
||||
DebugSourceDirs=
|
||||
UsePackages=0
|
||||
[Parameters]
|
||||
RunParams=
|
||||
HostApplication=
|
||||
Launcher=
|
||||
UseLauncher=0
|
||||
DebugCWD=
|
||||
[Version Info]
|
||||
IncludeVerInfo=0
|
||||
AutoIncBuild=0
|
||||
MajorVer=1
|
||||
MinorVer=0
|
||||
Release=0
|
||||
Build=0
|
||||
Debug=0
|
||||
PreRelease=0
|
||||
Special=0
|
||||
Private=0
|
||||
DLL=0
|
||||
Locale=1029
|
||||
CodePage=1250
|
||||
[Version Info Keys]
|
||||
CompanyName=
|
||||
FileDescription=
|
||||
FileVersion=1.0.0.0
|
||||
InternalName=
|
||||
LegalCopyright=
|
||||
LegalTrademarks=
|
||||
OriginalFilename=
|
||||
ProductName=
|
||||
ProductVersion=1.0.0.0
|
||||
Comments=
|
||||
[HistoryLists\hlUnitAliases]
|
||||
Count=1
|
||||
Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
|
||||
[HistoryLists\hlOutputDirectorry]
|
||||
Count=1
|
||||
Item0=..\..\lib\
|
||||
24
libsrc/FlashPlayer/FlashPlayer.dpr
Normal file
24
libsrc/FlashPlayer/FlashPlayer.dpr
Normal file
@@ -0,0 +1,24 @@
|
||||
program FlashPlayer;
|
||||
|
||||
uses
|
||||
Forms,
|
||||
Windows,
|
||||
Dialogs,
|
||||
uMain in 'uMain.pas' {frmMain};
|
||||
|
||||
{$R *.res}
|
||||
|
||||
begin
|
||||
Application.Initialize;
|
||||
Application.Title := 'FFDec Flash Player';
|
||||
if(ParamCount<2) then
|
||||
begin
|
||||
ShowMessage('Wrong parameter count. This EXE is for FFDec internal use only.');
|
||||
Application.Terminate;
|
||||
end
|
||||
else
|
||||
begin
|
||||
Application.CreateForm(TfrmMain, frmMain);
|
||||
end;
|
||||
Application.Run;
|
||||
end.
|
||||
BIN
libsrc/FlashPlayer/FlashPlayer.res
Normal file
BIN
libsrc/FlashPlayer/FlashPlayer.res
Normal file
Binary file not shown.
BIN
libsrc/FlashPlayer/flashplayer.ico
Normal file
BIN
libsrc/FlashPlayer/flashplayer.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
656
libsrc/FlashPlayer/uMain.dfm
Normal file
656
libsrc/FlashPlayer/uMain.dfm
Normal file
@@ -0,0 +1,656 @@
|
||||
object frmMain: TfrmMain
|
||||
Left = 300
|
||||
Top = 617
|
||||
Width = 1381
|
||||
Height = 811
|
||||
Caption = 'FFDec Flash Player'
|
||||
Color = clWhite
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -14
|
||||
Font.Name = 'MS Sans Serif'
|
||||
Font.Style = []
|
||||
Icon.Data = {
|
||||
0000010004000000000001000800EC310000460000003030000001000800A80E
|
||||
0000323200002020000001000800A8080000DA40000010100000010008006805
|
||||
00008249000089504E470D0A1A0A0000000D4948445200000100000001000806
|
||||
0000005C72A866000031B34944415478DAED9D0B7C14D5F5C70F8F3C8090F008
|
||||
041523521031451E159AF8A041FEB4F28F88429428A08912B51A54A80F94FEED
|
||||
940AA258F081CADFA841010D1A10458A1695482B49E15F40298280881435BC02
|
||||
84040328F33FBF95B50177E6DED99DDD99D9BDDFCF673EBBB0B39BBBB373CE3D
|
||||
E7DC73CE6D448AA8E4FD8913F5FA8307E9686DADEF38C2CF8F1C3A4447F9F03D
|
||||
E2FFF911C4B76C49F149499480473EF0989092E2FB3F1C89FC7CE0E4C98D9CFE
|
||||
4E0AFB513FAA078170EFFDEC33DAC7C7DE2D5BE8787DBD23E3689C9848A95DBB
|
||||
52DB6EDD28950FA524BC87FAC15CCC5B85853F0A7ADDAE5D4E0FC7122DD2D27E
|
||||
540C571417ABFBCCA5A81FC645BC326488BE7DF9729F791E8DC09DE83460005D
|
||||
B778B1BAEF5C82FA211CA474D8307D7B7939D557573B3D1447486CD3863A6567
|
||||
53DEC285EA3E740875E123C8EB7979BE19DE6BE67CA480DB000BE1EAD252755F
|
||||
460875A1C3CCCB8306E9DB962D737A189EA4F3A04174FDB265EA1E0D23EAE286
|
||||
8137F2F3F58D656551EBCB471AC40EBAE7E6D255B367ABFBD566D405B5092CCD
|
||||
7D3C670ED5ECD8E1D8185A356942CD1B35A284C68D299E1F7124F21177E27933
|
||||
FEFF383E2F911F134E3C07C7F83872FC38D5F381E7DFF2E3515DA7637CD4F371
|
||||
F4C481730EF3E381EFBF77EC3B26A7A753CFD1A3D592A34DA88B1822C59999FA
|
||||
57959511FB7BCD5890539B36F51D6D59E053F9687BE27924D9C74A60DF77DFD1
|
||||
5E3CF2B117CFF9F8961544A4382333930A2B2BD53D1C02EAE20501D6E7D7CD9E
|
||||
4DC78F1D0BDBDFC0ACDD312E8E4E83B043D04F083D667437038BC1AF0CA01CBE
|
||||
E1C79D7C9D8E85513134E6EBD42B3F5FE51B0481BA601658306A94BE61FEFCB0
|
||||
083E04BE030BF8D9F1F1D4858F347E1EE77261B7C2177CCDBE3C7A94BEE0A38A
|
||||
95423814021441C68811347CEEDCE8B97061465D2809E6E7E6FA827A767326DF
|
||||
B0387E9690401DA34CE0CD80F0EF6425F0F99123B49D15C2D7FCDC6E10341C51
|
||||
56161B173404D40532615E4E8EBE65C912DB3E0FFEFBCF1313A90B0B7C2716FC
|
||||
581178115008DBD942D8CA0AE15FF5F5B6C611BAE6E4D0C8254BD48536405D98
|
||||
00CC1E30C097B0630710F27359E07B356B4667C7C585FE813100DC8575DF7E4B
|
||||
9B5821D8E52A20C1287FF97275BF9F82BA200D783E2B4BDF595161CB67C197EF
|
||||
C1829FC133BE9AE98303C2BF812D82F5AC08103BB0838E595934A6A242FD2027
|
||||
501782595450A0AF2B2909F973DAB31FDF8305BE271F498D1B3BFDB5A28ADAE3
|
||||
C7E96328033E76DB1033E8555040579694C4FCFD1FF317606A9B367A28C53898
|
||||
DD7BB1C0F766131F517C45F8C12AC25A7611D6B13208C5454031D284EAEA9896
|
||||
8198FDF2CFF5EBA77FBD6A55D0EF87E0F765A1CF6CDE5CCDF60E01ABA0F2F061
|
||||
5ACDCA201445707ABF7E74F3AA5531290B31F7A5971415E9AB67CE0CFAFD88E4
|
||||
F765A187E0BB3D29275640F2914F11F011CA0A42DFA222CA993933A67ED498FA
|
||||
B2D3D2D2F4604B7121F817B568E19BF55550CF9DC00A8035F0515D5DD08AA045
|
||||
870E744F5555CCFCC031F1454BB2B3F52FCBCB837A2F0A6CFAF36CAFA2F9DE01
|
||||
8A00F1810AB608822D5C3A2B3B9B0ACACBA3FE078FFA2F382931510FA669A65F
|
||||
F0B17EAFF02EC8275811A42240D3D307EBEBA35A46A2F6CB059BBE8B593E8B05
|
||||
FF223ED48C1F1DC022F88895002C82608285D19C561C955FEA892E5DF4FD5BB7
|
||||
5A7E1F9277FEBB65CB8897D62A2203CA96FF72E850504945ADBB74A13BB76E8D
|
||||
3A7989BA2F34292E4EB75AAD87001F041F7EBE22FA4176211481D54021AA0D1F
|
||||
3C762CAA64266ABE0C3AEC6E5AB8D0F2FB10D51F80DD6F94B91F53C01578AFB6
|
||||
D6B76A609573870D8B9A4EC651F1251EEFDC593FB06D9BA5F7A00C7730CFFA2A
|
||||
7B2FB64156E1DB3535964B925B75EE4C776DDBE679F9F1FC17B06AF223B03798
|
||||
677C15DD573404AB054BD922B012248C0697C0B3830F26CA7F3ACFF6D7A4A450
|
||||
B20AF2290250F3FDF7F4DAC18396AD012FAF127872D0C1D4EBC3D787C9AF5088
|
||||
587AE890E5D88057FB0D786EC0B37AF7D6ABD6AE953E1F11FEA1C9C9744E4282
|
||||
D343577888CD478ED09B353596560A3AF4EE4DB7AE5DEB2999F2D460ADAEEF2B
|
||||
935F110AC1B8045ECB17F0CC40A775E8A0D75555499F7F61F3E6F45F49494E0F
|
||||
5B110560B970E5E1C3D2E77BA9A0C813839C9294A4CB6EB3A54C7E4538B0EA12
|
||||
603BB3076A6B5D2F5FAE1FA095621EB4E41AD5AA956AD0A138097F1BF24DFCB8
|
||||
95CDFAADFCFCE77CAF145A5C0A864BF00ABB04B22DC9BC504CE4EAC15959E347
|
||||
1EFFD5ECEFAB8CBED8E4C0F1E3B48D8FCF5948716CE763CB89E7DFF071EA5D74
|
||||
330BFFAC205685A04C4A5909C8D613B83D57C0B503D388A4C3AFDDD9DC87F02B
|
||||
6283AF58D03F64015C81F6E13C1B6346AFB698D7FF5B56004F07B92C0C25B088
|
||||
DD818DEC16C8A2B954D65C3928CD82F0ABF5FDE807FB047CC8B378F909A1DF6E
|
||||
C3EEC4C15A000DB19A2FA0B950DE5C37202B667F768B16D49F0F4574B19167F4
|
||||
0F21F438B09720CFF876138A05D09015757554CE870C6E74075C35182B01BF2B
|
||||
F8C753F9FCD10384FE25FEED4BD9ACDE61C30C2FC20E0BC00FEA08DE626B4006
|
||||
B705065D3310D9A53E14F3E4B2BFDF353EDEE9212B42640FCFEC10F812F4F80F
|
||||
C306A166D86501F8C132E1829A1AA96222372D11BA6210B2493E58E3BFB6552B
|
||||
EAA8F6D8F32C68E1BD98CDFAB93CDBBF83BDFF1C1A879D16809F9DECB2BC7AE0
|
||||
8054AE805B92851C1F806C7A2F847F74EBD6AA7EDFA354B070C0C47F958F4336
|
||||
EEFEDB90389E183A75EAE43BBA76ED4AEBD6ADA3952B57063CD76E0BC00FFA0B
|
||||
CCD9BF5F4A09B8216DD8D13F2E5BD803B37FB49AF93DC7376CE2CF62F37E0E0B
|
||||
BD1D91FB86B464E1CDCCCCA45FFDEA57949595455D5898CE3CF34C6AD4200F64
|
||||
C28409F4C8238F047C7F382C003FB004E6B02520E30E385D40E4D81FB652D29B
|
||||
C73EBF4AEDF50E58A79F525747B359F043D9A9A721EDDAB5F3097A7676365D7C
|
||||
F1C5D4B3674F8A17C481CC1440B82C003F880920614806274B891DF9A3569A79
|
||||
A868BF77B053F021F003070EA44B2EB9C427F4DDBB773F697697C1290BC08F95
|
||||
D501A79A8A38A20034C9441FB5CEEF0DFC82FF3C36E90CE173E0C30F1932846E
|
||||
B8E106BAECB2CB8433BC08272D003F56F2043407E431E27F5036D14765F8B91F
|
||||
44F435BEB96760C38D103EA75FBF7E3EA1CFCBCBA3366DDAD8363EA72D003FB2
|
||||
19834EE40844F48FC976EF55B9FDEE6711FBB877D5D6069DB4939E9E4E23478E
|
||||
A4FCFC7C3AE79C73C232463758007E5E3F7850AA7620D2DD8623F68764FBF6A3
|
||||
AA0F413FB52D973B415E7E11CFFA4B83D85D0791FB2BAFBCD227F403060CB0EC
|
||||
D35BC52D16801FAC0CC854114672DF8188499926E1F7A39EFFA6D6AD95F0BB10
|
||||
98FBD3D9D49FCC87D5001F027877DF7DB7CFC46FDEBC79C4C6EC260B00E01ACE
|
||||
DEBF5FAA9F801621D98CC81F91F1FB91E8730BFB7FAA7F9FFB409EFE556CC26E
|
||||
B668EE43F0274E9C48D75D775DD867FB40B8CD0200682AF2BFD5D542251AA9C2
|
||||
A1B0FF01D94C3FA4F8AAFC7EF7F14A7D3D155ADC47CF69C1F7E3360BC0CF1676
|
||||
0390322C2212998261FD70D9F57ED5C0D37D208B6D6C6D2D3D67A1DEFDB4D34E
|
||||
A369D3A6392EF87EDC6801F8916D341AEEFC80B0FE4A9A84DF8F3DFA0AD8EF57
|
||||
B80704FA86F3AC2F5BA187F5FB5B6FBD951E7AE8214A4E4E767AF83FE2560BC0
|
||||
CFF3EC0AC8B41CD7C228A761FB6099DA7EE5F7BB0F2CEFDD5053235DB08335FC
|
||||
679F7D96FAF4E9E3F4D07F829B2D00201D0F08637E40583EB4243B5BFFB2BC5C
|
||||
789ECAF17717C8E6FBBD64D65A6BB6DA205C63C68C7185B91F08B75B0040B666
|
||||
E0ACEC6C2A282FB7FD4287E597D3244C7FE5F7BB8B89EC933E2CB9F945FFFEFD
|
||||
A9B4B4D4E7F3BB19B75B007E64E3015A18E4D5F60F9C9696A6D7EDDA657A0EB6
|
||||
EC1A6363CAA722347EC737E00C49E1BFEFBEFBE8E1871F76EDACDF102F58007E
|
||||
64E2012DD2D2E89E5DBB6CBDF0B67ED892A2227DF5CC99A6E720C9E776E5F7BB
|
||||
863B0F1DA2A72422FD30F9E7CD9B4783070F767AC8D278C5020088073CCD4A40
|
||||
D443A06F5111E5CC9C699BDCDAAA003409D35F95F7BA87DB59F89F95107E04FA
|
||||
5E7FFD755FFEBE97F092050064CB87351BE5D6B60F7AAE5F3FFDEB55AB4CCF51
|
||||
A6BF7BB8956F349935FEC2C2429AC9565DA8A5B94EE0250BC04FC9FEFDF46F41
|
||||
D6ECE9AC906F5EB5CA16D9B54D016812B3FFCD2CFCAAA79FF3C8CEFCE3C68DA3
|
||||
E9D3A73B3DDCA0F19A0500D053F0397605446836C9AE2D1F32B54D1BBD5E3068
|
||||
55DFEF0ED09F0FEBFC22EEBFFF7E9A32658AD3C30D092F5A0040A67F40224FA6
|
||||
13AAAB4396DF903F60514181BEAEA4C4F41C24FCDC959AAAAAFC1C660DCF2E97
|
||||
4874AC45461F72F9BD8E172D008040E0E37BF70A7FA75E050574654949484215
|
||||
B2446A12A6FFF0E464CA484CB4FB3A292C80DD73FBB0F08BBAF3C2E487E91F0D
|
||||
78D502009B8E1CA1D7241284B4106538A4373F9F95A5EFACA8303D070D3ED0D2
|
||||
5BE12C39070E089B783CF1C41374C71D77383D54DBF0AA05E047A68148C7AC2C
|
||||
1A535111B41C87A40034C1EC0F931F81BFB66ACDDF51FE5057477F12A4F8DE76
|
||||
DB6DF4F4D34F3B3D545BF1B20500F6B3B5364B2237400B418E837EA34C5F7F74
|
||||
F4CD565D7D1DE56D3625AF109892175E78212DE7DFD28B4B7D6678DD0200E828
|
||||
BC42A0BC43D957206805A00966FF563CEBFF96677F15F8730EF8FDDD7806D963
|
||||
B2BD36F2F9FFF9CF7FBA3EAF3F18BC6E0100CCFECFF26F784010BBD18294E5A0
|
||||
DE342F2747DFB26489E9392AE3CF794439FEA8E3FFF0C30F7D3BEE4423D16001
|
||||
00990CC1AE39393472C912CBF21C9402D02466FF3BDAB68DE435529C02FAF85D
|
||||
2058F283CF0FDF3F1A387AF428FDFDEF7FA7F2F272DAB06103AD5FBF9EB66CD9
|
||||
6278BE572C003F4FEEDB17162BC0F21B64DA7C21E1A7AF9AFD1D4514F52F2828
|
||||
A0175F7CD1E96186C461B66EDE7BEF3D5AB46891EFD8CF0A4F162F5900008941
|
||||
4B05564030EDC32C2B004D30FB23E9E79E76ED9CB8468A132C63C1FF8D49D349
|
||||
F8FB5BB76E8D688B6EBBD0D9A259BC7831BDF4D24BB46CD9323A24B9F7DEA978
|
||||
CD0200D3F6EC112607691665DAD2C90B468DD2D7CF9D6B7A0E9A7C5CE8C11B2B
|
||||
9AF87975357D6A525B3E977F43ECCAE32520F8A848449622CCFB50F19A0500D0
|
||||
3404CD43CCE8316A140D9F3B575AAE2D2900517F7F95F2EB3CA8EDBFD36456C4
|
||||
921F7C652F34F40010FC3973E6D0D4A95369E3C68DB67DAE172D00991461ABFB
|
||||
09489FF85661A1BEA6B8D8F41CB5EEEF2C58F6EBB26F1F551BDC20717C7CB46A
|
||||
15F5EDDBD7E9A14AF1C1071FF8BA0D9B05F382C58B160090C90BE85358485714
|
||||
174BC9B6B40210CDFE98F5C7F1EC9FE89199251A1165FC7925F0575353E3AB46
|
||||
7CE6996742FE2C28BDB39B34A1F39B36A55E7C9CC74737FE77778F96A5637BB1
|
||||
196C051CB3C90A9096564D10FC534D3E9DA713CFFE46BBF562634E04FEDAB76F
|
||||
EFF4304DF9EB5FFF4AB7DC720B6DDFBE3DA8F7A7B3700F8D8FA70B58083220F0
|
||||
FCEF689B94649A886A92B22D75527166A6FE5565A5E1EB98FDC7B66D4B498D1B
|
||||
3B7D6D62162CF9E59844FE911073EFBDF73A3D4C43E0EB1715150535EB63561F
|
||||
9E904043F9E8E3D199DD0A3256C019999954585929946F2905A009667FD5ECC3
|
||||
79AE397890CA0CF69FC7ECBF73E74E57EDDAD31098FCB9B9B9BE653D5960DA8F
|
||||
4A4CA4BBD9F2F4AA391F0A324D433409F9169EF0FEC489FADF264F363D47B5FA
|
||||
7216E4FA77C48C60F0BA9B7DFF6DDBB6D1E5975F2E1DE187E08FE109E76E16FE
|
||||
B3E3E29C1EBE63C8B40EBB64E2441A3879B2A98C0B15C0F4F474BD66C70EC3D7
|
||||
DBB3E0DFAA1A7D3ACA34F607EF33591F5EB972A52BF3FD57AF5E4D393939B467
|
||||
CF1EA9F30B58E8272525D119CAD5F48152E1DD26F91EC9E9E9347EC78ED01480
|
||||
2630FF07F20F72914AFC719473F7EDA3CD06C1BF1E3D7AD0279F7CE2F4107F02
|
||||
847FE0C08152997C1D58E05F60F7657094952B878A4C6290269071D317DFC8CF
|
||||
D73F9E3DDBF40F8C4F4D55C13F07A938768C2E32C9817763971F28A4ECEC6CA9
|
||||
DC7DCCFA7FE649A695BAC77E422DBB7ED3D9F533A3677E3E5D357BB6A19C9B2A
|
||||
80294949FA51130DA3DA7D39CF4D35355462B00B7333F69511FC6BE322170D3E
|
||||
FFC5175F4CDF7CF38DE979C82A9DCDB3FED56AF35853446DC3E259793E505B1B
|
||||
9C02D004E6BFAAF9779E54F69F8D32FFF2F2F2E8D5575F757A883F02A1472AB2
|
||||
688DBF1DCFF66FA7A450DF180EF2C922D32B40339173C3175E1E3448DF66B22C
|
||||
83B5FFBB55DEBFA3A0E63FC32412FCFEFBEFD3A5975EEAF4307D609D1F3EFF72
|
||||
411BB99F376D4A4BD9AA54813E39900BF0982027A0F3A04174FDB2650105D550
|
||||
7A35C1ECDF837DB3AB5CBAAE1C2B14B3F6BFC540FBB76BD78E76EFDEEDF4107F
|
||||
64C68C19347EFC78D37390D0F321CFFCAA89AC35DE603770BD811BE8473390F5
|
||||
A015C0B5ACA5BBAAA8ACA398F9FF575C7105BDF9E69B4E0FD107827E175C7001
|
||||
1D33A925410A6F45EBD6749A9AF92DF3055FD7398280AA664501BC9E97A76F28
|
||||
2D35FC30D5F4C31D982DFFB925F517ADBA20FC6635FCF0F92B79E68FE5C49E50
|
||||
11350BC9C8CBA3AB4B4B7F22EF0115C0B4B434BD6ED72EC30F53A9BFCE83D2DF
|
||||
36264B4068F6D9BF7F7FA787E933FB61FE1B81C6A4157C2FC5420E7F38111508
|
||||
B5E8D081EEA9AA9253009AC0FC1FCDA69AD2D6CE6256FC03A13AC0AF39DDF20B
|
||||
F5FC08FC998135FE712A912C64B6F0FDF0AA493118D002C87B500AE07E36FF55
|
||||
F4DF59CC6AFFFBF4E9E3EBF5EF24D5D5D5D4BB776FDA6192463E283E9EDE5579
|
||||
24B620B31AA0C92880D261C3F44D0B171A7EC8993CBB14B005A0709681ACED97
|
||||
1B24808C1D3B969E7CF24947C777EDB5D752A9491C097EFFBA366D54D0CF464A
|
||||
F6EFA77F9B045ACF1D368CF2162E3C49E67FA200A6B669A3D79BAC2DABC61FEE
|
||||
A08549D0C7E9A69F6BD6ACA15FFCE217A6E7CC4F4951597E36236A1796C80A77
|
||||
4275B5B902D094FFEF7A4409405F7EF925A5A7A73B36BEA14387D25B6FBD65F8
|
||||
3AF2FB5F503924B613CC72A02505A0B2FFDCC12BF5F534AAA626E06BE8F9FFF5
|
||||
D75F3B3636ACF9F7ECD9D3F0F54E4D9AD0273C89A80232FB09260E70D23F5E19
|
||||
3244DFBC78B1E19B95FFEF0E26D4D6D2A3064B3EC3D8CF5BB0608163631B3E7C
|
||||
382D3489217DC8F7CF25CA820C1BA238C0394386D0758B17FF28F727290051F5
|
||||
9F6AFBED0ECC0280D83863E2C4898E8CEBD34F3FA58C8C0CC3D755D43FFC88E2
|
||||
00A756079EA4003481FF7F236BEF8E4A7B3B8E5905E05FFEF2171A3C78B023E3
|
||||
1245FED5EC1F7EACC601A41580F2FFDD017EE09F99FCC0F0FF1107883498FD7B
|
||||
F5EA6598EF0FC1FF50B98F11E1619E2064E3003F3E11EDFCA39A7FB88345478E
|
||||
D0B0830703BEE66405E0F5D75FEFDBC2CB88F7F9DE19A08AC72282A84948C39D
|
||||
837E54002FF6EFAFEF58B1C2F04D6AFDDF1D986500C2F4870B1069D0D63B95AD
|
||||
43A3D93F8B67FF8FD4EC1F31447180F4FEFDE9C6152B4E5600D33A74D0EBAAAA
|
||||
0CDFA4BAFFB803E4FF2F35D0EED84E6BCA9429111F135A8EDF74D34D86AF2FE1
|
||||
D95F35F48C1CA22E412DD2D2E89E5DBB4E56009A0A007A82D3F7EEA5AAE3C703
|
||||
BE367FFE7CBAE69A6B223E26741D32EAF483FDF8D6B8A827612C20B367807642
|
||||
F6A515C0BDEC5F46DB1E6B5E031B80A49994007FFEF9E7D4B973E7888E09C53E
|
||||
679D7596E1EB4FB0E53856598E11055B873D2AD86B41B3A20054031077605602
|
||||
8CEDBF0E1E3C488D22ACA41F7DF451BAEFBEFB02BE067B717B6AAA2AF8710051
|
||||
8310ADA102106DFFA53200DDC1D4C38791C411F03534FF4013904873FEF9E71B
|
||||
76FB51893FCE21CA08F46F1BE65300F37373F58D65658627F766136E88EA00E4
|
||||
38B93CC32F34D80074DCB871347DFAF4888E4794F9F7627232E5272646744C8A
|
||||
1F587CE810AD35D93CB47B6E2E8D282BFB41013CD3A387BEDBA4671B96FF2E54
|
||||
5D5B1CA7F3BE7DB4DDA007E04B2FBDE45B8B8F24D8CAFBF6DB6F0FF81ADCC65D
|
||||
6ACB78C7106D1BD6BE470FBA6DFDFA1F14C0A4C444FDB8495B61D501D879443D
|
||||
003FFEF8639F391E49468C1841AFBDF65AC0D786252450594A4A44C7A3F80FA2
|
||||
16618DD9327BB0BEFE0705A00956006E674DAE7AB53BCBDFD89FFB95410A30B6
|
||||
00430FC0F8082BE9D34F3FDD708BAF67D865BCD562F41FD1EB437CF8B31C603B
|
||||
A0552882895881C21DA852D1E5D8C796E2D36C319AA111C9298007DBB777FAFB
|
||||
C43C33D8A4FB9D8149E7440FC0CD9B3753B76EDD0C5F47F61F76F769CEB7D861
|
||||
16EA3A3E0EF081C834FE5DC3079C995A7EFC8E8F63F27F9AFCD9284DF9B3FD2A
|
||||
269E9FE380D2883FF1EFF1ECB6C6720C6292202D5C935100AD78E6BF832D0085
|
||||
B3E4D7D4D0CB066E5A6161213DF7DC73111D4F717131DD7CF3CD4E5F1653A624
|
||||
25D184188E5D3DC916C001839811D06414C0E94D9BD21895C9E5384800DA6390
|
||||
01F8F4D34FD36DB7DD16D1F1888A7FDC40AC2B80E7ABABE9EBEFBE337C5D9351
|
||||
00AA0AD0792AD8FFBFC8A40418E63FDC804872F6D9670B77F9759A585700A2AA
|
||||
400D0A409404D42D218146A868AEA34C64DFFF618316604EF40044E00F0140B7
|
||||
13EB0A60FEC183F49941DE08403250A3254545FAEA99330D4F524940CE733E9B
|
||||
72FF3230E59CF0FFE7CD9B47A3468D72FAB20889750520DA35B86F5111357A23
|
||||
3F5FFF78F66CE393D43E808E22EA00841D80B113702441F20F9280DC4EAC2B80
|
||||
A5870ED16A936CC09EF9F9D4489406AC1A813ACB53FC03DE6950DB8D02A0AAAA
|
||||
AA88EF01880620C83BA8E7D9A596DD131C757575F42D8F15C7617657F088D771
|
||||
24262652120B63C303FF87FC85047631F11CDFA5499326BED7F0FF286AC2CEC2
|
||||
DFB1E5E33F8EB0398BA623FE7FE3B3274C98404B972E0D38CE585700A20D4391
|
||||
0EDCE8E54183F46DCB96199E04E1EFAF148063987500C6CC0F0B2096316B441A
|
||||
EB0AE02316FEF74DD2813B0F1A448D9ECFCAD2775654189E04F3BFAFAAE77684
|
||||
0327EAFF8D92645E78E105BAF1C61B9D1EA6A398A523C7BA0280F9BFD4A433D0
|
||||
199999D4E8E98C0C7DCF860D8627A95660CE61B6031070AA03B09B501680311B
|
||||
F8FE596072FFB4CBC8A046D3D3D3F51A932D9CAF4949A173D5268E8E702DFF78
|
||||
F30DA2B8FDFAF5A37FFCE31F4E0FD17194023066D39123F49A410769909C9E4E
|
||||
8D44BB01ABCD409D017DDD53D9FC3F64D0D5C5C91D80DC845200C6883609C16E
|
||||
C18D26C5C5E9C74D3A87DCCC277568DAD4E9EF127320F037D0A49CD389F25F37
|
||||
A21480313B59AE5F3451008D7962172A00D50DD819B0F4F794C11A6EA74E9DE8
|
||||
8B2FBE707A88AE4029006344DD817D0A40B900EEC4ACFBCFD8B163E9C9279F74
|
||||
7A88AE40AD021823E502A820A0FB40DAEFF9264AF9DD77DFA55FFFFAD74E0FD3
|
||||
15280BC018A920A068197078723265C47053052740E38F1906195CC898DBBB77
|
||||
6FC4BBFFB815A5008C11ED10E45B062CCECCD4BFAAAC343C4925024516B4C54A
|
||||
3389FE63E71FEC00A4F801A5008C914A0412A5020FE48B78510C5FC44853CC3F
|
||||
DA2D263F1A36FFC426A08A1F50310063A4528145C5406A57E0C8D2877DFF7506
|
||||
A5BF88FE6FDBB62DE2BBFFB81965011823550CA4CA81DD83A8F3CF238F3C42F7
|
||||
DE7BAFD3C374154A011823550EAC1A82B887913535F4AA41EA6F5C5C9CAFF4B7
|
||||
8DEACF78124A011823D51044B50473071BD9ECEFC5E6BF514AD6E8D1A3E9E597
|
||||
5F767A98AE43C5008C916A0986279A6A0AEA3866B33F58B97225656565393D4C
|
||||
D7A12C0063A49A829E78A2DA823B8868F67762E30FAFA0148031B6B405571B83
|
||||
841FD1EC8F757FACFF2B7E8A5200C6D8B23108505B83850FCCFE192669BF3D7A
|
||||
F4F055FEA9A5BFC0280560CCC37BF6F8CACA8DD0641580DA1C347CE4B09FB6D4
|
||||
C44F5BB060010D1B36CCE961BA16A5000263697350D1F6E0792929748E2A08B2
|
||||
9D45478ED03093620DE5FB8B510A20309BF9DE2A35B9B74EDA1EFC991E3DF4DD
|
||||
EBD71B9E8C4CC00B63F442860BE4FC9FCBA6FF0E131FCD899EFF5E432980C020
|
||||
03F03D9334E0F6EC5ADEB67EFD0F0A40940EAC9281EC6702FF388F9AA469AA9E
|
||||
7F7228051098C5870ED15A932C40A4018F282BFB4101889281CE8C8BA382D6AD
|
||||
9DFE4E518368D90F38B1E1A717510A203025FBF7D3BF4D3A7D210968E0E4C9FF
|
||||
092D6B2681C0667CDA3DEDDA39FD9DA20244652F3970805699FC38D8EA1B5B7E
|
||||
2BC4A84CC0C04CDBB387BE15AC00E0514A01807B590124AAA5A890316BF601D0
|
||||
E77FD3A64D949C9CECF4503D81B2007E0AE24B8FB2023043B3AA005477E0D079
|
||||
FBC811BAC224320BE6CE9D4B23478E74749C2B56ACF0EDBBF7FDF7DFFBF6EB6B
|
||||
F8084EFDBF501EC1A99FDFF06F3424D0FB27B3EB8AF10622561580A81B30D04E
|
||||
5500D3D2D2F4BA5DBB0CDFA076080A8DAF8E1FA79EFBF651B589593660C000FA
|
||||
E0830F1C1D2736FE4C4D4DF56DC2E975625501885A81B5484BA37B76ED3A5901
|
||||
BCD8BFBFBEC3409302B54B70F0608FBF4BD9EF5F6792978D5E7FEBD6ADA3CE9D
|
||||
3B3B3A56F8D3F0ABA381585500E57575B4820F23D2FBF7A71B57AC385901BC55
|
||||
58A8AF292E367C93AA0A0C8E5A16FEFE02E1076EC9F7C766A32525254E0FC316
|
||||
62550188AA00FB1416D215C5C5272B00A099C401E21A35A2FBD54A802520FCFF
|
||||
C53EFF2A81395DC83FC873CF3DE7F4707DB46FDF9EF60802485E211615005699
|
||||
1EC38ED2122B00405A0100B54B903C88C4FE8635F1DF04C28F629FCACA4A6AEE
|
||||
821B75F5EAD5BE04A468211615809500203849018876095271003920FC393CF3
|
||||
2F3731C300FC7E08FF79E79DE7F4907D4C9A3489FEF0873F383D0CDB88450520
|
||||
F2FFB11BD084EAEAC00AE0952143F4CD8B171BBE5965048A81E975250BFF5281
|
||||
F0376BD68CDE79E71DEADFBFBFD343FE915FFEF297B46AD5AA80AFB5611730B5
|
||||
7163A7876889DFB1F017C6D8CA952803F09C2143E8BAC58B032B00A009E20077
|
||||
A7A6FA1E153F05C29F5B53438B4DFAB00108FFDB6FBF4D975E7AA9D343FE91DD
|
||||
BB7753C78E1D0D97FFE6A7A4D0D5AA22D4D558F5FF81250500D466A181C152DF
|
||||
0D870E4909FFA2458B5CB7B71F1A8EDE70C30D015FC3AFBD8B157F2B8F5900B1
|
||||
86683350A08914808A035807FDFCAFE599DFACB417A0B5775959992B4B7CCD52
|
||||
6A07C4C7D3FB6A09D8F588360239D5FF073F5100A5C386E99B162E34FC101507
|
||||
3899297575F4473E447973107E08981BBBFB1CE69B06E6FF7E83D9E391A424BA
|
||||
27C682695E44E4FF9FCBF75EDEC285E60A0068023700F900B11E07406AEFF53C
|
||||
EB8B22FD00C28F1C7F3724FA04E2C9279FA43BEFBCD3F0F50D3C7374577520AE
|
||||
067EFFC39205400D094A015CCBE660D718DE9E1A453D37B1BFBF87958008083F
|
||||
32EB9C2EF031E2282BB06EDDBAD1F6EDDB03BEDEA94913DAA6BA42BB9E60FC7F
|
||||
1050014CEBD041AFABAA32FCA058DD3014EBFBF7B19FF59449A7958640F867CD
|
||||
9AE54BAF752B66C13FF03F2D5AD01F55CCC7F588F6016C5800D490800AE0F5BC
|
||||
3C7D83414008C46283106CDBFD07F6F5AB24667D809D7C5F79E51557EFE6A3B3
|
||||
42CBC8C8A08D1B37067C1DBFF30E36FF554768F723DA0320232F8FAE2E2D9553
|
||||
004053CB813ED0B917FDFB360B22FC0D81AF5F5C5CECFAA61E6FBDF5160D1D3A
|
||||
D4F0F5716CE9FD39062D3DAF11ACF90F0C15C0A4B838FDB84944B14762225DE5
|
||||
F21B3C1490C30FC1AFB050178F35FE993367BADAE46F8859E61F54FBB6D4543A
|
||||
43ADFDBB1ED12EC040B3AA005E1E3448DFB66C99E107466B56E0BFBEFBCEE7E7
|
||||
8B52794F05453D58E6734B5EBF08341E193870A0E1EB05ACE05F8862051F2DC8
|
||||
64FF751E3488AE5FB6CC9A02009AC00D88A62E4130A3FEC87E3EF6E8B3DA0B67
|
||||
ECD8B1F4D8638F51BC47564610F9EFD5AB97A1EF0FD4D29F371075FF019A899C
|
||||
9B2A80294949FA5193CD05A2A14908D6F11FE78B284AE10D44EBD6AD69F6ECD9
|
||||
AECCEC33E381071EA0871F7ED8F0F5DC84047A2D25C5E9612A241035FF884F4A
|
||||
A2076A6B8353006FE4E7EB1FF30D6EC6787603923CE62762396F0ECFF458CEFB
|
||||
97A0534F20B0BC57545444BFFFFDEFA98DC7B64E5FB3660D6566669AF6FCFB3F
|
||||
FE4E7DD4ECEF7AD070663A9BFF66F42A28A02B4B4A8253004013B8015EDA360C
|
||||
D97B4F1D3E4C252CFC32493CA702C1CFCBCB234DD31CEFDD170C30FD2FB8E002
|
||||
5A6FB20DDC109EFDDF54B3BF27106DFF0534818C0B15C0F4F474BD66C70EC3D7
|
||||
DBF34C71ABCB674144F2D18BFF4D36F383ED753B78F0609A3A752A9D7FFEF94E
|
||||
7F9DA079F0C107E94F7FFA93E1EB2D1B35A24D6DDBD2691EB3E8629559D5D5B4
|
||||
DBC4824D4E4FA7F13B7684A60044DB8601B7EE198035FC497575C2869C66A045
|
||||
16FC6537D5EE07838CE9FF627232E527263A3D548504557C4F3F6752B50BFCDB
|
||||
7F999D23B586A709DC80BECD9AD160176E1E3AF4E0C1A0827BA06BD7AEBE19DF
|
||||
8DD57B5641B51F84DFCCF41F141F4FEF7A3CA01B4B88527F812621DF520AA038
|
||||
3353FFAAB2D2F075E4028C4B4D75DDD661B9AC00165A540068D185CAB8ABAEBA
|
||||
8A1AB9ECFB0403D27D73727268E9D2A586E7C0F4FF944D7F95F4E30D10C49E21
|
||||
58FB3F83157E6165A53D0A0068022BC08D0542B2160032F810DCBBEBAEBB3CED
|
||||
E307E28E3BEEA0A79E7ACAF49C67D87ABB354AF239620151E30FA049CAB6B402
|
||||
989498A81F37493774A315205200D888F3F6DB6FF7F5E5473FFC6863C68C1934
|
||||
7EFC78D37354B71F6F2133FB378E8BA3078F1DB3570188760E026815D6DF45A5
|
||||
A3660A005B704340BC92BD671551A10F80E9BF8E853F168ABAA205B4FC2E3769
|
||||
FB0D1AEEFC23C2D2742D2A1042F9E85D2EAA0F3053004F3CF184CF3C8E4610F1
|
||||
CFCECEA6432629A210F97758F80744A9028C4630EB3FCEB3FFB736CDFEC092A4
|
||||
2E18354A5F3F77AEE9396E4A0C325300D3A74FA771E3C6393D44DBD9BC79B34F
|
||||
F8BFF9E61BD3F3D4929FF79049FCE9316A140D9F3B373C0A00C858016E691662
|
||||
B60A108D0A0033FF65975D26DCDB4F75F9F126D3F877359BFD816651A62D2B80
|
||||
F9B9B9FAC6B232D373DC5225184B2EC08A152BE8F2CB2F3735FBC1F53CEBCF56
|
||||
65BE9E036BFE4B05BF6DF7DC5C1A5156165E050034C19260AB264DE80E173492
|
||||
8C150580801F9631BF1524865CC2FEE17BECF7BB2546A39047D4F20B6841C873
|
||||
5077C2BC9C1C7DCB9225A6E7B8C10A888518C0BC79F3A8A0A0C034C5179CC34A
|
||||
B9B2756BB5BB8F0791A9F93F75CF3F59829E0A34092BE0B76DDA383ADB44BB02
|
||||
78F4D147E9BEFBEE139E87D6DEEFB3D9AF96FBBC0722FFCF56578765F607414B
|
||||
E7EC0103F4EDCB979B9EE3F43662D1EA02D4D4D4F866FD85263B38F939AF6953
|
||||
5F8EBF4AF3F526A2EDBE41A70103287FF9F2C82A00A009AC00CCFEBF6DDBD631
|
||||
B3D36C15C0AB0AE0934F3EA1DCDC5CDAB2658BF0DC7E3CE3BF9392A2CC7E8FB2
|
||||
8F677D54FC1DB339F2DF909014C0F35959FACE8A0AD3739C6C1B166D2EC08B2F
|
||||
BEE8EB44240AF60124F8BCC966BFD7BA3529FE83A8DD17E8989545632A2A9C51
|
||||
00401358016038DF88190E249D448B0B80725E083EB61893015D7DCAF89AAB68
|
||||
BF77D9505F4F0BD8D513A18528C321DF218B0A0AF475821B130141340D8974A1
|
||||
503458009F7EFAA96F89CFAC96BF21AA9DB7F79149F905A27E7F32D8229153DB
|
||||
B4D1EB05DD499C2817F6B20580FE7D0F3DF490AF298968890F20BEFF47BEBE13
|
||||
5C9286AD081E9972DF449E50275457872CBFB64DC99A842B10E9D6615EB5002A
|
||||
2A2AE8A69B6E32EDDBDF900EECE7CF4F49F125FA28BC8D4CAB2FA0D924BBB629
|
||||
0051D7207026DFA005AD5BDBF5278578AD1600CB7B68352E6AE0D11004FB4AD9
|
||||
E46FA7827D5141C9FEFDF46F81C527DBED47065B9D7251A110886486A0975C00
|
||||
A4F36287A11D261D984F4515F5441732197F40B3516E6D55004B8A8AF4D53367
|
||||
9A9E83C8F4EDEC0A244760CB692FB800AB57AFF665F32D1724553504B33D0A7A
|
||||
06AB5AFEA8A1E6FBEFE9698935FFBE4545943373A63B1500989696A6D7EDDA65
|
||||
7A4EA45C01375B00DBB66DA3FBEFBF9F5E7BED354BEF43F75ED4F2ABCCBEE8E2
|
||||
7916FEAF05EDEB5BA4A5D13DBB76D92AB3615997D3240282915815709B024087
|
||||
DEFDECE36167A159B3664945F7FD60D67F8CAFD768D5C423EA9089FA032D0CF2
|
||||
1A160550929DAD7F595E2E3CEFDA56ADA86B18CD5837B900E8D083E0DE4C7691
|
||||
4435FB3FB94E2CF48FB3F0AB405FF4B199EFCF52BE4F458492EF6F46D8327344
|
||||
5D8441B313B502E14A5775C32A0072F7B175786969A9A5191FA4376942CFB66C
|
||||
A97CFD28057EFFFFB2E92F4AF869CC13C083F5F56191D5B0A6E66912AEC0E94D
|
||||
9BD29830ED2DE8940B0053FF9D77DEA169D3A6590AEEF9C16AFE9866CDE8CF3C
|
||||
EBBBA9CDBAC25E64FC7EA085514EC37A77C9B40F03E18A07445A0120671F0D3A
|
||||
D06E5C3689E75490C73FB5450BEAEEC2BD1615F621EBF767E4E5D1D5A5A5DE54
|
||||
00E0892E5DF4FD5BB70ACF0B473C20523180DDBB77FB7C7B04F6440D398DE8C5
|
||||
02FF049BFB2A9B2FFAD972F428BD7AE080F0BCD65DBAD09D5BB786554623625F
|
||||
CAC6036EB1393F20DC0A00FEFDE38F3FEEF3EF654A7403816E3D0FF18C7F9D8A
|
||||
EEC704D27EBFC5FEFEC112310753938807B4E759F0A6D6AD6D2B630D870B80F5
|
||||
FB575F7D95E6CF9F2F5DA11708E4EF8F63D7E72EF6F555D96E6C80249F17F6EF
|
||||
A7DD0EFBFD0D89D89D573A6C98BE49A285959D0D44ECEA088425BC3973E6D082
|
||||
050B68D5AA55218DE9E7ACE4C6B3E08F645F5F097EEC00E1C7729FA8C1073877
|
||||
D830CA5BB830BA140078BC7367FD00CFA022BAB3705C9D9212F2DF0BC50580D0
|
||||
BFF1C61BBEA0DECA952B431E0B32F8EE66C11FA496F46292D7F95EDC28B15375
|
||||
ABCE9DE9AE6DDB222697119F8264E201A02F9BC6835BB60CE96F59550028C479
|
||||
F7DD777D267E30CB77A782705E017F8F3BF95051FDD8051B7AAC9688118573BD
|
||||
DF08476C504D221E0042DD6D58140340A79DF2F2727AEFBDF768D9B265B47DFB
|
||||
765BBE1F32F66E65A12FE24365EFC53632BBF9FAD11C90474714C0EB7979FA86
|
||||
D252A97343291F365300AD5BB7F6E5E5DB095A7063B647BEBE4AE051C896F782
|
||||
70AFF71BE1D85D2AB3AF809FBC94143A2721C1F2DF3053007681E5CB1CF6EB61
|
||||
EAAB945D851FD91C7F10AE3C7F191C9DA666F5EEAD57AD5D2B3C0FD172AC0C74
|
||||
B49824132E0580515CC60A69041F57B0D0ABD6DB8A86EC3C76CCD7D25B54DB0F
|
||||
3AF4EE4DB7AE5DEB981C3A6EA7CA660A62A61DCD66BB959E82762A0008FDC52C
|
||||
EC7958A1E0436DB6A108047AFACD61D75294E8032291E927C2710500A675E8A0
|
||||
D7555509CF8312B8D68225609607200B76D719C93E3D045F05F4146660E6478A
|
||||
AF8CF0B7E8D081EEA9AA725CFE1C1F809F294949FAD1DA5AE1797007B0D1884C
|
||||
4C20180BA0257F7E36CFF4D92CF8D7B0E0ABCE3B0A1990DF5FC6F79B8CD96F57
|
||||
4B6F3B70C520FCC8E6080099D5011905005B229385FD372CF4E8B09BA58A7114
|
||||
16B112ED7762ADDF0CD70CC48F4C67613FA23C01230580CABB5FB3B00FE403D5
|
||||
776AC94E112C56D6F92355E06305570DC68F26992804CC3206FD3100E4DF0FE0
|
||||
8B3FE08469AF02780A3B90CDF0F3A3B950DE5C37203F9A052560543BB0E6BBEF
|
||||
E84C167615BC53D88D6C6EBF1FCDA5B2E6CA41F9B1E20EA08A100943AAC24E11
|
||||
4EEA75DD27FC32557DC08D667F435C3B303F560283E827701D2B81486C3AA288
|
||||
3D6A8F1FA7B9070E48D5F303B705FC02E1EAC1F991D97DD80F7205AE642510CE
|
||||
76E38AD803A9BD6FD6D448ADF103372DF599E1FA01FA914D16F2E3C476E48AE8
|
||||
44B681A71FB724F9C8E08941FA914D1BF6832DC89034A45C024530A07FDF029E
|
||||
F545BBF536C40DE9BD56F0CC40FDC81610F9814B3054327350A1F083CCBE4507
|
||||
0F4A9BFCC0E9C29E60F0D460FD582925F663478721456C60D5E4074E96F48682
|
||||
E706ECC74A53113F7009AE4A495189408A80C0E47F8D677D99DD7A1AE254330F
|
||||
3BF0E4A01B62255700204F60705252D05D8614D109F2F997F2CC2F53CCE3C7ED
|
||||
6BFC32787AF07E64BB0D3704D6005C022BFD0514D107EAF791D26B25D00722DD
|
||||
BD375C78FE0BF891DD77E054101BC072A1CA208C2D30D3C3D7B792CBEF27927D
|
||||
FBC34D547C898658750900560AFE9BAD810CB53D574CB0A1BE9EFEC2B3BE9508
|
||||
3FF042669F55A2EACBF8B19A2FE007F5044392935590304AD9F7FDF7BE59FFB3
|
||||
20BA44796D7D5F96A8FB427E64B7263F15B80259CD9BD3457C28B7203A80B9FF
|
||||
D1E1C354C18795209F9FEEB9B934A2AC2C2A6F86A8FC520DB1524CD490564D9A
|
||||
D0C0162D945BE07110DD5FC1827F80677FAB44A3C97F2A51FDE5FC946467EB5F
|
||||
969707F55E280258047DD5B2A1A74070AF2248C1075E4DECB14AD47FC1864C4B
|
||||
4BD3EB76ED0AEABD500417B012E8ABB6F3762D30EF21F8FFC747B082EFA5421E
|
||||
3B88992FEA67495191BE7AE6CCA0DF8F1583BE6C1164F2A17A09BA0334E958C5
|
||||
B3FD3FF8B01AD96F48DFA222CA993933A67ED498FAB20D29CECCD4BFAAAC0CFA
|
||||
FDB002600D5CDCA28552040E01C1FF7B5D9D6FD60F26B8E7E7F47EFDE8E655AB
|
||||
62F2478CC92FDD102BCD46020145D02B31917AB3325059859101D97B6B59E8D7
|
||||
D5D78724F85E69DA114E62FACBFB595450A0AF2B2909F973D092EC7C560638D4
|
||||
7E81F682765C9FB0C0E3906DC96546AF8202BAB2A424E6EFFF98BF000D793E2B
|
||||
4BDF595161CB6721A9A84742826F1951050D8303B33B5A71AD61A1976DC229A2
|
||||
6356168DA9A8503FC809D485084030FD068C80F09FCB8A00D58767AB5D87A440
|
||||
338E7FB1D06F62E10FC5C46F48AC2CEB59455D10135E193244DFBC78B16D9F87
|
||||
1504C40ACE62EBA0132B036519FC00847CFBB163B495051EC21FEC125E20BAE6
|
||||
E4D0C8254BD48536405D18099056FCD99B6F92D52223112849C6F133B6103A36
|
||||
6D1A330A0102BF93FDF8CF59E0B7B3C0EF6181B76BA607A8D3EF367468D4A6EF
|
||||
DA89BA401658306A94BE61FE7CDB150180F0631501B1832E7CA4459942F882AF
|
||||
D9972CECF0E511C5B753E0FD40F033468CA0E173E746CF850B33EA4205C15B85
|
||||
85FABA397328981A035920FC1DF9863E8D15018E56AC14DAF2FFB93DE7006BF3
|
||||
30E1AB58E0F7F2E3372CEC3BF9793804DE0F04BF577E3E5D515CECEE8BE342D4
|
||||
050B9150138AAC8238422A2B041C6D9B34A176FC8823D225CC28ADDDC7C20D21
|
||||
C7F3BD78CE4728997856392333930A2B2BD53D1C02EAE2D9C4FB1327EA1FB355
|
||||
50B36387237F1F16430B5602CDF931811FE3F9B1393F363DF15AB313FF877588
|
||||
447E8E73A04CBE6381854373E4F871AAE703CF8FF2FF7D8BE7FC8815F7C3FC1C
|
||||
FF87730E9F98E19D22393D9D7A8E1E4D03274F56F7AE0DA88B1806DEC8CFF7F5
|
||||
22385A5BEBF450A282F8A4243AEFEAAB55E24E18501734CCBC3C6890BEBDBC3C
|
||||
2C81C368067E7DA7EC6CBA7ED932758F861175712308F6328032B0B2C7612C81
|
||||
525C08BD577BEC7B1175A11D04F9055F7CF00185528CE465508C03818F960EBB
|
||||
5E445D781781CCC31D1F7D14B50A01029F7ED14574DDE2C5EABE7309EA877031
|
||||
C837D8B7650BEDDDB4C9736E438BB4344AEDDE9DDA76EDAAD6E75D8CFA613C08
|
||||
961CF77EF619EDE3632F2B887026249981A699A92CE06DBB75A3543ED4D29CF7
|
||||
503F58940225517FF0201DABABA323870ED1117E8E65C9233535BE7FE3F9517E
|
||||
04F12D5BFA96DA12F8312139F987E72929BE7FC7A1E3113F57C21D9DFC3FB05B
|
||||
459D4B95757A0000000049454E44AE4260822800000030000000600000000100
|
||||
0800000000000000000000000000000000000000000000000000000000000202
|
||||
04000505070004040B0003030E0004040D0008080B000A0A0E000C0C0E000404
|
||||
1200050514000C0C100006061A0006061D001111160015151A00060621000707
|
||||
280007072C001B1B20001D1D22000808350008083B0022222800242429002828
|
||||
2E002E2E2F0036363A0039393D003C3C3C000808470008084B0008084D000707
|
||||
50000808530008085A0008085F003E3E42000909660009096A000A0A71000A0A
|
||||
76000B0B79000B0B7D004343470044444700464649004A4A4C00535354005757
|
||||
57005B5B5D00666667007171710077777700787878007D7D7D00000080000606
|
||||
83000B0B8100090984000C0C85000404890005058F000C0C890016168B001717
|
||||
8C00070790000D0D91000D0D96000606990006069D000D0D9900222291003434
|
||||
9A003E3E9E000707A3000E0EA0000E0EA6000707A9000909B1000F0FB2000909
|
||||
B5001010B4001010BA005050A7005757AB007272B8000E0ECE001111C2001111
|
||||
C9001212D1001212D6001010DA001010DE001313E1001414E3001212E6001414
|
||||
E7001414E9001515EE001414F3001515F5001616FA001515FE00808080008A8A
|
||||
8A008D8D8D00929292009A9A9A009E9E9E00A1A1A100A7A7A700AAAAAA00B0B0
|
||||
B000BDBDBD00C9C9C900D0D0D000D7D7D700D9D9D900DDDDDD00E2E2E200E5E5
|
||||
E500EBEBEB00EDEDED00F1F1F100F5F5F500F9F9F900FEFEFE00000000002F26
|
||||
000050410000705B000090740000B08E0000CFA90000F0C30000FFD21100FFD8
|
||||
3100FFDD5100FFE47100FFEA9100FFF0B100FFF6D100FFFFFF00000000002F14
|
||||
00005022000070300000903E0000B04D0000CF5B0000F0690000FF791100FF8A
|
||||
3100FF9D5100FFAF7100FFC19100FFD2B100FFE5D100FFFFFF00000000002F03
|
||||
0000500400007006000090090000B00A0000CF0C0000F00E0000FF201200FF3E
|
||||
3100FF5C5100FF7A7100FF979100FFB6B100FFD4D100FFFFFF00000000002F00
|
||||
0E00500017007000210090002B00B0003600CF004000F0004900FF115A00FF31
|
||||
7000FF518600FF719C00FF91B200FFB1C800FFD1DF00FFFFFF00000000002F00
|
||||
20005000360070004C0090006200B0007800CF008E00F000A400FF11B300FF31
|
||||
BE00FF51C700FF71D100FF91DC00FFB1E500FFD1F000FFFFFF00000000002C00
|
||||
2F004B0050006900700087009000A500B000C400CF00E100F000F011FF00F231
|
||||
FF00F451FF00F671FF00F791FF00F9B1FF00FBD1FF00FFFFFF00000000001B00
|
||||
2F002D0050003F007000520090006300B0007600CF008800F0009911FF00A631
|
||||
FF00B451FF00C271FF00CF91FF00DCB1FF00EBD1FF00FFFFFF00000000000800
|
||||
2F000E005000150070001B0090002100B0002600CF002C00F0003E11FF005831
|
||||
FF007151FF008C71FF00A691FF00BFB1FF00DAD1FF00FFFFFF00000000000000
|
||||
0000000000000000000000000056554A483B3B484A5556000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000543B383D4246
|
||||
4F52534E4B4339383B5400000000000000000000000000000000000000000000
|
||||
00000000000000003B393D505E676666666666666667665E513D383C00000000
|
||||
0000000000000000000000000000000000000000000040384B5E676766666666
|
||||
666666666666666666665F4D3841000000000000000000000000000000000000
|
||||
000000004938475F66666666666666666666666666666666666667675E453849
|
||||
0000000000000000000000000000000000000041395767676767666666666666
|
||||
66666666666666666666666666665A3941000000000000000000000000000000
|
||||
0000394261676767676767676666666666666666666666666666666666676761
|
||||
423B0000000000000000000000000000003846652923475F6767676767676766
|
||||
6666666666666666666666666666666666463800000000000000000000000000
|
||||
394C6667240807011F5266676767676666666666666666666666666666666667
|
||||
6766463900000000000000000000004142656767242E7E6F25000C2B63676767
|
||||
6766666666666666666666666666666666666642410000000000000000004939
|
||||
62666767242E8F8F8F77360E0A47666766666666666666666666666666666666
|
||||
6667676139490000000000000000385767676666262E8F8F8F8F8F7C34011662
|
||||
67676766666666666666666666666666666666665A3800000000000000414766
|
||||
66666767242E8F8F8F8F8F8F8F7414105B676666666666666666666666666666
|
||||
66666667674541000000000000385D6767666666262E8F8F8F8F8F8F8F8F7A1C
|
||||
055B676767666666666666666666666666666666665F3800000000003B4D6666
|
||||
66666667241A7B8F8F8F8F8F8F8F8F7E1B126567676767666666666666666666
|
||||
6666666767674B3C00000000385E6767666666664D0C08347A7F8F8F8F8F8F8F
|
||||
790B26676767676767676766666666666666666666665F380000005442666666
|
||||
666666666666430C026D8F8F8F8F8F8F8F70005E676767676767676766666666
|
||||
666666666767673D5400003B4F67676666666666666666663C02688F8F8F8F8F
|
||||
8F7F0F2A67676767676767676767676666666666666666503B0000385E666666
|
||||
6666666666666666674C01327F8F8F8F8F8F360C44444444444444475B666666
|
||||
666666666667675C38005638676767666666666666666666666658026D8F8F8F
|
||||
8F8F75080B0707080B0808004467676666666666666666673956554366666666
|
||||
6666666666666666666767270F7D8F8F8F8F8F8F8F8F8F8F8F8F8F0B47666666
|
||||
666666666666676742554A466767666666666666666666666666666306688F8F
|
||||
8F8F8F8F8F8F8F8F8F8F8F0B446767666666666666666667464A484E67666666
|
||||
6666666666666666666667673C06798F8F8F8F8F8F8F8F8F8F8F8F0B47666666
|
||||
66666666666767674E483B5167676766666666666666666666666666660B698F
|
||||
8F8F8F8F8F8F8F8F8F8F8F08446767666666666666666666533B3B5366666666
|
||||
66666666666666666666666767222F8F8F8F8F8F8F8F8F8F8F8F8F0847666666
|
||||
6666666666666767513B484E6767676666666666666666666666666666440B8F
|
||||
8F8F8F8F712D2C2D2D2E2E024467666666666666666666674E484A4667676666
|
||||
666666666666666666666667675A00748F8F8F8F730022262627272759666666
|
||||
6666666666676767464A5542676767666666666666666666666666666667076B
|
||||
8F8F8F8F7F0E2A67676766666666666666666666666666674355563966676666
|
||||
666666666666666666666667676720308F8F8F8F8F370A656766666666666666
|
||||
6666666666676767385600385C6767676766666666666666666666666666400E
|
||||
8F8F8F8F8F79023F6767676766666666666666666666675B3800003B4F676767
|
||||
66666666666666666666666666675A00738F8F8F8F8F69015267676666666666
|
||||
666666666767674F3B0000543D67676767666666666666666666666666666610
|
||||
687F8F8F8F8F8F330359676767676666666666666667663D54000000385E6767
|
||||
66666666666666666666666666676727198F8F8F8F8F8F7F2E01285F67666666
|
||||
6666666767675D38000000003C4B67676767666666666666666666666666665A
|
||||
026E8F8F8F8F8F8F7F6C0E000C3C66666666666667674B3C0000000000385E67
|
||||
67666666666666666666666666666767280B798F8F8F8F8F8F8F7E721D1F6666
|
||||
66676767675D3800000000000040456767676767666666666666666666666666
|
||||
66111D7C8F8F8F8F8F8F8F8F331E67666667676767454100000000000000385A
|
||||
67676766666666666666666666666666675B0D18778F8F8F8F8F8F8F331E6767
|
||||
6767676757380000000000000000493861676767676766666666666666666666
|
||||
666663150E6A7E8F8F8F8F8F331E676767676761384900000000000000000041
|
||||
3E656767676666666666666666666666666667662A021469768F8F8F331E6767
|
||||
6767643E41000000000000000000000039466767676767676666666666666666
|
||||
666666666661260C02183672311E676767674639000000000000000000000000
|
||||
00384665676767676766666666666666666666666666666658281100001E6767
|
||||
644638000000000000000000000000000000393E606767676767676767666666
|
||||
6666666666666666666667635958676142390000000000000000000000000000
|
||||
0000004138576767676767676767676767676767676767676767676767675738
|
||||
41000000000000000000000000000000000000004938455D6767676767676767
|
||||
6767676767676767676767675D45384900000000000000000000000000000000
|
||||
00000000000040384B5D676767676767676767676767676767675D4B38400000
|
||||
0000000000000000000000000000000000000000000000003B383D4F5C676767
|
||||
676767676767675C4F3D383B0000000000000000000000000000000000000000
|
||||
00000000000000000000543B38383E464E51514E464238383B54000000000000
|
||||
000000000000000000000000000000000000000000000000000000000056554A
|
||||
483B3B484A555600000000000000000000000000000000000000FFFFE007FFFF
|
||||
0000FFFF0000FFFF0000FFFC00003FFF0000FFF000000FFF0000FFC0000003FF
|
||||
0000FF80000001FF0000FF00000000FF0000FE000000007F0000FC000000003F
|
||||
0000F8000000001F0000F0000000000F0000F0000000000F0000E00000000007
|
||||
0000E000000000070000C000000000030000C000000000030000800000000001
|
||||
0000800000000001000080000000000100000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000800000000001000080000000000100008000000000010000C00000000003
|
||||
0000C000000000030000E000000000070000E000000000070000F0000000000F
|
||||
0000F0000000000F0000F8000000001F0000FC000000003F0000FE000000007F
|
||||
0000FF00000000FF0000FF80000001FF0000FFC0000003FF0000FFF000000FFF
|
||||
0000FFFC00003FFF0000FFFF0000FFFF0000FFFFE007FFFF0000280000002000
|
||||
0000400000000100080000000000000000000000000000000000000000000000
|
||||
000000000000030305000B0B14000C0C16000E0E1D0012121F000F0F22001313
|
||||
220017172300101024001919270012122D0014142F00191928001D1D29001E1E
|
||||
2F001313340014143A0012123C0015153F00222231002A2A3A002C2C39003131
|
||||
3D001212450010104B001616480012124E0013135200323243003A3A46001717
|
||||
660012126A001414690012126E000F0F7D001111700013137E00454554004B4B
|
||||
570050505E005E5E6A0063636F00676772006D6D77007373780078787F000606
|
||||
8400090987000A0A88000E0E8E0012128E0015158E000D0D95000E0E9D001010
|
||||
92001919910010109A0010109C002E2E9B0031319F000E0EA8001010A3001010
|
||||
A6000F0FB7001010BA001010BF006262B4007A7ABE000D0DC2001212CE000F0F
|
||||
D0001212D1001010DA001212E7001414E7001414E9001313EE001414EC001414
|
||||
F1001414F5001616FB001616FE00808085008C8C8F00969699009E9E9F00A0A0
|
||||
A100AEAEAE00B7B7B700BEBEBE00D6D6D600DADADA00E2E2E200E4E4E400E9E9
|
||||
E900EEEEEE00F0F0F000F6F6F600F8F8F800FEFEFE004CB0000059CF000067F0
|
||||
000078FF11008AFF31009CFF5100AEFF7100C0FF9100D2FFB100E4FFD100FFFF
|
||||
FF0000000000262F0000405000005A700000749000008EB00000A9CF0000C2F0
|
||||
0000D1FF1100D8FF3100DEFF5100E3FF7100E9FF9100EFFFB100F6FFD100FFFF
|
||||
FF00000000002F26000050410000705B000090740000B08E0000CFA90000F0C3
|
||||
0000FFD21100FFD83100FFDD5100FFE47100FFEA9100FFF0B100FFF6D100FFFF
|
||||
FF00000000002F1400005022000070300000903E0000B04D0000CF5B0000F069
|
||||
0000FF791100FF8A3100FF9D5100FFAF7100FFC19100FFD2B100FFE5D100FFFF
|
||||
FF00000000002F030000500400007006000090090000B00A0000CF0C0000F00E
|
||||
0000FF201200FF3E3100FF5C5100FF7A7100FF979100FFB6B100FFD4D100FFFF
|
||||
FF00000000002F000E00500017007000210090002B00B0003600CF004000F000
|
||||
4900FF115A00FF317000FF518600FF719C00FF91B200FFB1C800FFD1DF00FFFF
|
||||
FF00000000002F0020005000360070004C0090006200B0007800CF008E00F000
|
||||
A400FF11B300FF31BE00FF51C700FF71D100FF91DC00FFB1E500FFD1F000FFFF
|
||||
FF00000000002C002F004B0050006900700087009000A500B000C400CF00E100
|
||||
F000F011FF00F231FF00F451FF00F671FF00F791FF00F9B1FF00FBD1FF00FFFF
|
||||
FF00000000001B002F002D0050003F007000520090006300B0007600CF008800
|
||||
F0009911FF00A631FF00B451FF00C271FF00CF91FF00DCB1FF00EBD1FF00FFFF
|
||||
FF000000000008002F000E005000150070001B0090002100B0002600CF002C00
|
||||
F0003E11FF005831FF007151FF008C71FF00A691FF00BFB1FF00DAD1FF00FFFF
|
||||
FF00000000000000000000000000433C382F2F383C4300000000000000000000
|
||||
000000000000000000000043313945494A50504A494539314300000000000000
|
||||
0000000000000000004431404F525252525252525252524F4031440000000000
|
||||
00000000000000003B3F4F52525252525252525252525252524D3F3B00000000
|
||||
0000000000000034414952525252525252525252525252525252524234000000
|
||||
00000000000034474B0110324B52525252525252525252525252525247340000
|
||||
00000000003B42524B0F5C2E0A1A485252525252525252525252525252423B00
|
||||
00000000443F52524B0F6F6F6F5A0A3352525252525252525252525252523F44
|
||||
00000000314D52524B0F6F6F6F6F6127184B5252525252525252525252524D31
|
||||
00000043405252524B08626F6F6F6F6F55125252525252525252525252525240
|
||||
430000314F52525250220553636F6F6F6F2B255252525252525252525252524F
|
||||
300000395252525252524E2017606F6F6F610451525252525252525252525252
|
||||
390043455252525252525252370E616F6F6F281B1F1F1F1F2452525252525252
|
||||
45433C49525252525252525252232C6F6F6F5E59595959590352525252525252
|
||||
493C384A52525252525252525250065D6F6F6F6F6F6F6F6F0352525252525252
|
||||
4A382F505252525252525252525236296F6F6F6F6F6F6F6F0352525252525252
|
||||
502F2F50525252525252525252524E0D6F6F6F615B5C5B5B0352525252525252
|
||||
502F384A52525252525252525252520B5F6F6F5B011313131952525252525252
|
||||
4A383C49525252525252525252525221586F6F6F144952525252525252525252
|
||||
493C434552525252525252525252523D2A6F6F6F542452525252525252525252
|
||||
4543003952525252525252525252524E0D6F6F6F63163E525252525252525252
|
||||
390000304F5252525252525252525252115C6F6F6F5F0E21465252525252524F
|
||||
300000434052525252525252525252523E266F6F6F6F6257151C525252525240
|
||||
43000000314D52525252525252525252521B53646F6F6F6F610C525252524D31
|
||||
00000000443F52525252525252525252524E1C1E5F6F6F6F610C525252523F44
|
||||
00000000003B425252525252525252525252523A0756616F610C525252423B00
|
||||
00000000000034475252525252525252525252524922091D2D0C525247340000
|
||||
0000000000000034425252525252525252525252525252483532524234000000
|
||||
00000000000000003B3F4D52525252525252525252525252524D3F3B00000000
|
||||
0000000000000000004431404F525252525252525252524F4031440000000000
|
||||
000000000000000000000043303945494A50504A494539304300000000000000
|
||||
0000000000000000000000000000433C382F2F383C4300000000000000000000
|
||||
0000FFF00FFFFF8001FFFE00007FFC00003FF800001FF000000FE0000007C000
|
||||
0003C00000038000000180000001800000010000000000000000000000000000
|
||||
000000000000000000000000000000000000800000018000000180000001C000
|
||||
0003C0000003E0000007F000000FF800001FFC00003FFE00007FFF8001FFFFF0
|
||||
0FFF280000001000000020000000010008000000000000000000000000000000
|
||||
00000000000000000000000000003F3F69002A2A720044447700272784002323
|
||||
8F002C2C8F003535870033338C0035358E002A2A91002D2D910023239A001F1F
|
||||
A1001F1FB1001C1CBF002323A0002525A4003333BE0040408700515181005555
|
||||
86005F5F80006363870062628E0066668E00696989004747B4004A4ABC001515
|
||||
C3001515D4001919D6002828C5001717E5001515F3001515FA001616FE006969
|
||||
C1007E7EC8009797AA00AFAFBB00BABAC700C2C2C800CDCDD400D1D1D300D5D5
|
||||
D800DDDDE000E4E4E500F1F1F100F9F9F900FFFFFF0000704C000090630000B0
|
||||
790000CF8F0000F0A60011FFB40031FFBE0051FFC80071FFD30091FFDC00B1FF
|
||||
E500D1FFF000FFFFFF0000000000002F0E00005018000070220000902C0000B0
|
||||
360000CF400000F04A0011FF5B0031FF710051FF870071FF9D0091FFB200B1FF
|
||||
C900D1FFDF00FFFFFF0000000000022F00000450000006700000089000000AB0
|
||||
00000BCF00000EF0000020FF12003DFF31005BFF510079FF710098FF9100B5FF
|
||||
B100D4FFD100FFFFFF0000000000142F000022500000307000003D9000004CB0
|
||||
000059CF000067F0000078FF11008AFF31009CFF5100AEFF7100C0FF9100D2FF
|
||||
B100E4FFD100FFFFFF0000000000262F0000405000005A700000749000008EB0
|
||||
0000A9CF0000C2F00000D1FF1100D8FF3100DEFF5100E3FF7100E9FF9100EFFF
|
||||
B100F6FFD100FFFFFF00000000002F26000050410000705B000090740000B08E
|
||||
0000CFA90000F0C30000FFD21100FFD83100FFDD5100FFE47100FFEA9100FFF0
|
||||
B100FFF6D100FFFFFF00000000002F1400005022000070300000903E0000B04D
|
||||
0000CF5B0000F0690000FF791100FF8A3100FF9D5100FFAF7100FFC19100FFD2
|
||||
B100FFE5D100FFFFFF00000000002F030000500400007006000090090000B00A
|
||||
0000CF0C0000F00E0000FF201200FF3E3100FF5C5100FF7A7100FF979100FFB6
|
||||
B100FFD4D100FFFFFF00000000002F000E00500017007000210090002B00B000
|
||||
3600CF004000F0004900FF115A00FF317000FF518600FF719C00FF91B200FFB1
|
||||
C800FFD1DF00FFFFFF00000000002F0020005000360070004C0090006200B000
|
||||
7800CF008E00F000A400FF11B300FF31BE00FF51C700FF71D100FF91DC00FFB1
|
||||
E500FFD1F000FFFFFF00000000002C002F004B0050006900700087009000A500
|
||||
B000C400CF00E100F000F011FF00F231FF00F451FF00F671FF00F791FF00F9B1
|
||||
FF00FBD1FF00FFFFFF00000000001B002F002D0050003F007000520090006300
|
||||
B0007600CF008800F0009911FF00A631FF00B451FF00C271FF00CF91FF00DCB1
|
||||
FF00EBD1FF00FFFFFF000000000008002F000E005000150070001B0090002100
|
||||
B0002600CF002C00F0003E11FF005831FF007151FF008C71FF00A691FF00BFB1
|
||||
FF00DAD1FF00FFFFFF000000000000251C12121C250000000000000000262023
|
||||
2424242423202600000000001B0D0E23242424242424211B0000002621092C17
|
||||
112424242424242126000020240832322B0724242424242420002523241F032E
|
||||
32280F242424242423251C24242424042D321A1515102424241C122424242424
|
||||
143232323206242424121224242424240B313016180C242424121C2424242424
|
||||
1D2A321324242424241C25232424242424153229052224242325002024242424
|
||||
240C2E322F012424200000262124242424240A2731192421260000001B212424
|
||||
2424241E0A02211B000000000026202324242424232026000000000000000025
|
||||
1C12121C250000000000F81F0000E0070000C003000080010000800100000000
|
||||
000000000000000000000000000000000000000000008001000080010000C003
|
||||
0000E0070000F81F0000}
|
||||
OldCreateOrder = False
|
||||
OnActivate = FormActivate
|
||||
OnCreate = FormCreate
|
||||
PixelsPerInch = 120
|
||||
TextHeight = 16
|
||||
object tmrWatchDog: TTimer
|
||||
OnTimer = tmrWatchDogTimer
|
||||
Left = 16
|
||||
Top = 8
|
||||
end
|
||||
end
|
||||
451
libsrc/FlashPlayer/uMain.pas
Normal file
451
libsrc/FlashPlayer/uMain.pas
Normal file
@@ -0,0 +1,451 @@
|
||||
unit uMain;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
|
||||
Dialogs, OleCtrls, ShockwaveFlashObjects_TLB, StdCtrls, ExtCtrls;
|
||||
|
||||
type
|
||||
TfrmMain = class(TForm)
|
||||
tmrWatchDog: TTimer;
|
||||
|
||||
procedure FormActivate(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure FormDestroy(Sender: TObject);
|
||||
procedure tmrWatchDogTimer(Sender: TObject);
|
||||
private
|
||||
{ Private declarations }
|
||||
public
|
||||
{ Public declarations }
|
||||
end;
|
||||
|
||||
type
|
||||
TMySWF = class(TShockwaveFlash)
|
||||
public
|
||||
procedure CreateWnd; override;
|
||||
end;
|
||||
|
||||
type
|
||||
TPipeThread = class(TThread)
|
||||
protected
|
||||
flashFile: string;
|
||||
w: integer;
|
||||
h: integer;
|
||||
bgColor: TColor;
|
||||
procedure Execute; override;
|
||||
procedure displaySWF;
|
||||
procedure freeSWF;
|
||||
procedure setPos;
|
||||
procedure setBGColor;
|
||||
end;
|
||||
|
||||
TBuf = array[0..255] of byte;
|
||||
|
||||
var
|
||||
frmMain: TfrmMain;
|
||||
k: string;
|
||||
t: TPipeThread;
|
||||
flaPreview: TMySWF;
|
||||
target: HWND = 0;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.dfm}
|
||||
|
||||
|
||||
|
||||
procedure TMySWF.CreateWnd;
|
||||
begin
|
||||
inherited;
|
||||
end;
|
||||
|
||||
function arrToStr(k: TBuf; len: integer): string;
|
||||
var
|
||||
s: string;
|
||||
i: integer;
|
||||
begin
|
||||
s := '';
|
||||
for i := 0 to len - 1 do
|
||||
begin
|
||||
if k[i] = 0 then
|
||||
break;
|
||||
s := s + '' + chr(k[i]);
|
||||
end;
|
||||
Result := s;
|
||||
end;
|
||||
|
||||
procedure ReadPipe(pipe: cardinal; var buffer: TBuf; bytesToRead: cardinal);
|
||||
var
|
||||
numBytesRead: DWORD;
|
||||
readResult: longbool;
|
||||
begin
|
||||
numBytesRead := 0;
|
||||
readResult := ReadFile(pipe, buffer, bytesToRead, numBytesRead, nil);
|
||||
if (not readResult) or (numBytesRead <> bytesToRead) then
|
||||
begin
|
||||
Application.Terminate;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure WritePipe(pipe: cardinal; var buffer: TBuf; bytesToWrite: cardinal);
|
||||
var
|
||||
written: cardinal;
|
||||
writeResult: longbool;
|
||||
begin
|
||||
written := 0;
|
||||
writeResult := WriteFile(pipe, buffer, bytesToWrite, written, nil);
|
||||
if (not writeResult) or (written <> bytesToWrite) then
|
||||
begin
|
||||
Application.Terminate;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPipeThread.freeSWF();
|
||||
begin
|
||||
if Assigned(flaPreview) then
|
||||
begin
|
||||
try
|
||||
flaPreview.Stop;
|
||||
flaPreview.Movie := '';
|
||||
flaPreview.Free;
|
||||
flaPreview := nil;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPipeThread.displaySWF();
|
||||
begin
|
||||
Windows.SetParent(frmMain.Handle, target);
|
||||
freeSWF();
|
||||
flaPreview := TMySWF.Create(frmMain);
|
||||
flaPreview.Left := 0;
|
||||
flaPreview.Top := 0;
|
||||
flaPreview.Width := self.w;
|
||||
flaPreview.Height := self.h;
|
||||
frmMain.Caption := 'set movie:' + flashFile;
|
||||
flaPreview.Parent := frmMain;
|
||||
flaPreview.Movie := flashFile;
|
||||
flaPreview.SetFocus;
|
||||
end;
|
||||
|
||||
procedure TPipeThread.setBGColor();
|
||||
begin
|
||||
frmMain.Color := self.bgColor;
|
||||
end;
|
||||
|
||||
|
||||
procedure TPipeThread.setPos();
|
||||
begin
|
||||
SetWindowPos(frmMain.Handle, 0, 0, 0, self.w, self.h, SWP_SHOWWINDOW);
|
||||
flaPreview.Left := 0;
|
||||
flaPreview.Top := 0;
|
||||
flaPreview.Width := self.w;
|
||||
flaPreview.Height := self.h;
|
||||
flaPreview.CreateWnd;
|
||||
//displaySWF();
|
||||
end;
|
||||
|
||||
procedure TPipeThread.Execute();
|
||||
var
|
||||
pipe: cardinal;
|
||||
buffer: TBuf;
|
||||
pipename: PAnsiChar;
|
||||
len: integer;
|
||||
cmd: integer;
|
||||
val: cardinal;
|
||||
vals: string;
|
||||
vars: string;
|
||||
|
||||
const
|
||||
CMD_PLAY = 1;
|
||||
CMD_RESIZE = 2;
|
||||
CMD_BGCOLOR = 3;
|
||||
CMD_CURRENT_FRAME = 4;
|
||||
CMD_TOTAL_FRAMES = 5;
|
||||
CMD_PAUSE = 6;
|
||||
CMD_RESUME = 7;
|
||||
CMD_PLAYING = 8;
|
||||
CMD_REWIND = 9;
|
||||
CMD_GOTO = 10;
|
||||
CMD_CALL = 11;
|
||||
CMD_GETVARIABLE = 12;
|
||||
CMD_SETVARIABLE = 13;
|
||||
begin
|
||||
|
||||
try
|
||||
pipename := PAnsiChar('\\.\\pipe\ffdec_flashplayer_' + ParamStr(1));
|
||||
begin
|
||||
pipe := CreateFile(pipename, GENERIC_READ or GENERIC_WRITE,
|
||||
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
|
||||
repeat
|
||||
try
|
||||
ReadPipe(pipe, buffer, 1);
|
||||
cmd := buffer[0];
|
||||
case cmd of
|
||||
CMD_PLAY:
|
||||
begin
|
||||
ReadPipe(pipe, buffer, 1);
|
||||
len := buffer[0];
|
||||
ReadPipe(pipe, buffer, len);
|
||||
self.flashFile := arrToStr(buffer, len);
|
||||
try
|
||||
Synchronize(displaySWF);
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
freeSWF();
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
CMD_RESIZE:
|
||||
begin
|
||||
ReadPipe(pipe, buffer, 4);
|
||||
self.w := buffer[0] * 256 + buffer[1];
|
||||
self.h := buffer[2] * 256 + buffer[3];
|
||||
Synchronize(setPos);
|
||||
end;
|
||||
CMD_BGCOLOR:
|
||||
begin
|
||||
ReadPipe(pipe, buffer, 3);
|
||||
self.bgColor := RGB(buffer[0], buffer[1], buffer[2]);
|
||||
Synchronize(setBGColor);
|
||||
end;
|
||||
CMD_CURRENT_FRAME:
|
||||
begin
|
||||
val := 0;
|
||||
try
|
||||
if flaPreview.ReadyState = 4 then
|
||||
val := flaPreview.CurrentFrame
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
freeSWF();
|
||||
end;
|
||||
end;
|
||||
buffer[0] := (val shr 8) mod 256;
|
||||
buffer[1] := val mod 256;
|
||||
WritePipe(pipe, buffer, 2);
|
||||
end;
|
||||
CMD_TOTAL_FRAMES:
|
||||
begin
|
||||
val := 0;
|
||||
try
|
||||
if flaPreview.ReadyState = 4 then
|
||||
val := flaPreview.TotalFrames
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
freeSWF();
|
||||
end;
|
||||
end;
|
||||
buffer[0] := (val shr 8) mod 256;
|
||||
buffer[1] := val mod 256;
|
||||
WritePipe(pipe, buffer, 2);
|
||||
end;
|
||||
CMD_PAUSE:
|
||||
begin
|
||||
try
|
||||
flaPreview.Stop;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
freeSWF();
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
CMD_RESUME:
|
||||
begin
|
||||
try
|
||||
flaPreview.Play;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
freeSWF();
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
CMD_PLAYING:
|
||||
begin
|
||||
buffer[0] := 0;
|
||||
try
|
||||
if flaPreview.ReadyState = 4 then
|
||||
if flaPreview.IsPlaying then
|
||||
buffer[0] := 1;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
freeSWF();
|
||||
end;
|
||||
end;
|
||||
|
||||
WritePipe(pipe, buffer, 1);
|
||||
end;
|
||||
CMD_REWIND:
|
||||
begin
|
||||
try
|
||||
flaPreview.Rewind;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
freeSWF();
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
CMD_GOTO:
|
||||
begin
|
||||
ReadPipe(pipe, buffer, 2);
|
||||
val := (buffer[0] shl 8) + buffer[1];
|
||||
try
|
||||
flaPreview.GotoFrame(val);
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
freeSWF();
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
CMD_CALL:
|
||||
begin
|
||||
ReadPipe(pipe, buffer, 2);
|
||||
val := (buffer[0] shl 8) + buffer[1];
|
||||
ReadPipe(pipe, buffer, val);
|
||||
SetString(vals, PChar(Addr(buffer)), val);
|
||||
try
|
||||
vals := flaPreview.CallFunction(vals);
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
vals := '';
|
||||
freeSWF();
|
||||
end;
|
||||
end;
|
||||
val := length(vals);
|
||||
buffer[0] := (val shr 8) mod 256;
|
||||
buffer[1] := val mod 256;
|
||||
WritePipe(pipe, buffer, 2);
|
||||
Move(vals[1], buffer, val);
|
||||
WritePipe(pipe, buffer, val);
|
||||
end;
|
||||
CMD_GETVARIABLE:
|
||||
begin
|
||||
ReadPipe(pipe, buffer, 2);
|
||||
val := (buffer[0] shl 8) + buffer[1];
|
||||
ReadPipe(pipe, buffer, val);
|
||||
SetString(vals, PChar(Addr(buffer)), val);
|
||||
try
|
||||
vals := flaPreview.GetVariable(vals);
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
vals := '';
|
||||
freeSWF();
|
||||
end;
|
||||
end;
|
||||
val := length(vals);
|
||||
buffer[0] := (val shr 8) mod 256;
|
||||
buffer[1] := val mod 256;
|
||||
WritePipe(pipe, buffer, 2);
|
||||
Move(vals[1], buffer, val);
|
||||
WritePipe(pipe, buffer, val);
|
||||
end;
|
||||
CMD_SETVARIABLE:
|
||||
begin
|
||||
ReadPipe(pipe, buffer, 2);
|
||||
val := (buffer[0] shl 8) + buffer[1];
|
||||
ReadPipe(pipe, buffer, val);
|
||||
SetString(vars, PChar(Addr(buffer)), val);
|
||||
|
||||
ReadPipe(pipe, buffer, 2);
|
||||
val := (buffer[0] shl 8) + buffer[1];
|
||||
ReadPipe(pipe, buffer, val);
|
||||
SetString(vals, PChar(Addr(buffer)), val);
|
||||
|
||||
try
|
||||
flaPreview.SetVariable(vars, vals);
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
freeSWF();
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
freeSWF();
|
||||
end;
|
||||
end;
|
||||
until False;
|
||||
|
||||
CloseHandle(pipe);
|
||||
end;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.FormActivate(Sender: TObject);
|
||||
begin
|
||||
|
||||
if (ParamCount >= 2) then
|
||||
begin
|
||||
flaPreview.Parent := frmMain;
|
||||
|
||||
ShowWindow(Application.Handle, SW_HIDE);
|
||||
SetWindowLong(Application.Handle, GWL_EXSTYLE,
|
||||
getWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
|
||||
ShowWindow(Application.Handle, SW_SHOW);
|
||||
|
||||
SetForegroundWindow(HWND(StrToInt(ParamStr(2))));
|
||||
frmMain.Caption := 'FlashPlayerWindow_' + ParamStr(2);
|
||||
Application.Title := 'FlashPlayerWindow_' + ParamStr(2);
|
||||
target := HWND(StrToInt(ParamStr(1)));
|
||||
|
||||
SetWindowLong(frmMain.Handle, GWL_STYLE, 0);
|
||||
ShowWindow(frmMain.Handle, SW_SHOW);
|
||||
|
||||
frmMain.Left := 0;
|
||||
frmMain.Top := 0;
|
||||
Windows.SetParent(frmMain.Handle, target);
|
||||
|
||||
t := TPipeThread.Create(True);
|
||||
t.Resume;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.FormCreate(Sender: TObject);
|
||||
begin
|
||||
if (ParamCount >= 2) then
|
||||
begin
|
||||
flaPreview := TMySWF.Create(frmMain);
|
||||
flaPreview.AllowScriptAccess := 'always';
|
||||
flaPreview.BackgroundColor := -1;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.FormDestroy(Sender: TObject);
|
||||
begin
|
||||
t.Free;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.tmrWatchDogTimer(Sender: TObject);
|
||||
begin
|
||||
if target <> 0 then
|
||||
begin
|
||||
if not IsWindow(target) then
|
||||
begin
|
||||
Application.Terminate;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
73
libsrc/LZMA/build.xml
Normal file
73
libsrc/LZMA/build.xml
Normal file
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- You may freely edit this file. See commented blocks below for -->
|
||||
<!-- some examples of how to customize the build. -->
|
||||
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||
<!-- the Compile on Save feature is turned off for the project. -->
|
||||
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||
<!-- in the project's Project Properties dialog box.-->
|
||||
<project name="LZMA" default="default" basedir=".">
|
||||
<description>Builds, tests, and runs the project LZMA.</description>
|
||||
<import file="nbproject/build-impl.xml"/>
|
||||
<!--
|
||||
|
||||
There exist several targets which are by default empty and which can be
|
||||
used for execution of your tasks. These targets are usually executed
|
||||
before and after some main targets. They are:
|
||||
|
||||
-pre-init: called before initialization of project properties
|
||||
-post-init: called after initialization of project properties
|
||||
-pre-compile: called before javac compilation
|
||||
-post-compile: called after javac compilation
|
||||
-pre-compile-single: called before javac compilation of single file
|
||||
-post-compile-single: called after javac compilation of single file
|
||||
-pre-compile-test: called before javac compilation of JUnit tests
|
||||
-post-compile-test: called after javac compilation of JUnit tests
|
||||
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||
-pre-jar: called before JAR building
|
||||
-post-jar: called after JAR building
|
||||
-post-clean: called after cleaning build products
|
||||
|
||||
(Targets beginning with '-' are not intended to be called on their own.)
|
||||
|
||||
Example of inserting an obfuscator after compilation could look like this:
|
||||
|
||||
<target name="-post-compile">
|
||||
<obfuscate>
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
</obfuscate>
|
||||
</target>
|
||||
|
||||
For list of available properties check the imported
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
|
||||
Another way to customize the build is by overriding existing main targets.
|
||||
The targets of interest are:
|
||||
|
||||
-init-macrodef-javac: defines macro for javac compilation
|
||||
-init-macrodef-junit: defines macro for junit execution
|
||||
-init-macrodef-debug: defines macro for class debugging
|
||||
-init-macrodef-java: defines macro for class execution
|
||||
-do-jar: JAR building
|
||||
run: execution of project
|
||||
-javadoc-build: Javadoc generation
|
||||
test-report: JUnit report generation
|
||||
|
||||
An example of overriding the target for project execution could look like this:
|
||||
|
||||
<target name="run" depends="LZMA-impl.jar">
|
||||
<exec dir="bin" executable="launcher.exe">
|
||||
<arg file="${dist.jar}"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
Notice that the overridden target depends on the jar target and not only on
|
||||
the compile target as the regular run target does. Again, for a list of available
|
||||
properties which you can use, check the target you are overriding in the
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
-->
|
||||
</project>
|
||||
3
libsrc/LZMA/manifest.mf
Normal file
3
libsrc/LZMA/manifest.mf
Normal file
@@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
X-COMMENT: Main-Class will be added automatically by build
|
||||
|
||||
1413
libsrc/LZMA/nbproject/build-impl.xml
Normal file
1413
libsrc/LZMA/nbproject/build-impl.xml
Normal file
File diff suppressed because it is too large
Load Diff
8
libsrc/LZMA/nbproject/genfiles.properties
Normal file
8
libsrc/LZMA/nbproject/genfiles.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
build.xml.data.CRC32=cf8fb9e4
|
||||
build.xml.script.CRC32=0d82b5ac
|
||||
build.xml.stylesheet.CRC32=8064a381@1.68.1.46
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=cf8fb9e4
|
||||
nbproject/build-impl.xml.script.CRC32=fd6704e6
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.74.1.48
|
||||
71
libsrc/LZMA/nbproject/project.properties
Normal file
71
libsrc/LZMA/nbproject/project.properties
Normal file
@@ -0,0 +1,71 @@
|
||||
annotation.processing.enabled=true
|
||||
annotation.processing.enabled.in.editor=false
|
||||
annotation.processing.processor.options=
|
||||
annotation.processing.processors.list=
|
||||
annotation.processing.run.all.processors=true
|
||||
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
||||
build.classes.dir=${build.dir}/classes
|
||||
build.classes.excludes=**/*.java,**/*.form
|
||||
# This directory is removed when the project is cleaned:
|
||||
build.dir=build
|
||||
build.generated.dir=${build.dir}/generated
|
||||
build.generated.sources.dir=${build.dir}/generated-sources
|
||||
# Only compile against the classpath explicitly listed here:
|
||||
build.sysclasspath=ignore
|
||||
build.test.classes.dir=${build.dir}/test/classes
|
||||
build.test.results.dir=${build.dir}/test/results
|
||||
# Uncomment to specify the preferred debugger connection transport:
|
||||
#debug.transport=dt_socket
|
||||
debug.classpath=\
|
||||
${run.classpath}
|
||||
debug.test.classpath=\
|
||||
${run.test.classpath}
|
||||
# This directory is removed when the project is cleaned:
|
||||
dist.dir=dist
|
||||
dist.jar=../../lib/LZMA.jar
|
||||
dist.javadoc.dir=${dist.dir}/javadoc
|
||||
excludes=
|
||||
includes=**
|
||||
jar.compress=false
|
||||
javac.classpath=
|
||||
# Space-separated list of extra javac options
|
||||
javac.compilerargs=
|
||||
javac.deprecation=false
|
||||
javac.processorpath=\
|
||||
${javac.classpath}
|
||||
javac.source=1.6
|
||||
javac.target=1.6
|
||||
javac.test.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
javac.test.processorpath=\
|
||||
${javac.test.classpath}
|
||||
javadoc.additionalparam=
|
||||
javadoc.author=false
|
||||
javadoc.encoding=${source.encoding}
|
||||
javadoc.noindex=false
|
||||
javadoc.nonavbar=false
|
||||
javadoc.notree=false
|
||||
javadoc.private=false
|
||||
javadoc.splitindex=true
|
||||
javadoc.use=true
|
||||
javadoc.version=false
|
||||
javadoc.windowtitle=
|
||||
main.class=
|
||||
manifest.file=manifest.mf
|
||||
meta.inf.dir=${src.dir}/META-INF
|
||||
mkdist.disabled=false
|
||||
platform.active=default_platform
|
||||
run.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
# Space-separated list of JVM arguments used when running the project
|
||||
# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
|
||||
# or test-sys-prop.name=value to set system properties for unit tests):
|
||||
run.jvmargs=
|
||||
run.test.classpath=\
|
||||
${javac.test.classpath}:\
|
||||
${build.test.classes.dir}
|
||||
source.encoding=UTF-8
|
||||
src.dir=src
|
||||
test.src.dir=test
|
||||
15
libsrc/LZMA/nbproject/project.xml
Normal file
15
libsrc/LZMA/nbproject/project.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.java.j2seproject</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<name>LZMA</name>
|
||||
<source-roots>
|
||||
<root id="src.dir"/>
|
||||
</source-roots>
|
||||
<test-roots>
|
||||
<root id="test.src.dir"/>
|
||||
</test-roots>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
52
libsrc/LZMA/src/SevenZip/CRC.java
Normal file
52
libsrc/LZMA/src/SevenZip/CRC.java
Normal file
@@ -0,0 +1,52 @@
|
||||
// SevenZip/CRC.java
|
||||
|
||||
package SevenZip;
|
||||
|
||||
public class CRC
|
||||
{
|
||||
static public int[] Table = new int[256];
|
||||
|
||||
static
|
||||
{
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
int r = i;
|
||||
for (int j = 0; j < 8; j++)
|
||||
if ((r & 1) != 0)
|
||||
r = (r >>> 1) ^ 0xEDB88320;
|
||||
else
|
||||
r >>>= 1;
|
||||
Table[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
int _value = -1;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
_value = -1;
|
||||
}
|
||||
|
||||
public void Update(byte[] data, int offset, int size)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
_value = Table[(_value ^ data[offset + i]) & 0xFF] ^ (_value >>> 8);
|
||||
}
|
||||
|
||||
public void Update(byte[] data)
|
||||
{
|
||||
int size = data.length;
|
||||
for (int i = 0; i < size; i++)
|
||||
_value = Table[(_value ^ data[i]) & 0xFF] ^ (_value >>> 8);
|
||||
}
|
||||
|
||||
public void UpdateByte(int b)
|
||||
{
|
||||
_value = Table[(_value ^ b) & 0xFF] ^ (_value >>> 8);
|
||||
}
|
||||
|
||||
public int GetDigest()
|
||||
{
|
||||
return _value ^ (-1);
|
||||
}
|
||||
}
|
||||
382
libsrc/LZMA/src/SevenZip/Compression/LZ/BinTree.java
Normal file
382
libsrc/LZMA/src/SevenZip/Compression/LZ/BinTree.java
Normal file
@@ -0,0 +1,382 @@
|
||||
// LZ.BinTree
|
||||
|
||||
package SevenZip.Compression.LZ;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
public class BinTree extends InWindow
|
||||
{
|
||||
int _cyclicBufferPos;
|
||||
int _cyclicBufferSize = 0;
|
||||
int _matchMaxLen;
|
||||
|
||||
int[] _son;
|
||||
int[] _hash;
|
||||
|
||||
int _cutValue = 0xFF;
|
||||
int _hashMask;
|
||||
int _hashSizeSum = 0;
|
||||
|
||||
boolean HASH_ARRAY = true;
|
||||
|
||||
static final int kHash2Size = 1 << 10;
|
||||
static final int kHash3Size = 1 << 16;
|
||||
static final int kBT2HashSize = 1 << 16;
|
||||
static final int kStartMaxLen = 1;
|
||||
static final int kHash3Offset = kHash2Size;
|
||||
static final int kEmptyHashValue = 0;
|
||||
static final int kMaxValForNormalize = (1 << 30) - 1;
|
||||
|
||||
int kNumHashDirectBytes = 0;
|
||||
int kMinMatchCheck = 4;
|
||||
int kFixHashSize = kHash2Size + kHash3Size;
|
||||
|
||||
public void SetType(int numHashBytes)
|
||||
{
|
||||
HASH_ARRAY = (numHashBytes > 2);
|
||||
if (HASH_ARRAY)
|
||||
{
|
||||
kNumHashDirectBytes = 0;
|
||||
kMinMatchCheck = 4;
|
||||
kFixHashSize = kHash2Size + kHash3Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
kNumHashDirectBytes = 2;
|
||||
kMinMatchCheck = 2 + 1;
|
||||
kFixHashSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void Init() throws IOException
|
||||
{
|
||||
super.Init();
|
||||
for (int i = 0; i < _hashSizeSum; i++)
|
||||
_hash[i] = kEmptyHashValue;
|
||||
_cyclicBufferPos = 0;
|
||||
ReduceOffsets(-1);
|
||||
}
|
||||
|
||||
public void MovePos() throws IOException
|
||||
{
|
||||
if (++_cyclicBufferPos >= _cyclicBufferSize)
|
||||
_cyclicBufferPos = 0;
|
||||
super.MovePos();
|
||||
if (_pos == kMaxValForNormalize)
|
||||
Normalize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public boolean Create(int historySize, int keepAddBufferBefore,
|
||||
int matchMaxLen, int keepAddBufferAfter)
|
||||
{
|
||||
if (historySize > kMaxValForNormalize - 256)
|
||||
return false;
|
||||
_cutValue = 16 + (matchMaxLen >> 1);
|
||||
|
||||
int windowReservSize = (historySize + keepAddBufferBefore +
|
||||
matchMaxLen + keepAddBufferAfter) / 2 + 256;
|
||||
|
||||
super.Create(historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize);
|
||||
|
||||
_matchMaxLen = matchMaxLen;
|
||||
|
||||
int cyclicBufferSize = historySize + 1;
|
||||
if (_cyclicBufferSize != cyclicBufferSize)
|
||||
_son = new int[(_cyclicBufferSize = cyclicBufferSize) * 2];
|
||||
|
||||
int hs = kBT2HashSize;
|
||||
|
||||
if (HASH_ARRAY)
|
||||
{
|
||||
hs = historySize - 1;
|
||||
hs |= (hs >> 1);
|
||||
hs |= (hs >> 2);
|
||||
hs |= (hs >> 4);
|
||||
hs |= (hs >> 8);
|
||||
hs >>= 1;
|
||||
hs |= 0xFFFF;
|
||||
if (hs > (1 << 24))
|
||||
hs >>= 1;
|
||||
_hashMask = hs;
|
||||
hs++;
|
||||
hs += kFixHashSize;
|
||||
}
|
||||
if (hs != _hashSizeSum)
|
||||
_hash = new int [_hashSizeSum = hs];
|
||||
return true;
|
||||
}
|
||||
public int GetMatches(int[] distances) throws IOException
|
||||
{
|
||||
int lenLimit;
|
||||
if (_pos + _matchMaxLen <= _streamPos)
|
||||
lenLimit = _matchMaxLen;
|
||||
else
|
||||
{
|
||||
lenLimit = _streamPos - _pos;
|
||||
if (lenLimit < kMinMatchCheck)
|
||||
{
|
||||
MovePos();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
int matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
|
||||
int cur = _bufferOffset + _pos;
|
||||
int maxLen = kStartMaxLen; // to avoid items for len < hashSize;
|
||||
int hashValue, hash2Value = 0, hash3Value = 0;
|
||||
|
||||
if (HASH_ARRAY)
|
||||
{
|
||||
int temp = CrcTable[_bufferBase[cur] & 0xFF] ^ (_bufferBase[cur + 1] & 0xFF);
|
||||
hash2Value = temp & (kHash2Size - 1);
|
||||
temp ^= ((int)(_bufferBase[cur + 2] & 0xFF) << 8);
|
||||
hash3Value = temp & (kHash3Size - 1);
|
||||
hashValue = (temp ^ (CrcTable[_bufferBase[cur + 3] & 0xFF] << 5)) & _hashMask;
|
||||
}
|
||||
else
|
||||
hashValue = ((_bufferBase[cur] & 0xFF) ^ ((int)(_bufferBase[cur + 1] & 0xFF) << 8));
|
||||
|
||||
int curMatch = _hash[kFixHashSize + hashValue];
|
||||
if (HASH_ARRAY)
|
||||
{
|
||||
int curMatch2 = _hash[hash2Value];
|
||||
int curMatch3 = _hash[kHash3Offset + hash3Value];
|
||||
_hash[hash2Value] = _pos;
|
||||
_hash[kHash3Offset + hash3Value] = _pos;
|
||||
if (curMatch2 > matchMinPos)
|
||||
if (_bufferBase[_bufferOffset + curMatch2] == _bufferBase[cur])
|
||||
{
|
||||
distances[offset++] = maxLen = 2;
|
||||
distances[offset++] = _pos - curMatch2 - 1;
|
||||
}
|
||||
if (curMatch3 > matchMinPos)
|
||||
if (_bufferBase[_bufferOffset + curMatch3] == _bufferBase[cur])
|
||||
{
|
||||
if (curMatch3 == curMatch2)
|
||||
offset -= 2;
|
||||
distances[offset++] = maxLen = 3;
|
||||
distances[offset++] = _pos - curMatch3 - 1;
|
||||
curMatch2 = curMatch3;
|
||||
}
|
||||
if (offset != 0 && curMatch2 == curMatch)
|
||||
{
|
||||
offset -= 2;
|
||||
maxLen = kStartMaxLen;
|
||||
}
|
||||
}
|
||||
|
||||
_hash[kFixHashSize + hashValue] = _pos;
|
||||
|
||||
int ptr0 = (_cyclicBufferPos << 1) + 1;
|
||||
int ptr1 = (_cyclicBufferPos << 1);
|
||||
|
||||
int len0, len1;
|
||||
len0 = len1 = kNumHashDirectBytes;
|
||||
|
||||
if (kNumHashDirectBytes != 0)
|
||||
{
|
||||
if (curMatch > matchMinPos)
|
||||
{
|
||||
if (_bufferBase[_bufferOffset + curMatch + kNumHashDirectBytes] !=
|
||||
_bufferBase[cur + kNumHashDirectBytes])
|
||||
{
|
||||
distances[offset++] = maxLen = kNumHashDirectBytes;
|
||||
distances[offset++] = _pos - curMatch - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int count = _cutValue;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (curMatch <= matchMinPos || count-- == 0)
|
||||
{
|
||||
_son[ptr0] = _son[ptr1] = kEmptyHashValue;
|
||||
break;
|
||||
}
|
||||
int delta = _pos - curMatch;
|
||||
int cyclicPos = ((delta <= _cyclicBufferPos) ?
|
||||
(_cyclicBufferPos - delta) :
|
||||
(_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
|
||||
|
||||
int pby1 = _bufferOffset + curMatch;
|
||||
int len = Math.min(len0, len1);
|
||||
if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
|
||||
{
|
||||
while(++len != lenLimit)
|
||||
if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
|
||||
break;
|
||||
if (maxLen < len)
|
||||
{
|
||||
distances[offset++] = maxLen = len;
|
||||
distances[offset++] = delta - 1;
|
||||
if (len == lenLimit)
|
||||
{
|
||||
_son[ptr1] = _son[cyclicPos];
|
||||
_son[ptr0] = _son[cyclicPos + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((_bufferBase[pby1 + len] & 0xFF) < (_bufferBase[cur + len] & 0xFF))
|
||||
{
|
||||
_son[ptr1] = curMatch;
|
||||
ptr1 = cyclicPos + 1;
|
||||
curMatch = _son[ptr1];
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
_son[ptr0] = curMatch;
|
||||
ptr0 = cyclicPos;
|
||||
curMatch = _son[ptr0];
|
||||
len0 = len;
|
||||
}
|
||||
}
|
||||
MovePos();
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void Skip(int num) throws IOException
|
||||
{
|
||||
do
|
||||
{
|
||||
int lenLimit;
|
||||
if (_pos + _matchMaxLen <= _streamPos)
|
||||
lenLimit = _matchMaxLen;
|
||||
else
|
||||
{
|
||||
lenLimit = _streamPos - _pos;
|
||||
if (lenLimit < kMinMatchCheck)
|
||||
{
|
||||
MovePos();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
|
||||
int cur = _bufferOffset + _pos;
|
||||
|
||||
int hashValue;
|
||||
|
||||
if (HASH_ARRAY)
|
||||
{
|
||||
int temp = CrcTable[_bufferBase[cur] & 0xFF] ^ (_bufferBase[cur + 1] & 0xFF);
|
||||
int hash2Value = temp & (kHash2Size - 1);
|
||||
_hash[hash2Value] = _pos;
|
||||
temp ^= ((int)(_bufferBase[cur + 2] & 0xFF) << 8);
|
||||
int hash3Value = temp & (kHash3Size - 1);
|
||||
_hash[kHash3Offset + hash3Value] = _pos;
|
||||
hashValue = (temp ^ (CrcTable[_bufferBase[cur + 3] & 0xFF] << 5)) & _hashMask;
|
||||
}
|
||||
else
|
||||
hashValue = ((_bufferBase[cur] & 0xFF) ^ ((int)(_bufferBase[cur + 1] & 0xFF) << 8));
|
||||
|
||||
int curMatch = _hash[kFixHashSize + hashValue];
|
||||
_hash[kFixHashSize + hashValue] = _pos;
|
||||
|
||||
int ptr0 = (_cyclicBufferPos << 1) + 1;
|
||||
int ptr1 = (_cyclicBufferPos << 1);
|
||||
|
||||
int len0, len1;
|
||||
len0 = len1 = kNumHashDirectBytes;
|
||||
|
||||
int count = _cutValue;
|
||||
while (true)
|
||||
{
|
||||
if (curMatch <= matchMinPos || count-- == 0)
|
||||
{
|
||||
_son[ptr0] = _son[ptr1] = kEmptyHashValue;
|
||||
break;
|
||||
}
|
||||
|
||||
int delta = _pos - curMatch;
|
||||
int cyclicPos = ((delta <= _cyclicBufferPos) ?
|
||||
(_cyclicBufferPos - delta) :
|
||||
(_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
|
||||
|
||||
int pby1 = _bufferOffset + curMatch;
|
||||
int len = Math.min(len0, len1);
|
||||
if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
|
||||
{
|
||||
while (++len != lenLimit)
|
||||
if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
|
||||
break;
|
||||
if (len == lenLimit)
|
||||
{
|
||||
_son[ptr1] = _son[cyclicPos];
|
||||
_son[ptr0] = _son[cyclicPos + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((_bufferBase[pby1 + len] & 0xFF) < (_bufferBase[cur + len] & 0xFF))
|
||||
{
|
||||
_son[ptr1] = curMatch;
|
||||
ptr1 = cyclicPos + 1;
|
||||
curMatch = _son[ptr1];
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
_son[ptr0] = curMatch;
|
||||
ptr0 = cyclicPos;
|
||||
curMatch = _son[ptr0];
|
||||
len0 = len;
|
||||
}
|
||||
}
|
||||
MovePos();
|
||||
}
|
||||
while (--num != 0);
|
||||
}
|
||||
|
||||
void NormalizeLinks(int[] items, int numItems, int subValue)
|
||||
{
|
||||
for (int i = 0; i < numItems; i++)
|
||||
{
|
||||
int value = items[i];
|
||||
if (value <= subValue)
|
||||
value = kEmptyHashValue;
|
||||
else
|
||||
value -= subValue;
|
||||
items[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void Normalize()
|
||||
{
|
||||
int subValue = _pos - _cyclicBufferSize;
|
||||
NormalizeLinks(_son, _cyclicBufferSize * 2, subValue);
|
||||
NormalizeLinks(_hash, _hashSizeSum, subValue);
|
||||
ReduceOffsets(subValue);
|
||||
}
|
||||
|
||||
public void SetCutValue(int cutValue) { _cutValue = cutValue; }
|
||||
|
||||
private static final int[] CrcTable = new int[256];
|
||||
|
||||
static
|
||||
{
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
int r = i;
|
||||
for (int j = 0; j < 8; j++)
|
||||
if ((r & 1) != 0)
|
||||
r = (r >>> 1) ^ 0xEDB88320;
|
||||
else
|
||||
r >>>= 1;
|
||||
CrcTable[i] = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
131
libsrc/LZMA/src/SevenZip/Compression/LZ/InWindow.java
Normal file
131
libsrc/LZMA/src/SevenZip/Compression/LZ/InWindow.java
Normal file
@@ -0,0 +1,131 @@
|
||||
// LZ.InWindow
|
||||
|
||||
package SevenZip.Compression.LZ;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class InWindow
|
||||
{
|
||||
public byte[] _bufferBase; // pointer to buffer with data
|
||||
java.io.InputStream _stream;
|
||||
int _posLimit; // offset (from _buffer) of first byte when new block reading must be done
|
||||
boolean _streamEndWasReached; // if (true) then _streamPos shows real end of stream
|
||||
|
||||
int _pointerToLastSafePosition;
|
||||
|
||||
public int _bufferOffset;
|
||||
|
||||
public int _blockSize; // Size of Allocated memory block
|
||||
public int _pos; // offset (from _buffer) of curent byte
|
||||
int _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
|
||||
int _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
|
||||
public int _streamPos; // offset (from _buffer) of first not read byte from Stream
|
||||
|
||||
public void MoveBlock()
|
||||
{
|
||||
int offset = _bufferOffset + _pos - _keepSizeBefore;
|
||||
// we need one additional byte, since MovePos moves on 1 byte.
|
||||
if (offset > 0)
|
||||
offset--;
|
||||
|
||||
int numBytes = _bufferOffset + _streamPos - offset;
|
||||
|
||||
// check negative offset ????
|
||||
for (int i = 0; i < numBytes; i++)
|
||||
_bufferBase[i] = _bufferBase[offset + i];
|
||||
_bufferOffset -= offset;
|
||||
}
|
||||
|
||||
public void ReadBlock() throws IOException
|
||||
{
|
||||
if (_streamEndWasReached)
|
||||
return;
|
||||
while (true)
|
||||
{
|
||||
int size = (0 - _bufferOffset) + _blockSize - _streamPos;
|
||||
if (size == 0)
|
||||
return;
|
||||
int numReadBytes = _stream.read(_bufferBase, _bufferOffset + _streamPos, size);
|
||||
if (numReadBytes == -1)
|
||||
{
|
||||
_posLimit = _streamPos;
|
||||
int pointerToPostion = _bufferOffset + _posLimit;
|
||||
if (pointerToPostion > _pointerToLastSafePosition)
|
||||
_posLimit = _pointerToLastSafePosition - _bufferOffset;
|
||||
|
||||
_streamEndWasReached = true;
|
||||
return;
|
||||
}
|
||||
_streamPos += numReadBytes;
|
||||
if (_streamPos >= _pos + _keepSizeAfter)
|
||||
_posLimit = _streamPos - _keepSizeAfter;
|
||||
}
|
||||
}
|
||||
|
||||
void Free() { _bufferBase = null; }
|
||||
|
||||
public void Create(int keepSizeBefore, int keepSizeAfter, int keepSizeReserv)
|
||||
{
|
||||
_keepSizeBefore = keepSizeBefore;
|
||||
_keepSizeAfter = keepSizeAfter;
|
||||
int blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
|
||||
if (_bufferBase == null || _blockSize != blockSize)
|
||||
{
|
||||
Free();
|
||||
_blockSize = blockSize;
|
||||
_bufferBase = new byte[_blockSize];
|
||||
}
|
||||
_pointerToLastSafePosition = _blockSize - keepSizeAfter;
|
||||
}
|
||||
|
||||
public void SetStream(java.io.InputStream stream) { _stream = stream; }
|
||||
public void ReleaseStream() { _stream = null; }
|
||||
|
||||
public void Init() throws IOException
|
||||
{
|
||||
_bufferOffset = 0;
|
||||
_pos = 0;
|
||||
_streamPos = 0;
|
||||
_streamEndWasReached = false;
|
||||
ReadBlock();
|
||||
}
|
||||
|
||||
public void MovePos() throws IOException
|
||||
{
|
||||
_pos++;
|
||||
if (_pos > _posLimit)
|
||||
{
|
||||
int pointerToPostion = _bufferOffset + _pos;
|
||||
if (pointerToPostion > _pointerToLastSafePosition)
|
||||
MoveBlock();
|
||||
ReadBlock();
|
||||
}
|
||||
}
|
||||
|
||||
public byte GetIndexByte(int index) { return _bufferBase[_bufferOffset + _pos + index]; }
|
||||
|
||||
// index + limit have not to exceed _keepSizeAfter;
|
||||
public int GetMatchLen(int index, int distance, int limit)
|
||||
{
|
||||
if (_streamEndWasReached)
|
||||
if ((_pos + index) + limit > _streamPos)
|
||||
limit = _streamPos - (_pos + index);
|
||||
distance++;
|
||||
// Byte *pby = _buffer + (size_t)_pos + index;
|
||||
int pby = _bufferOffset + _pos + index;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++);
|
||||
return i;
|
||||
}
|
||||
|
||||
public int GetNumAvailableBytes() { return _streamPos - _pos; }
|
||||
|
||||
public void ReduceOffsets(int subValue)
|
||||
{
|
||||
_bufferOffset += subValue;
|
||||
_posLimit -= subValue;
|
||||
_pos -= subValue;
|
||||
_streamPos -= subValue;
|
||||
}
|
||||
}
|
||||
85
libsrc/LZMA/src/SevenZip/Compression/LZ/OutWindow.java
Normal file
85
libsrc/LZMA/src/SevenZip/Compression/LZ/OutWindow.java
Normal file
@@ -0,0 +1,85 @@
|
||||
// LZ.OutWindow
|
||||
|
||||
package SevenZip.Compression.LZ;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class OutWindow
|
||||
{
|
||||
byte[] _buffer;
|
||||
int _pos;
|
||||
int _windowSize = 0;
|
||||
int _streamPos;
|
||||
java.io.OutputStream _stream;
|
||||
|
||||
public void Create(int windowSize)
|
||||
{
|
||||
if (_buffer == null || _windowSize != windowSize)
|
||||
_buffer = new byte[windowSize];
|
||||
_windowSize = windowSize;
|
||||
_pos = 0;
|
||||
_streamPos = 0;
|
||||
}
|
||||
|
||||
public void SetStream(java.io.OutputStream stream) throws IOException
|
||||
{
|
||||
ReleaseStream();
|
||||
_stream = stream;
|
||||
}
|
||||
|
||||
public void ReleaseStream() throws IOException
|
||||
{
|
||||
Flush();
|
||||
_stream = null;
|
||||
}
|
||||
|
||||
public void Init(boolean solid)
|
||||
{
|
||||
if (!solid)
|
||||
{
|
||||
_streamPos = 0;
|
||||
_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void Flush() throws IOException
|
||||
{
|
||||
int size = _pos - _streamPos;
|
||||
if (size == 0)
|
||||
return;
|
||||
_stream.write(_buffer, _streamPos, size);
|
||||
if (_pos >= _windowSize)
|
||||
_pos = 0;
|
||||
_streamPos = _pos;
|
||||
}
|
||||
|
||||
public void CopyBlock(int distance, int len) throws IOException
|
||||
{
|
||||
int pos = _pos - distance - 1;
|
||||
if (pos < 0)
|
||||
pos += _windowSize;
|
||||
for (; len != 0; len--)
|
||||
{
|
||||
if (pos >= _windowSize)
|
||||
pos = 0;
|
||||
_buffer[_pos++] = _buffer[pos++];
|
||||
if (_pos >= _windowSize)
|
||||
Flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void PutByte(byte b) throws IOException
|
||||
{
|
||||
_buffer[_pos++] = b;
|
||||
if (_pos >= _windowSize)
|
||||
Flush();
|
||||
}
|
||||
|
||||
public byte GetByte(int distance)
|
||||
{
|
||||
int pos = _pos - distance - 1;
|
||||
if (pos < 0)
|
||||
pos += _windowSize;
|
||||
return _buffer[pos];
|
||||
}
|
||||
}
|
||||
88
libsrc/LZMA/src/SevenZip/Compression/LZMA/Base.java
Normal file
88
libsrc/LZMA/src/SevenZip/Compression/LZMA/Base.java
Normal file
@@ -0,0 +1,88 @@
|
||||
// Base.java
|
||||
|
||||
package SevenZip.Compression.LZMA;
|
||||
|
||||
public class Base
|
||||
{
|
||||
public static final int kNumRepDistances = 4;
|
||||
public static final int kNumStates = 12;
|
||||
|
||||
public static final int StateInit()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final int StateUpdateChar(int index)
|
||||
{
|
||||
if (index < 4)
|
||||
return 0;
|
||||
if (index < 10)
|
||||
return index - 3;
|
||||
return index - 6;
|
||||
}
|
||||
|
||||
public static final int StateUpdateMatch(int index)
|
||||
{
|
||||
return (index < 7 ? 7 : 10);
|
||||
}
|
||||
|
||||
public static final int StateUpdateRep(int index)
|
||||
{
|
||||
return (index < 7 ? 8 : 11);
|
||||
}
|
||||
|
||||
public static final int StateUpdateShortRep(int index)
|
||||
{
|
||||
return (index < 7 ? 9 : 11);
|
||||
}
|
||||
|
||||
public static final boolean StateIsCharState(int index)
|
||||
{
|
||||
return index < 7;
|
||||
}
|
||||
|
||||
public static final int kNumPosSlotBits = 6;
|
||||
public static final int kDicLogSizeMin = 0;
|
||||
// public static final int kDicLogSizeMax = 28;
|
||||
// public static final int kDistTableSizeMax = kDicLogSizeMax * 2;
|
||||
|
||||
public static final int kNumLenToPosStatesBits = 2; // it's for speed optimization
|
||||
public static final int kNumLenToPosStates = 1 << kNumLenToPosStatesBits;
|
||||
|
||||
public static final int kMatchMinLen = 2;
|
||||
|
||||
public static final int GetLenToPosState(int len)
|
||||
{
|
||||
len -= kMatchMinLen;
|
||||
if (len < kNumLenToPosStates)
|
||||
return len;
|
||||
return (int)(kNumLenToPosStates - 1);
|
||||
}
|
||||
|
||||
public static final int kNumAlignBits = 4;
|
||||
public static final int kAlignTableSize = 1 << kNumAlignBits;
|
||||
public static final int kAlignMask = (kAlignTableSize - 1);
|
||||
|
||||
public static final int kStartPosModelIndex = 4;
|
||||
public static final int kEndPosModelIndex = 14;
|
||||
public static final int kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
|
||||
|
||||
public static final int kNumFullDistances = 1 << (kEndPosModelIndex / 2);
|
||||
|
||||
public static final int kNumLitPosStatesBitsEncodingMax = 4;
|
||||
public static final int kNumLitContextBitsMax = 8;
|
||||
|
||||
public static final int kNumPosStatesBitsMax = 4;
|
||||
public static final int kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
|
||||
public static final int kNumPosStatesBitsEncodingMax = 4;
|
||||
public static final int kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
|
||||
|
||||
public static final int kNumLowLenBits = 3;
|
||||
public static final int kNumMidLenBits = 3;
|
||||
public static final int kNumHighLenBits = 8;
|
||||
public static final int kNumLowLenSymbols = 1 << kNumLowLenBits;
|
||||
public static final int kNumMidLenSymbols = 1 << kNumMidLenBits;
|
||||
public static final int kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols +
|
||||
(1 << kNumHighLenBits);
|
||||
public static final int kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1;
|
||||
}
|
||||
329
libsrc/LZMA/src/SevenZip/Compression/LZMA/Decoder.java
Normal file
329
libsrc/LZMA/src/SevenZip/Compression/LZMA/Decoder.java
Normal file
@@ -0,0 +1,329 @@
|
||||
package SevenZip.Compression.LZMA;
|
||||
|
||||
import SevenZip.Compression.RangeCoder.BitTreeDecoder;
|
||||
import SevenZip.Compression.LZMA.Base;
|
||||
import SevenZip.Compression.LZ.OutWindow;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Decoder
|
||||
{
|
||||
class LenDecoder
|
||||
{
|
||||
short[] m_Choice = new short[2];
|
||||
BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
|
||||
BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
|
||||
BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);
|
||||
int m_NumPosStates = 0;
|
||||
|
||||
public void Create(int numPosStates)
|
||||
{
|
||||
for (; m_NumPosStates < numPosStates; m_NumPosStates++)
|
||||
{
|
||||
m_LowCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumLowLenBits);
|
||||
m_MidCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumMidLenBits);
|
||||
}
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_Choice);
|
||||
for (int posState = 0; posState < m_NumPosStates; posState++)
|
||||
{
|
||||
m_LowCoder[posState].Init();
|
||||
m_MidCoder[posState].Init();
|
||||
}
|
||||
m_HighCoder.Init();
|
||||
}
|
||||
|
||||
public int Decode(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, int posState) throws IOException
|
||||
{
|
||||
if (rangeDecoder.DecodeBit(m_Choice, 0) == 0)
|
||||
return m_LowCoder[posState].Decode(rangeDecoder);
|
||||
int symbol = Base.kNumLowLenSymbols;
|
||||
if (rangeDecoder.DecodeBit(m_Choice, 1) == 0)
|
||||
symbol += m_MidCoder[posState].Decode(rangeDecoder);
|
||||
else
|
||||
symbol += Base.kNumMidLenSymbols + m_HighCoder.Decode(rangeDecoder);
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
|
||||
class LiteralDecoder
|
||||
{
|
||||
class Decoder2
|
||||
{
|
||||
short[] m_Decoders = new short[0x300];
|
||||
|
||||
public void Init()
|
||||
{
|
||||
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_Decoders);
|
||||
}
|
||||
|
||||
public byte DecodeNormal(SevenZip.Compression.RangeCoder.Decoder rangeDecoder) throws IOException
|
||||
{
|
||||
int symbol = 1;
|
||||
do
|
||||
symbol = (symbol << 1) | rangeDecoder.DecodeBit(m_Decoders, symbol);
|
||||
while (symbol < 0x100);
|
||||
return (byte)symbol;
|
||||
}
|
||||
|
||||
public byte DecodeWithMatchByte(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, byte matchByte) throws IOException
|
||||
{
|
||||
int symbol = 1;
|
||||
do
|
||||
{
|
||||
int matchBit = (matchByte >> 7) & 1;
|
||||
matchByte <<= 1;
|
||||
int bit = rangeDecoder.DecodeBit(m_Decoders, ((1 + matchBit) << 8) + symbol);
|
||||
symbol = (symbol << 1) | bit;
|
||||
if (matchBit != bit)
|
||||
{
|
||||
while (symbol < 0x100)
|
||||
symbol = (symbol << 1) | rangeDecoder.DecodeBit(m_Decoders, symbol);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (symbol < 0x100);
|
||||
return (byte)symbol;
|
||||
}
|
||||
}
|
||||
|
||||
Decoder2[] m_Coders;
|
||||
int m_NumPrevBits;
|
||||
int m_NumPosBits;
|
||||
int m_PosMask;
|
||||
|
||||
public void Create(int numPosBits, int numPrevBits)
|
||||
{
|
||||
if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits)
|
||||
return;
|
||||
m_NumPosBits = numPosBits;
|
||||
m_PosMask = (1 << numPosBits) - 1;
|
||||
m_NumPrevBits = numPrevBits;
|
||||
int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
|
||||
m_Coders = new Decoder2[numStates];
|
||||
for (int i = 0; i < numStates; i++)
|
||||
m_Coders[i] = new Decoder2();
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
|
||||
for (int i = 0; i < numStates; i++)
|
||||
m_Coders[i].Init();
|
||||
}
|
||||
|
||||
Decoder2 GetDecoder(int pos, byte prevByte)
|
||||
{
|
||||
return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + ((prevByte & 0xFF) >>> (8 - m_NumPrevBits))];
|
||||
}
|
||||
}
|
||||
|
||||
OutWindow m_OutWindow = new OutWindow();
|
||||
SevenZip.Compression.RangeCoder.Decoder m_RangeDecoder = new SevenZip.Compression.RangeCoder.Decoder();
|
||||
|
||||
short[] m_IsMatchDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax];
|
||||
short[] m_IsRepDecoders = new short[Base.kNumStates];
|
||||
short[] m_IsRepG0Decoders = new short[Base.kNumStates];
|
||||
short[] m_IsRepG1Decoders = new short[Base.kNumStates];
|
||||
short[] m_IsRepG2Decoders = new short[Base.kNumStates];
|
||||
short[] m_IsRep0LongDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax];
|
||||
|
||||
BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];
|
||||
short[] m_PosDecoders = new short[Base.kNumFullDistances - Base.kEndPosModelIndex];
|
||||
|
||||
BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);
|
||||
|
||||
LenDecoder m_LenDecoder = new LenDecoder();
|
||||
LenDecoder m_RepLenDecoder = new LenDecoder();
|
||||
|
||||
LiteralDecoder m_LiteralDecoder = new LiteralDecoder();
|
||||
|
||||
int m_DictionarySize = -1;
|
||||
int m_DictionarySizeCheck = -1;
|
||||
|
||||
int m_PosStateMask;
|
||||
|
||||
public Decoder()
|
||||
{
|
||||
for (int i = 0; i < Base.kNumLenToPosStates; i++)
|
||||
m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);
|
||||
}
|
||||
|
||||
boolean SetDictionarySize(int dictionarySize)
|
||||
{
|
||||
if (dictionarySize < 0)
|
||||
return false;
|
||||
if (m_DictionarySize != dictionarySize)
|
||||
{
|
||||
m_DictionarySize = dictionarySize;
|
||||
m_DictionarySizeCheck = Math.max(m_DictionarySize, 1);
|
||||
m_OutWindow.Create(Math.max(m_DictionarySizeCheck, (1 << 12)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean SetLcLpPb(int lc, int lp, int pb)
|
||||
{
|
||||
if (lc > Base.kNumLitContextBitsMax || lp > 4 || pb > Base.kNumPosStatesBitsMax)
|
||||
return false;
|
||||
m_LiteralDecoder.Create(lp, lc);
|
||||
int numPosStates = 1 << pb;
|
||||
m_LenDecoder.Create(numPosStates);
|
||||
m_RepLenDecoder.Create(numPosStates);
|
||||
m_PosStateMask = numPosStates - 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Init() throws IOException
|
||||
{
|
||||
m_OutWindow.Init(false);
|
||||
|
||||
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsMatchDecoders);
|
||||
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRep0LongDecoders);
|
||||
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepDecoders);
|
||||
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG0Decoders);
|
||||
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG1Decoders);
|
||||
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG2Decoders);
|
||||
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_PosDecoders);
|
||||
|
||||
m_LiteralDecoder.Init();
|
||||
int i;
|
||||
for (i = 0; i < Base.kNumLenToPosStates; i++)
|
||||
m_PosSlotDecoder[i].Init();
|
||||
m_LenDecoder.Init();
|
||||
m_RepLenDecoder.Init();
|
||||
m_PosAlignDecoder.Init();
|
||||
m_RangeDecoder.Init();
|
||||
}
|
||||
|
||||
public boolean Code(java.io.InputStream inStream, java.io.OutputStream outStream,
|
||||
long outSize) throws IOException
|
||||
{
|
||||
m_RangeDecoder.SetStream(inStream);
|
||||
m_OutWindow.SetStream(outStream);
|
||||
Init();
|
||||
|
||||
int state = Base.StateInit();
|
||||
int rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
|
||||
|
||||
long nowPos64 = 0;
|
||||
byte prevByte = 0;
|
||||
while (outSize < 0 || nowPos64 < outSize)
|
||||
{
|
||||
int posState = (int)nowPos64 & m_PosStateMask;
|
||||
if (m_RangeDecoder.DecodeBit(m_IsMatchDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0)
|
||||
{
|
||||
LiteralDecoder.Decoder2 decoder2 = m_LiteralDecoder.GetDecoder((int)nowPos64, prevByte);
|
||||
if (!Base.StateIsCharState(state))
|
||||
prevByte = decoder2.DecodeWithMatchByte(m_RangeDecoder, m_OutWindow.GetByte(rep0));
|
||||
else
|
||||
prevByte = decoder2.DecodeNormal(m_RangeDecoder);
|
||||
m_OutWindow.PutByte(prevByte);
|
||||
state = Base.StateUpdateChar(state);
|
||||
nowPos64++;
|
||||
}
|
||||
else
|
||||
{
|
||||
int len;
|
||||
if (m_RangeDecoder.DecodeBit(m_IsRepDecoders, state) == 1)
|
||||
{
|
||||
len = 0;
|
||||
if (m_RangeDecoder.DecodeBit(m_IsRepG0Decoders, state) == 0)
|
||||
{
|
||||
if (m_RangeDecoder.DecodeBit(m_IsRep0LongDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0)
|
||||
{
|
||||
state = Base.StateUpdateShortRep(state);
|
||||
len = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int distance;
|
||||
if (m_RangeDecoder.DecodeBit(m_IsRepG1Decoders, state) == 0)
|
||||
distance = rep1;
|
||||
else
|
||||
{
|
||||
if (m_RangeDecoder.DecodeBit(m_IsRepG2Decoders, state) == 0)
|
||||
distance = rep2;
|
||||
else
|
||||
{
|
||||
distance = rep3;
|
||||
rep3 = rep2;
|
||||
}
|
||||
rep2 = rep1;
|
||||
}
|
||||
rep1 = rep0;
|
||||
rep0 = distance;
|
||||
}
|
||||
if (len == 0)
|
||||
{
|
||||
len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen;
|
||||
state = Base.StateUpdateRep(state);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rep3 = rep2;
|
||||
rep2 = rep1;
|
||||
rep1 = rep0;
|
||||
len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState);
|
||||
state = Base.StateUpdateMatch(state);
|
||||
int posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder);
|
||||
if (posSlot >= Base.kStartPosModelIndex)
|
||||
{
|
||||
int numDirectBits = (posSlot >> 1) - 1;
|
||||
rep0 = ((2 | (posSlot & 1)) << numDirectBits);
|
||||
if (posSlot < Base.kEndPosModelIndex)
|
||||
rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,
|
||||
rep0 - posSlot - 1, m_RangeDecoder, numDirectBits);
|
||||
else
|
||||
{
|
||||
rep0 += (m_RangeDecoder.DecodeDirectBits(
|
||||
numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);
|
||||
rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
|
||||
if (rep0 < 0)
|
||||
{
|
||||
if (rep0 == -1)
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
rep0 = posSlot;
|
||||
}
|
||||
if (rep0 >= nowPos64 || rep0 >= m_DictionarySizeCheck)
|
||||
{
|
||||
// m_OutWindow.Flush();
|
||||
return false;
|
||||
}
|
||||
m_OutWindow.CopyBlock(rep0, len);
|
||||
nowPos64 += len;
|
||||
prevByte = m_OutWindow.GetByte(0);
|
||||
}
|
||||
}
|
||||
m_OutWindow.Flush();
|
||||
m_OutWindow.ReleaseStream();
|
||||
m_RangeDecoder.ReleaseStream();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean SetDecoderProperties(byte[] properties)
|
||||
{
|
||||
if (properties.length < 5)
|
||||
return false;
|
||||
int val = properties[0] & 0xFF;
|
||||
int lc = val % 9;
|
||||
int remainder = val / 9;
|
||||
int lp = remainder % 5;
|
||||
int pb = remainder / 5;
|
||||
int dictionarySize = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
dictionarySize += ((int)(properties[1 + i]) & 0xFF) << (i * 8);
|
||||
if (!SetLcLpPb(lc, lp, pb))
|
||||
return false;
|
||||
return SetDictionarySize(dictionarySize);
|
||||
}
|
||||
}
|
||||
1416
libsrc/LZMA/src/SevenZip/Compression/LZMA/Encoder.java
Normal file
1416
libsrc/LZMA/src/SevenZip/Compression/LZMA/Encoder.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,55 @@
|
||||
package SevenZip.Compression.RangeCoder;
|
||||
|
||||
public class BitTreeDecoder
|
||||
{
|
||||
short[] Models;
|
||||
int NumBitLevels;
|
||||
|
||||
public BitTreeDecoder(int numBitLevels)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new short[1 << numBitLevels];
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
Decoder.InitBitModels(Models);
|
||||
}
|
||||
|
||||
public int Decode(Decoder rangeDecoder) throws java.io.IOException
|
||||
{
|
||||
int m = 1;
|
||||
for (int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--)
|
||||
m = (m << 1) + rangeDecoder.DecodeBit(Models, m);
|
||||
return m - (1 << NumBitLevels);
|
||||
}
|
||||
|
||||
public int ReverseDecode(Decoder rangeDecoder) throws java.io.IOException
|
||||
{
|
||||
int m = 1;
|
||||
int symbol = 0;
|
||||
for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
{
|
||||
int bit = rangeDecoder.DecodeBit(Models, m);
|
||||
m <<= 1;
|
||||
m += bit;
|
||||
symbol |= (bit << bitIndex);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public static int ReverseDecode(short[] Models, int startIndex,
|
||||
Decoder rangeDecoder, int NumBitLevels) throws java.io.IOException
|
||||
{
|
||||
int m = 1;
|
||||
int symbol = 0;
|
||||
for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
{
|
||||
int bit = rangeDecoder.DecodeBit(Models, startIndex + m);
|
||||
m <<= 1;
|
||||
m += bit;
|
||||
symbol |= (bit << bitIndex);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package SevenZip.Compression.RangeCoder;
|
||||
import java.io.IOException;
|
||||
|
||||
public class BitTreeEncoder
|
||||
{
|
||||
short[] Models;
|
||||
int NumBitLevels;
|
||||
|
||||
public BitTreeEncoder(int numBitLevels)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new short[1 << numBitLevels];
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
Decoder.InitBitModels(Models);
|
||||
}
|
||||
|
||||
public void Encode(Encoder rangeEncoder, int symbol) throws IOException
|
||||
{
|
||||
int m = 1;
|
||||
for (int bitIndex = NumBitLevels; bitIndex != 0; )
|
||||
{
|
||||
bitIndex--;
|
||||
int bit = (symbol >>> bitIndex) & 1;
|
||||
rangeEncoder.Encode(Models, m, bit);
|
||||
m = (m << 1) | bit;
|
||||
}
|
||||
}
|
||||
|
||||
public void ReverseEncode(Encoder rangeEncoder, int symbol) throws IOException
|
||||
{
|
||||
int m = 1;
|
||||
for (int i = 0; i < NumBitLevels; i++)
|
||||
{
|
||||
int bit = symbol & 1;
|
||||
rangeEncoder.Encode(Models, m, bit);
|
||||
m = (m << 1) | bit;
|
||||
symbol >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
public int GetPrice(int symbol)
|
||||
{
|
||||
int price = 0;
|
||||
int m = 1;
|
||||
for (int bitIndex = NumBitLevels; bitIndex != 0; )
|
||||
{
|
||||
bitIndex--;
|
||||
int bit = (symbol >>> bitIndex) & 1;
|
||||
price += Encoder.GetPrice(Models[m], bit);
|
||||
m = (m << 1) + bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
|
||||
public int ReverseGetPrice(int symbol)
|
||||
{
|
||||
int price = 0;
|
||||
int m = 1;
|
||||
for (int i = NumBitLevels; i != 0; i--)
|
||||
{
|
||||
int bit = symbol & 1;
|
||||
symbol >>>= 1;
|
||||
price += Encoder.GetPrice(Models[m], bit);
|
||||
m = (m << 1) | bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
|
||||
public static int ReverseGetPrice(short[] Models, int startIndex,
|
||||
int NumBitLevels, int symbol)
|
||||
{
|
||||
int price = 0;
|
||||
int m = 1;
|
||||
for (int i = NumBitLevels; i != 0; i--)
|
||||
{
|
||||
int bit = symbol & 1;
|
||||
symbol >>>= 1;
|
||||
price += Encoder.GetPrice(Models[startIndex + m], bit);
|
||||
m = (m << 1) | bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
|
||||
public static void ReverseEncode(short[] Models, int startIndex,
|
||||
Encoder rangeEncoder, int NumBitLevels, int symbol) throws IOException
|
||||
{
|
||||
int m = 1;
|
||||
for (int i = 0; i < NumBitLevels; i++)
|
||||
{
|
||||
int bit = symbol & 1;
|
||||
rangeEncoder.Encode(Models, startIndex + m, bit);
|
||||
m = (m << 1) | bit;
|
||||
symbol >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
88
libsrc/LZMA/src/SevenZip/Compression/RangeCoder/Decoder.java
Normal file
88
libsrc/LZMA/src/SevenZip/Compression/RangeCoder/Decoder.java
Normal file
@@ -0,0 +1,88 @@
|
||||
package SevenZip.Compression.RangeCoder;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Decoder
|
||||
{
|
||||
static final int kTopMask = ~((1 << 24) - 1);
|
||||
|
||||
static final int kNumBitModelTotalBits = 11;
|
||||
static final int kBitModelTotal = (1 << kNumBitModelTotalBits);
|
||||
static final int kNumMoveBits = 5;
|
||||
|
||||
int Range;
|
||||
int Code;
|
||||
|
||||
java.io.InputStream Stream;
|
||||
|
||||
public final void SetStream(java.io.InputStream stream)
|
||||
{
|
||||
Stream = stream;
|
||||
}
|
||||
|
||||
public final void ReleaseStream()
|
||||
{
|
||||
Stream = null;
|
||||
}
|
||||
|
||||
public final void Init() throws IOException
|
||||
{
|
||||
Code = 0;
|
||||
Range = -1;
|
||||
for (int i = 0; i < 5; i++)
|
||||
Code = (Code << 8) | Stream.read();
|
||||
}
|
||||
|
||||
public final int DecodeDirectBits(int numTotalBits) throws IOException
|
||||
{
|
||||
int result = 0;
|
||||
for (int i = numTotalBits; i != 0; i--)
|
||||
{
|
||||
Range >>>= 1;
|
||||
int t = ((Code - Range) >>> 31);
|
||||
Code -= Range & (t - 1);
|
||||
result = (result << 1) | (1 - t);
|
||||
|
||||
if ((Range & kTopMask) == 0)
|
||||
{
|
||||
Code = (Code << 8) | Stream.read();
|
||||
Range <<= 8;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int DecodeBit(short[] probs, int index) throws IOException
|
||||
{
|
||||
int prob = probs[index];
|
||||
int newBound = (Range >>> kNumBitModelTotalBits) * prob;
|
||||
if ((Code ^ 0x80000000) < (newBound ^ 0x80000000))
|
||||
{
|
||||
Range = newBound;
|
||||
probs[index] = (short)(prob + ((kBitModelTotal - prob) >>> kNumMoveBits));
|
||||
if ((Range & kTopMask) == 0)
|
||||
{
|
||||
Code = (Code << 8) | Stream.read();
|
||||
Range <<= 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Range -= newBound;
|
||||
Code -= newBound;
|
||||
probs[index] = (short)(prob - ((prob) >>> kNumMoveBits));
|
||||
if ((Range & kTopMask) == 0)
|
||||
{
|
||||
Code = (Code << 8) | Stream.read();
|
||||
Range <<= 8;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public static void InitBitModels(short[] probs)
|
||||
{
|
||||
for (int i = 0; i < probs.length; i++)
|
||||
probs[i] = (kBitModelTotal >>> 1);
|
||||
}
|
||||
}
|
||||
151
libsrc/LZMA/src/SevenZip/Compression/RangeCoder/Encoder.java
Normal file
151
libsrc/LZMA/src/SevenZip/Compression/RangeCoder/Encoder.java
Normal file
@@ -0,0 +1,151 @@
|
||||
package SevenZip.Compression.RangeCoder;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Encoder
|
||||
{
|
||||
static final int kTopMask = ~((1 << 24) - 1);
|
||||
|
||||
static final int kNumBitModelTotalBits = 11;
|
||||
static final int kBitModelTotal = (1 << kNumBitModelTotalBits);
|
||||
static final int kNumMoveBits = 5;
|
||||
|
||||
java.io.OutputStream Stream;
|
||||
|
||||
long Low;
|
||||
int Range;
|
||||
int _cacheSize;
|
||||
int _cache;
|
||||
|
||||
long _position;
|
||||
|
||||
public void SetStream(java.io.OutputStream stream)
|
||||
{
|
||||
Stream = stream;
|
||||
}
|
||||
|
||||
public void ReleaseStream()
|
||||
{
|
||||
Stream = null;
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
_position = 0;
|
||||
Low = 0;
|
||||
Range = -1;
|
||||
_cacheSize = 1;
|
||||
_cache = 0;
|
||||
}
|
||||
|
||||
public void FlushData() throws IOException
|
||||
{
|
||||
for (int i = 0; i < 5; i++)
|
||||
ShiftLow();
|
||||
}
|
||||
|
||||
public void FlushStream() throws IOException
|
||||
{
|
||||
Stream.flush();
|
||||
}
|
||||
|
||||
public void ShiftLow() throws IOException
|
||||
{
|
||||
int LowHi = (int)(Low >>> 32);
|
||||
if (LowHi != 0 || Low < 0xFF000000L)
|
||||
{
|
||||
_position += _cacheSize;
|
||||
int temp = _cache;
|
||||
do
|
||||
{
|
||||
Stream.write(temp + LowHi);
|
||||
temp = 0xFF;
|
||||
}
|
||||
while(--_cacheSize != 0);
|
||||
_cache = (((int)Low) >>> 24);
|
||||
}
|
||||
_cacheSize++;
|
||||
Low = (Low & 0xFFFFFF) << 8;
|
||||
}
|
||||
|
||||
public void EncodeDirectBits(int v, int numTotalBits) throws IOException
|
||||
{
|
||||
for (int i = numTotalBits - 1; i >= 0; i--)
|
||||
{
|
||||
Range >>>= 1;
|
||||
if (((v >>> i) & 1) == 1)
|
||||
Low += Range;
|
||||
if ((Range & Encoder.kTopMask) == 0)
|
||||
{
|
||||
Range <<= 8;
|
||||
ShiftLow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public long GetProcessedSizeAdd()
|
||||
{
|
||||
return _cacheSize + _position + 4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static final int kNumMoveReducingBits = 2;
|
||||
public static final int kNumBitPriceShiftBits = 6;
|
||||
|
||||
public static void InitBitModels(short[] probs)
|
||||
{
|
||||
for (int i = 0; i < probs.length; i++)
|
||||
probs[i] = (kBitModelTotal >>> 1);
|
||||
}
|
||||
|
||||
public void Encode(short[] probs, int index, int symbol) throws IOException
|
||||
{
|
||||
int prob = probs[index];
|
||||
int newBound = (Range >>> kNumBitModelTotalBits) * prob;
|
||||
if (symbol == 0)
|
||||
{
|
||||
Range = newBound;
|
||||
probs[index] = (short)(prob + ((kBitModelTotal - prob) >>> kNumMoveBits));
|
||||
}
|
||||
else
|
||||
{
|
||||
Low += (newBound & 0xFFFFFFFFL);
|
||||
Range -= newBound;
|
||||
probs[index] = (short)(prob - ((prob) >>> kNumMoveBits));
|
||||
}
|
||||
if ((Range & kTopMask) == 0)
|
||||
{
|
||||
Range <<= 8;
|
||||
ShiftLow();
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] ProbPrices = new int[kBitModelTotal >>> kNumMoveReducingBits];
|
||||
|
||||
static
|
||||
{
|
||||
int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
|
||||
for (int i = kNumBits - 1; i >= 0; i--)
|
||||
{
|
||||
int start = 1 << (kNumBits - i - 1);
|
||||
int end = 1 << (kNumBits - i);
|
||||
for (int j = start; j < end; j++)
|
||||
ProbPrices[j] = (i << kNumBitPriceShiftBits) +
|
||||
(((end - j) << kNumBitPriceShiftBits) >>> (kNumBits - i - 1));
|
||||
}
|
||||
}
|
||||
|
||||
static public int GetPrice(int Prob, int symbol)
|
||||
{
|
||||
return ProbPrices[(((Prob - symbol) ^ ((-symbol))) & (kBitModelTotal - 1)) >>> kNumMoveReducingBits];
|
||||
}
|
||||
static public int GetPrice0(int Prob)
|
||||
{
|
||||
return ProbPrices[Prob >>> kNumMoveReducingBits];
|
||||
}
|
||||
static public int GetPrice1(int Prob)
|
||||
{
|
||||
return ProbPrices[(kBitModelTotal - Prob) >>> kNumMoveReducingBits];
|
||||
}
|
||||
}
|
||||
6
libsrc/LZMA/src/SevenZip/ICodeProgress.java
Normal file
6
libsrc/LZMA/src/SevenZip/ICodeProgress.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package SevenZip;
|
||||
|
||||
public interface ICodeProgress
|
||||
{
|
||||
public void SetProgress(long inSize, long outSize);
|
||||
}
|
||||
253
libsrc/LZMA/src/SevenZip/LzmaAlone.java
Normal file
253
libsrc/LZMA/src/SevenZip/LzmaAlone.java
Normal file
@@ -0,0 +1,253 @@
|
||||
package SevenZip;
|
||||
|
||||
public class LzmaAlone
|
||||
{
|
||||
static public class CommandLine
|
||||
{
|
||||
public static final int kEncode = 0;
|
||||
public static final int kDecode = 1;
|
||||
public static final int kBenchmak = 2;
|
||||
|
||||
public int Command = -1;
|
||||
public int NumBenchmarkPasses = 10;
|
||||
|
||||
public int DictionarySize = 1 << 23;
|
||||
public boolean DictionarySizeIsDefined = false;
|
||||
|
||||
public int Lc = 3;
|
||||
public int Lp = 0;
|
||||
public int Pb = 2;
|
||||
|
||||
public int Fb = 128;
|
||||
public boolean FbIsDefined = false;
|
||||
|
||||
public boolean Eos = false;
|
||||
|
||||
public int Algorithm = 2;
|
||||
public int MatchFinder = 1;
|
||||
|
||||
public String InFile;
|
||||
public String OutFile;
|
||||
|
||||
boolean ParseSwitch(String s)
|
||||
{
|
||||
if (s.startsWith("d"))
|
||||
{
|
||||
DictionarySize = 1 << Integer.parseInt(s.substring(1));
|
||||
DictionarySizeIsDefined = true;
|
||||
}
|
||||
else if (s.startsWith("fb"))
|
||||
{
|
||||
Fb = Integer.parseInt(s.substring(2));
|
||||
FbIsDefined = true;
|
||||
}
|
||||
else if (s.startsWith("a"))
|
||||
Algorithm = Integer.parseInt(s.substring(1));
|
||||
else if (s.startsWith("lc"))
|
||||
Lc = Integer.parseInt(s.substring(2));
|
||||
else if (s.startsWith("lp"))
|
||||
Lp = Integer.parseInt(s.substring(2));
|
||||
else if (s.startsWith("pb"))
|
||||
Pb = Integer.parseInt(s.substring(2));
|
||||
else if (s.startsWith("eos"))
|
||||
Eos = true;
|
||||
else if (s.startsWith("mf"))
|
||||
{
|
||||
String mfs = s.substring(2);
|
||||
if (mfs.equals("bt2"))
|
||||
MatchFinder = 0;
|
||||
else if (mfs.equals("bt4"))
|
||||
MatchFinder = 1;
|
||||
else if (mfs.equals("bt4b"))
|
||||
MatchFinder = 2;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean Parse(String[] args) throws Exception
|
||||
{
|
||||
int pos = 0;
|
||||
boolean switchMode = true;
|
||||
for (int i = 0; i < args.length; i++)
|
||||
{
|
||||
String s = args[i];
|
||||
if (s.length() == 0)
|
||||
return false;
|
||||
if (switchMode)
|
||||
{
|
||||
if (s.compareTo("--") == 0)
|
||||
{
|
||||
switchMode = false;
|
||||
continue;
|
||||
}
|
||||
if (s.charAt(0) == '-')
|
||||
{
|
||||
String sw = s.substring(1).toLowerCase();
|
||||
if (sw.length() == 0)
|
||||
return false;
|
||||
try
|
||||
{
|
||||
if (!ParseSwitch(sw))
|
||||
return false;
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (pos == 0)
|
||||
{
|
||||
if (s.equalsIgnoreCase("e"))
|
||||
Command = kEncode;
|
||||
else if (s.equalsIgnoreCase("d"))
|
||||
Command = kDecode;
|
||||
else if (s.equalsIgnoreCase("b"))
|
||||
Command = kBenchmak;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else if(pos == 1)
|
||||
{
|
||||
if (Command == kBenchmak)
|
||||
{
|
||||
try
|
||||
{
|
||||
NumBenchmarkPasses = Integer.parseInt(s);
|
||||
if (NumBenchmarkPasses < 1)
|
||||
return false;
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
InFile = s;
|
||||
}
|
||||
else if(pos == 2)
|
||||
OutFile = s;
|
||||
else
|
||||
return false;
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void PrintHelp()
|
||||
{
|
||||
System.out.println(
|
||||
"\nUsage: LZMA <e|d> [<switches>...] inputFile outputFile\n" +
|
||||
" e: encode file\n" +
|
||||
" d: decode file\n" +
|
||||
" b: Benchmark\n" +
|
||||
"<Switches>\n" +
|
||||
// " -a{N}: set compression mode - [0, 1], default: 1 (max)\n" +
|
||||
" -d{N}: set dictionary - [0,28], default: 23 (8MB)\n" +
|
||||
" -fb{N}: set number of fast bytes - [5, 273], default: 128\n" +
|
||||
" -lc{N}: set number of literal context bits - [0, 8], default: 3\n" +
|
||||
" -lp{N}: set number of literal pos bits - [0, 4], default: 0\n" +
|
||||
" -pb{N}: set number of pos bits - [0, 4], default: 2\n" +
|
||||
" -mf{MF_ID}: set Match Finder: [bt2, bt4], default: bt4\n" +
|
||||
" -eos: write End Of Stream marker\n"
|
||||
);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
System.out.println("\nLZMA (Java) 4.61 2008-11-23\n");
|
||||
|
||||
if (args.length < 1)
|
||||
{
|
||||
PrintHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
CommandLine params = new CommandLine();
|
||||
if (!params.Parse(args))
|
||||
{
|
||||
System.out.println("\nIncorrect command");
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.Command == CommandLine.kBenchmak)
|
||||
{
|
||||
int dictionary = (1 << 21);
|
||||
if (params.DictionarySizeIsDefined)
|
||||
dictionary = params.DictionarySize;
|
||||
if (params.MatchFinder > 1)
|
||||
throw new Exception("Unsupported match finder");
|
||||
SevenZip.LzmaBench.LzmaBenchmark(params.NumBenchmarkPasses, dictionary);
|
||||
}
|
||||
else if (params.Command == CommandLine.kEncode || params.Command == CommandLine.kDecode)
|
||||
{
|
||||
java.io.File inFile = new java.io.File(params.InFile);
|
||||
java.io.File outFile = new java.io.File(params.OutFile);
|
||||
|
||||
java.io.BufferedInputStream inStream = new java.io.BufferedInputStream(new java.io.FileInputStream(inFile));
|
||||
java.io.BufferedOutputStream outStream = new java.io.BufferedOutputStream(new java.io.FileOutputStream(outFile));
|
||||
|
||||
boolean eos = false;
|
||||
if (params.Eos)
|
||||
eos = true;
|
||||
if (params.Command == CommandLine.kEncode)
|
||||
{
|
||||
SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
|
||||
if (!encoder.SetAlgorithm(params.Algorithm))
|
||||
throw new Exception("Incorrect compression mode");
|
||||
if (!encoder.SetDictionarySize(params.DictionarySize))
|
||||
throw new Exception("Incorrect dictionary size");
|
||||
if (!encoder.SetNumFastBytes(params.Fb))
|
||||
throw new Exception("Incorrect -fb value");
|
||||
if (!encoder.SetMatchFinder(params.MatchFinder))
|
||||
throw new Exception("Incorrect -mf value");
|
||||
if (!encoder.SetLcLpPb(params.Lc, params.Lp, params.Pb))
|
||||
throw new Exception("Incorrect -lc or -lp or -pb value");
|
||||
encoder.SetEndMarkerMode(eos);
|
||||
encoder.WriteCoderProperties(outStream);
|
||||
long fileSize;
|
||||
if (eos)
|
||||
fileSize = -1;
|
||||
else
|
||||
fileSize = inFile.length();
|
||||
for (int i = 0; i < 8; i++)
|
||||
outStream.write((int)(fileSize >>> (8 * i)) & 0xFF);
|
||||
encoder.Code(inStream, outStream, -1, -1, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
int propertiesSize = 5;
|
||||
byte[] properties = new byte[propertiesSize];
|
||||
if (inStream.read(properties, 0, propertiesSize) != propertiesSize)
|
||||
throw new Exception("input .lzma file is too short");
|
||||
SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();
|
||||
if (!decoder.SetDecoderProperties(properties))
|
||||
throw new Exception("Incorrect stream properties");
|
||||
long outSize = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
int v = inStream.read();
|
||||
if (v < 0)
|
||||
throw new Exception("Can't read stream size");
|
||||
outSize |= ((long)v) << (8 * i);
|
||||
}
|
||||
if (!decoder.Code(inStream, outStream, outSize))
|
||||
throw new Exception("Error in data stream");
|
||||
}
|
||||
outStream.flush();
|
||||
outStream.close();
|
||||
inStream.close();
|
||||
}
|
||||
else
|
||||
throw new Exception("Incorrect command");
|
||||
return;
|
||||
}
|
||||
}
|
||||
392
libsrc/LZMA/src/SevenZip/LzmaBench.java
Normal file
392
libsrc/LZMA/src/SevenZip/LzmaBench.java
Normal file
@@ -0,0 +1,392 @@
|
||||
package SevenZip;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class LzmaBench
|
||||
{
|
||||
static final int kAdditionalSize = (1 << 21);
|
||||
static final int kCompressedAdditionalSize = (1 << 10);
|
||||
|
||||
static class CRandomGenerator
|
||||
{
|
||||
int A1;
|
||||
int A2;
|
||||
public CRandomGenerator() { Init(); }
|
||||
public void Init() { A1 = 362436069; A2 = 521288629; }
|
||||
public int GetRnd()
|
||||
{
|
||||
return
|
||||
((A1 = 36969 * (A1 & 0xffff) + (A1 >>> 16)) << 16) ^
|
||||
((A2 = 18000 * (A2 & 0xffff) + (A2 >>> 16)));
|
||||
}
|
||||
};
|
||||
|
||||
static class CBitRandomGenerator
|
||||
{
|
||||
CRandomGenerator RG = new CRandomGenerator();
|
||||
int Value;
|
||||
int NumBits;
|
||||
public void Init()
|
||||
{
|
||||
Value = 0;
|
||||
NumBits = 0;
|
||||
}
|
||||
public int GetRnd(int numBits)
|
||||
{
|
||||
int result;
|
||||
if (NumBits > numBits)
|
||||
{
|
||||
result = Value & ((1 << numBits) - 1);
|
||||
Value >>>= numBits;
|
||||
NumBits -= numBits;
|
||||
return result;
|
||||
}
|
||||
numBits -= NumBits;
|
||||
result = (Value << numBits);
|
||||
Value = RG.GetRnd();
|
||||
result |= Value & (((int)1 << numBits) - 1);
|
||||
Value >>>= numBits;
|
||||
NumBits = 32 - numBits;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
static class CBenchRandomGenerator
|
||||
{
|
||||
CBitRandomGenerator RG = new CBitRandomGenerator();
|
||||
int Pos;
|
||||
int Rep0;
|
||||
|
||||
public int BufferSize;
|
||||
public byte[] Buffer = null;
|
||||
|
||||
public CBenchRandomGenerator() { }
|
||||
public void Set(int bufferSize)
|
||||
{
|
||||
Buffer = new byte[bufferSize];
|
||||
Pos = 0;
|
||||
BufferSize = bufferSize;
|
||||
}
|
||||
int GetRndBit() { return RG.GetRnd(1); }
|
||||
int GetLogRandBits(int numBits)
|
||||
{
|
||||
int len = RG.GetRnd(numBits);
|
||||
return RG.GetRnd((int)len);
|
||||
}
|
||||
int GetOffset()
|
||||
{
|
||||
if (GetRndBit() == 0)
|
||||
return GetLogRandBits(4);
|
||||
return (GetLogRandBits(4) << 10) | RG.GetRnd(10);
|
||||
}
|
||||
int GetLen1() { return RG.GetRnd(1 + (int)RG.GetRnd(2)); }
|
||||
int GetLen2() { return RG.GetRnd(2 + (int)RG.GetRnd(2)); }
|
||||
public void Generate()
|
||||
{
|
||||
RG.Init();
|
||||
Rep0 = 1;
|
||||
while (Pos < BufferSize)
|
||||
{
|
||||
if (GetRndBit() == 0 || Pos < 1)
|
||||
Buffer[Pos++] = (byte)(RG.GetRnd(8));
|
||||
else
|
||||
{
|
||||
int len;
|
||||
if (RG.GetRnd(3) == 0)
|
||||
len = 1 + GetLen1();
|
||||
else
|
||||
{
|
||||
do
|
||||
Rep0 = GetOffset();
|
||||
while (Rep0 >= Pos);
|
||||
Rep0++;
|
||||
len = 2 + GetLen2();
|
||||
}
|
||||
for (int i = 0; i < len && Pos < BufferSize; i++, Pos++)
|
||||
Buffer[Pos] = Buffer[Pos - Rep0];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static class CrcOutStream extends java.io.OutputStream
|
||||
{
|
||||
public CRC CRC = new CRC();
|
||||
|
||||
public void Init()
|
||||
{
|
||||
CRC.Init();
|
||||
}
|
||||
public int GetDigest()
|
||||
{
|
||||
return CRC.GetDigest();
|
||||
}
|
||||
public void write(byte[] b)
|
||||
{
|
||||
CRC.Update(b);
|
||||
}
|
||||
public void write(byte[] b, int off, int len)
|
||||
{
|
||||
CRC.Update(b, off, len);
|
||||
}
|
||||
public void write(int b)
|
||||
{
|
||||
CRC.UpdateByte(b);
|
||||
}
|
||||
};
|
||||
|
||||
static class MyOutputStream extends java.io.OutputStream
|
||||
{
|
||||
byte[] _buffer;
|
||||
int _size;
|
||||
int _pos;
|
||||
|
||||
public MyOutputStream(byte[] buffer)
|
||||
{
|
||||
_buffer = buffer;
|
||||
_size = _buffer.length;
|
||||
}
|
||||
|
||||
public void reset()
|
||||
{
|
||||
_pos = 0;
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException
|
||||
{
|
||||
if (_pos >= _size)
|
||||
throw new IOException("Error");
|
||||
_buffer[_pos++] = (byte)b;
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return _pos;
|
||||
}
|
||||
};
|
||||
|
||||
static class MyInputStream extends java.io.InputStream
|
||||
{
|
||||
byte[] _buffer;
|
||||
int _size;
|
||||
int _pos;
|
||||
|
||||
public MyInputStream(byte[] buffer, int size)
|
||||
{
|
||||
_buffer = buffer;
|
||||
_size = size;
|
||||
}
|
||||
|
||||
public void reset()
|
||||
{
|
||||
_pos = 0;
|
||||
}
|
||||
|
||||
public int read()
|
||||
{
|
||||
if (_pos >= _size)
|
||||
return -1;
|
||||
return _buffer[_pos++] & 0xFF;
|
||||
}
|
||||
};
|
||||
|
||||
static class CProgressInfo implements ICodeProgress
|
||||
{
|
||||
public long ApprovedStart;
|
||||
public long InSize;
|
||||
public long Time;
|
||||
public void Init()
|
||||
{ InSize = 0; }
|
||||
public void SetProgress(long inSize, long outSize)
|
||||
{
|
||||
if (inSize >= ApprovedStart && InSize == 0)
|
||||
{
|
||||
Time = System.currentTimeMillis();
|
||||
InSize = inSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
static final int kSubBits = 8;
|
||||
|
||||
static int GetLogSize(int size)
|
||||
{
|
||||
for (int i = kSubBits; i < 32; i++)
|
||||
for (int j = 0; j < (1 << kSubBits); j++)
|
||||
if (size <= ((1) << i) + (j << (i - kSubBits)))
|
||||
return (i << kSubBits) + j;
|
||||
return (32 << kSubBits);
|
||||
}
|
||||
|
||||
static long MyMultDiv64(long value, long elapsedTime)
|
||||
{
|
||||
long freq = 1000; // ms
|
||||
long elTime = elapsedTime;
|
||||
while (freq > 1000000)
|
||||
{
|
||||
freq >>>= 1;
|
||||
elTime >>>= 1;
|
||||
}
|
||||
if (elTime == 0)
|
||||
elTime = 1;
|
||||
return value * freq / elTime;
|
||||
}
|
||||
|
||||
static long GetCompressRating(int dictionarySize, long elapsedTime, long size)
|
||||
{
|
||||
long t = GetLogSize(dictionarySize) - (18 << kSubBits);
|
||||
long numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits));
|
||||
long numCommands = (long)(size) * numCommandsForOne;
|
||||
return MyMultDiv64(numCommands, elapsedTime);
|
||||
}
|
||||
|
||||
static long GetDecompressRating(long elapsedTime, long outSize, long inSize)
|
||||
{
|
||||
long numCommands = inSize * 220 + outSize * 20;
|
||||
return MyMultDiv64(numCommands, elapsedTime);
|
||||
}
|
||||
|
||||
static long GetTotalRating(
|
||||
int dictionarySize,
|
||||
long elapsedTimeEn, long sizeEn,
|
||||
long elapsedTimeDe,
|
||||
long inSizeDe, long outSizeDe)
|
||||
{
|
||||
return (GetCompressRating(dictionarySize, elapsedTimeEn, sizeEn) +
|
||||
GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2;
|
||||
}
|
||||
|
||||
static void PrintValue(long v)
|
||||
{
|
||||
String s = "";
|
||||
s += v;
|
||||
for (int i = 0; i + s.length() < 6; i++)
|
||||
System.out.print(" ");
|
||||
System.out.print(s);
|
||||
}
|
||||
|
||||
static void PrintRating(long rating)
|
||||
{
|
||||
PrintValue(rating / 1000000);
|
||||
System.out.print(" MIPS");
|
||||
}
|
||||
|
||||
static void PrintResults(
|
||||
int dictionarySize,
|
||||
long elapsedTime,
|
||||
long size,
|
||||
boolean decompressMode, long secondSize)
|
||||
{
|
||||
long speed = MyMultDiv64(size, elapsedTime);
|
||||
PrintValue(speed / 1024);
|
||||
System.out.print(" KB/s ");
|
||||
long rating;
|
||||
if (decompressMode)
|
||||
rating = GetDecompressRating(elapsedTime, size, secondSize);
|
||||
else
|
||||
rating = GetCompressRating(dictionarySize, elapsedTime, size);
|
||||
PrintRating(rating);
|
||||
}
|
||||
|
||||
static public int LzmaBenchmark(int numIterations, int dictionarySize) throws Exception
|
||||
{
|
||||
if (numIterations <= 0)
|
||||
return 0;
|
||||
if (dictionarySize < (1 << 18))
|
||||
{
|
||||
System.out.println("\nError: dictionary size for benchmark must be >= 18 (256 KB)");
|
||||
return 1;
|
||||
}
|
||||
System.out.print("\n Compressing Decompressing\n\n");
|
||||
|
||||
SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
|
||||
SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();
|
||||
|
||||
if (!encoder.SetDictionarySize(dictionarySize))
|
||||
throw new Exception("Incorrect dictionary size");
|
||||
|
||||
int kBufferSize = dictionarySize + kAdditionalSize;
|
||||
int kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;
|
||||
|
||||
ByteArrayOutputStream propStream = new ByteArrayOutputStream();
|
||||
encoder.WriteCoderProperties(propStream);
|
||||
byte[] propArray = propStream.toByteArray();
|
||||
decoder.SetDecoderProperties(propArray);
|
||||
|
||||
CBenchRandomGenerator rg = new CBenchRandomGenerator();
|
||||
|
||||
rg.Set(kBufferSize);
|
||||
rg.Generate();
|
||||
CRC crc = new CRC();
|
||||
crc.Init();
|
||||
crc.Update(rg.Buffer, 0, rg.BufferSize);
|
||||
|
||||
CProgressInfo progressInfo = new CProgressInfo();
|
||||
progressInfo.ApprovedStart = dictionarySize;
|
||||
|
||||
long totalBenchSize = 0;
|
||||
long totalEncodeTime = 0;
|
||||
long totalDecodeTime = 0;
|
||||
long totalCompressedSize = 0;
|
||||
|
||||
MyInputStream inStream = new MyInputStream(rg.Buffer, rg.BufferSize);
|
||||
|
||||
byte[] compressedBuffer = new byte[kCompressedBufferSize];
|
||||
MyOutputStream compressedStream = new MyOutputStream(compressedBuffer);
|
||||
CrcOutStream crcOutStream = new CrcOutStream();
|
||||
MyInputStream inputCompressedStream = null;
|
||||
int compressedSize = 0;
|
||||
for (int i = 0; i < numIterations; i++)
|
||||
{
|
||||
progressInfo.Init();
|
||||
inStream.reset();
|
||||
compressedStream.reset();
|
||||
encoder.Code(inStream, compressedStream, -1, -1, progressInfo);
|
||||
long encodeTime = System.currentTimeMillis() - progressInfo.Time;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
compressedSize = compressedStream.size();
|
||||
inputCompressedStream = new MyInputStream(compressedBuffer, compressedSize);
|
||||
}
|
||||
else if (compressedSize != compressedStream.size())
|
||||
throw (new Exception("Encoding error"));
|
||||
|
||||
if (progressInfo.InSize == 0)
|
||||
throw (new Exception("Internal ERROR 1282"));
|
||||
|
||||
long decodeTime = 0;
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
inputCompressedStream.reset();
|
||||
crcOutStream.Init();
|
||||
|
||||
long outSize = kBufferSize;
|
||||
long startTime = System.currentTimeMillis();
|
||||
if (!decoder.Code(inputCompressedStream, crcOutStream, outSize))
|
||||
throw (new Exception("Decoding Error"));;
|
||||
decodeTime = System.currentTimeMillis() - startTime;
|
||||
if (crcOutStream.GetDigest() != crc.GetDigest())
|
||||
throw (new Exception("CRC Error"));
|
||||
}
|
||||
long benchSize = kBufferSize - (long)progressInfo.InSize;
|
||||
PrintResults(dictionarySize, encodeTime, benchSize, false, 0);
|
||||
System.out.print(" ");
|
||||
PrintResults(dictionarySize, decodeTime, kBufferSize, true, compressedSize);
|
||||
System.out.println();
|
||||
|
||||
totalBenchSize += benchSize;
|
||||
totalEncodeTime += encodeTime;
|
||||
totalDecodeTime += decodeTime;
|
||||
totalCompressedSize += compressedSize;
|
||||
}
|
||||
System.out.println("---------------------------------------------------");
|
||||
PrintResults(dictionarySize, totalEncodeTime, totalBenchSize, false, 0);
|
||||
System.out.print(" ");
|
||||
PrintResults(dictionarySize, totalDecodeTime,
|
||||
kBufferSize * (long)numIterations, true, totalCompressedSize);
|
||||
System.out.println(" Average");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
39
libsrc/Swf2Exe/Swf2Exe.cfg
Normal file
39
libsrc/Swf2Exe/Swf2Exe.cfg
Normal file
@@ -0,0 +1,39 @@
|
||||
-$A8
|
||||
-$B-
|
||||
-$C+
|
||||
-$D+
|
||||
-$E-
|
||||
-$F-
|
||||
-$G+
|
||||
-$H+
|
||||
-$I+
|
||||
-$J-
|
||||
-$K-
|
||||
-$L+
|
||||
-$M-
|
||||
-$N+
|
||||
-$O+
|
||||
-$P+
|
||||
-$Q-
|
||||
-$R-
|
||||
-$S-
|
||||
-$T-
|
||||
-$U-
|
||||
-$V+
|
||||
-$W-
|
||||
-$X+
|
||||
-$YD
|
||||
-$Z1
|
||||
-cg
|
||||
-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
|
||||
-H+
|
||||
-W+
|
||||
-M
|
||||
-$M16384,1048576
|
||||
-K$00400000
|
||||
-E"."
|
||||
-LE"c:\program files (x86)\borland\delphi7\Projects\Bpl"
|
||||
-LN"c:\program files (x86)\borland\delphi7\Projects\Bpl"
|
||||
-w-UNSAFE_TYPE
|
||||
-w-UNSAFE_CODE
|
||||
-w-UNSAFE_CAST
|
||||
138
libsrc/Swf2Exe/Swf2Exe.dof
Normal file
138
libsrc/Swf2Exe/Swf2Exe.dof
Normal file
@@ -0,0 +1,138 @@
|
||||
[FileVersion]
|
||||
Version=7.0
|
||||
[Compiler]
|
||||
A=8
|
||||
B=0
|
||||
C=1
|
||||
D=1
|
||||
E=0
|
||||
F=0
|
||||
G=1
|
||||
H=1
|
||||
I=1
|
||||
J=0
|
||||
K=0
|
||||
L=1
|
||||
M=0
|
||||
N=1
|
||||
O=1
|
||||
P=1
|
||||
Q=0
|
||||
R=0
|
||||
S=0
|
||||
T=0
|
||||
U=0
|
||||
V=1
|
||||
W=0
|
||||
X=1
|
||||
Y=1
|
||||
Z=1
|
||||
ShowHints=1
|
||||
ShowWarnings=1
|
||||
UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
|
||||
NamespacePrefix=
|
||||
SymbolDeprecated=1
|
||||
SymbolLibrary=1
|
||||
SymbolPlatform=1
|
||||
UnitLibrary=1
|
||||
UnitPlatform=1
|
||||
UnitDeprecated=1
|
||||
HResultCompat=1
|
||||
HidingMember=1
|
||||
HiddenVirtual=1
|
||||
Garbage=1
|
||||
BoundsError=1
|
||||
ZeroNilCompat=1
|
||||
StringConstTruncated=1
|
||||
ForLoopVarVarPar=1
|
||||
TypedConstVarPar=1
|
||||
AsgToTypedConst=1
|
||||
CaseLabelRange=1
|
||||
ForVariable=1
|
||||
ConstructingAbstract=1
|
||||
ComparisonFalse=1
|
||||
ComparisonTrue=1
|
||||
ComparingSignedUnsigned=1
|
||||
CombiningSignedUnsigned=1
|
||||
UnsupportedConstruct=1
|
||||
FileOpen=1
|
||||
FileOpenUnitSrc=1
|
||||
BadGlobalSymbol=1
|
||||
DuplicateConstructorDestructor=1
|
||||
InvalidDirective=1
|
||||
PackageNoLink=1
|
||||
PackageThreadVar=1
|
||||
ImplicitImport=1
|
||||
HPPEMITIgnored=1
|
||||
NoRetVal=1
|
||||
UseBeforeDef=1
|
||||
ForLoopVarUndef=1
|
||||
UnitNameMismatch=1
|
||||
NoCFGFileFound=1
|
||||
MessageDirective=1
|
||||
ImplicitVariants=1
|
||||
UnicodeToLocale=1
|
||||
LocaleToUnicode=1
|
||||
ImagebaseMultiple=1
|
||||
SuspiciousTypecast=1
|
||||
PrivatePropAccessor=1
|
||||
UnsafeType=0
|
||||
UnsafeCode=0
|
||||
UnsafeCast=0
|
||||
[Linker]
|
||||
MapFile=0
|
||||
OutputObjs=0
|
||||
ConsoleApp=1
|
||||
DebugInfo=0
|
||||
RemoteSymbols=0
|
||||
MinStackSize=16384
|
||||
MaxStackSize=1048576
|
||||
ImageBase=4194304
|
||||
ExeDescription=
|
||||
[Directories]
|
||||
OutputDir=.
|
||||
UnitOutputDir=
|
||||
PackageDLLOutputDir=
|
||||
PackageDCPOutputDir=
|
||||
SearchPath=
|
||||
Packages=vcl;rtl;vclx;VclSmp;vclshlctrls
|
||||
Conditionals=
|
||||
DebugSourceDirs=
|
||||
UsePackages=0
|
||||
[Parameters]
|
||||
RunParams=
|
||||
HostApplication=
|
||||
Launcher=
|
||||
UseLauncher=0
|
||||
DebugCWD=
|
||||
[Version Info]
|
||||
IncludeVerInfo=0
|
||||
AutoIncBuild=0
|
||||
MajorVer=1
|
||||
MinorVer=0
|
||||
Release=0
|
||||
Build=0
|
||||
Debug=0
|
||||
PreRelease=0
|
||||
Special=0
|
||||
Private=0
|
||||
DLL=0
|
||||
Locale=1029
|
||||
CodePage=1250
|
||||
[Version Info Keys]
|
||||
CompanyName=
|
||||
FileDescription=
|
||||
FileVersion=1.0.0.0
|
||||
InternalName=
|
||||
LegalCopyright=
|
||||
LegalTrademarks=
|
||||
OriginalFilename=
|
||||
ProductName=
|
||||
ProductVersion=1.0.0.0
|
||||
Comments=
|
||||
[HistoryLists\hlUnitAliases]
|
||||
Count=1
|
||||
Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
|
||||
[HistoryLists\hlOutputDirectorry]
|
||||
Count=1
|
||||
Item0=.
|
||||
16
libsrc/Swf2Exe/Swf2Exe.dpr
Normal file
16
libsrc/Swf2Exe/Swf2Exe.dpr
Normal file
@@ -0,0 +1,16 @@
|
||||
program Swf2Exe;
|
||||
|
||||
uses
|
||||
Forms,
|
||||
Windows,
|
||||
Dialogs,
|
||||
uMain in 'uMain.pas' {frmMain};
|
||||
|
||||
{$R *.res}
|
||||
|
||||
begin
|
||||
Application.Initialize;
|
||||
Application.Title := 'FFDec Flash Player';
|
||||
Application.CreateForm(TfrmMain, frmMain);
|
||||
Application.Run;
|
||||
end.
|
||||
BIN
libsrc/Swf2Exe/Swf2Exe.res
Normal file
BIN
libsrc/Swf2Exe/Swf2Exe.res
Normal file
Binary file not shown.
BIN
libsrc/Swf2Exe/flashplayer.ico
Normal file
BIN
libsrc/Swf2Exe/flashplayer.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
651
libsrc/Swf2Exe/uMain.dfm
Normal file
651
libsrc/Swf2Exe/uMain.dfm
Normal file
@@ -0,0 +1,651 @@
|
||||
object frmMain: TfrmMain
|
||||
Left = 323
|
||||
Top = 163
|
||||
Width = 1007
|
||||
Height = 661
|
||||
Caption = 'FFDec Flash Player'
|
||||
Color = clWhite
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -11
|
||||
Font.Name = 'MS Sans Serif'
|
||||
Font.Style = []
|
||||
Icon.Data = {
|
||||
0000010004000000000001000800EC310000460000003030000001000800A80E
|
||||
0000323200002020000001000800A8080000DA40000010100000010008006805
|
||||
00008249000089504E470D0A1A0A0000000D4948445200000100000001000806
|
||||
0000005C72A866000031B34944415478DAED9D0B7C14D5F5C70F8F3C8090F008
|
||||
041523521031451E159AF8A041FEB4F28F88429428A08912B51A54A80F94FEED
|
||||
940AA258F081CADFA841010D1A10458A1695482B49E15F40298280881435BC02
|
||||
84040328F33FBF95B50177E6DED99DDD99D9BDDFCF673EBBB0B39BBBB373CE3D
|
||||
E7DC73CE6D448AA8E4FD8913F5FA8307E9686DADEF38C2CF8F1C3A4447F9F03D
|
||||
E2FFF911C4B76C49F149499480473EF0989092E2FB3F1C89FC7CE0E4C98D9CFE
|
||||
4E0AFB513FAA078170EFFDEC33DAC7C7DE2D5BE8787DBD23E3689C9848A95DBB
|
||||
52DB6EDD28950FA524BC87FAC15CCC5B85853F0A7ADDAE5D4E0FC7122DD2D27E
|
||||
540C571417ABFBCCA5A81FC645BC326488BE7DF9729F791E8DC09DE83460005D
|
||||
B778B1BAEF5C82FA211CA474D8307D7B7939D557573B3D1447486CD3863A6567
|
||||
53DEC285EA3E740875E123C8EB7979BE19DE6BE67CA480DB000BE1EAD252755F
|
||||
460875A1C3CCCB8306E9DB962D737A189EA4F3A04174FDB265EA1E0D23EAE286
|
||||
8137F2F3F58D656551EBCB471AC40EBAE7E6D255B367ABFBD566D405B5092CCD
|
||||
7D3C670ED5ECD8E1D8185A356942CD1B35A284C68D299E1F7124F21177E27933
|
||||
FEFF383E2F911F134E3C07C7F83872FC38D5F381E7DFF2E3515DA7637CD4F371
|
||||
F4C481730EF3E381EFBF77EC3B26A7A753CFD1A3D592A34DA88B1822C59999FA
|
||||
57959511FB7BCD5890539B36F51D6D59E053F9687BE27924D9C74A60DF77DFD1
|
||||
5E3CF2B117CFF9F8961544A4382333930A2B2BD53D1C02EAE20501D6E7D7CD9E
|
||||
4DC78F1D0BDBDFC0ACDD312E8E4E83B043D04F083D667437038BC1AF0CA01CBE
|
||||
E1C79D7C9D8E85513134E6EBD42B3F5FE51B0481BA601658306A94BE61FEFCB0
|
||||
083E04BE030BF8D9F1F1D4858F347E1EE77261B7C2177CCDBE3C7A94BEE0A38A
|
||||
95423814021441C68811347CEEDCE8B97061465D2809E6E7E6FA827A767326DF
|
||||
B0387E9690401DA34CE0CD80F0EF6425F0F99123B49D15C2D7FCDC6E10341C51
|
||||
56161B173404D40532615E4E8EBE65C912DB3E0FFEFBCF1313A90B0B7C2716FC
|
||||
581178115008DBD942D8CA0AE15FF5F5B6C611BAE6E4D0C8254BD48536405D98
|
||||
00CC1E30C097B0630710F27359E07B356B4667C7C585FE813100DC8575DF7E4B
|
||||
9B5821D8E52A20C1287FF97275BF9F82BA200D783E2B4BDF595161CB67C197EF
|
||||
C1829FC133BE9AE98303C2BF812D82F5AC08103BB0838E595934A6A242FD2027
|
||||
501782595450A0AF2B2909F973DAB31FDF8305BE271F498D1B3BFDB5A28ADAE3
|
||||
C7E96328033E76DB1033E8555040579694C4FCFD1FF317606A9B367A28C53898
|
||||
DD7BB1C0F766131F517C45F8C12AC25A7611D6B13208C5454031D284EAEA9896
|
||||
8198FDF2CFF5EBA77FBD6A55D0EF87E0F765A1CF6CDE5CCDF60E01ABA0F2F061
|
||||
5ACDCA201445707ABF7E74F3AA5531290B31F7A5971415E9AB67CE0CFAFD88E4
|
||||
F765A187E0BB3D29275640F2914F11F011CA0A42DFA222CA993933A67ED498FA
|
||||
B2D3D2D2F4604B7121F817B568E19BF55550CF9DC00A8035F0515D5DD08AA045
|
||||
870E744F5555CCFCC031F1454BB2B3F52FCBCB837A2F0A6CFAF36CAFA2F9DE01
|
||||
8A00F1810AB608822D5C3A2B3B9B0ACACBA3FE078FFA2F382931510FA669A65F
|
||||
F0B17EAFF02EC8275811A42240D3D307EBEBA35A46A2F6CB059BBE8B593E8B05
|
||||
FF223ED48C1F1DC022F88895002C82608285D19C561C955FEA892E5DF4FD5BB7
|
||||
5A7E1F9277FEBB65CB8897D62A2203CA96FF72E850504945ADBB74A13BB76E8D
|
||||
3A7989BA2F34292E4EB75AAD87001F041F7EBE22FA4176211481D54021AA0D1F
|
||||
3C762CAA64266ABE0C3AEC6E5AB8D0F2FB10D51F80DD6F94B91F53C01578AFB6
|
||||
D6B76A609573870D8B9A4EC651F1251EEFDC593FB06D9BA5F7A00C7730CFFA2A
|
||||
7B2FB64156E1DB3535964B925B75EE4C776DDBE679F9F1FC17B06AF223B03798
|
||||
677C15DD573404AB054BD922B012248C0697C0B3830F26CA7F3ACFF6D7A4A450
|
||||
B20AF2290250F3FDF7F4DAC18396AD012FAF127872D0C1D4EBC3D787C9AF5088
|
||||
587AE890E5D88057FB0D786EC0B37AF7D6ABD6AE953E1F11FEA1C9C9744E4282
|
||||
D343577888CD478ED09B353596560A3AF4EE4DB7AE5DEB2999F2D460ADAEEF2B
|
||||
935F110AC1B8045ECB17F0CC40A775E8A0D75555499F7F61F3E6F45F49494E0F
|
||||
5B110560B970E5E1C3D2E77BA9A0C813839C9294A4CB6EB3A54C7E4538B0EA12
|
||||
603BB3076A6B5D2F5FAE1FA095621EB4E41AD5AA956AD0A138097F1BF24DFCB8
|
||||
95CDFAADFCFCE77CAF145A5C0A864BF00ABB04B22DC9BC504CE4EAC15959E347
|
||||
1EFFD5ECEFAB8CBED8E4C0F1E3B48D8FCF5948716CE763CB89E7DFF071EA5D74
|
||||
330BFFAC205685A04C4A5909C8D613B83D57C0B503D388A4C3AFDDD9DC87F02B
|
||||
6283AF58D03F64015C81F6E13C1B6346AFB698D7FF5B56004F07B92C0C25B088
|
||||
DD818DEC16C8A2B954D65C3928CD82F0ABF5FDE807FB047CC8B378F909A1DF6E
|
||||
C3EEC4C15A000DB19A2FA0B950DE5C37202B667F768B16D49F0F4574B19167F4
|
||||
0F21F438B09720CFF876138A05D09015757554CE870C6E74075C35182B01BF2B
|
||||
F8C753F9FCD10384FE25FEED4BD9ACDE61C30C2FC20E0BC00FEA08DE626B4006
|
||||
B705065D3310D9A53E14F3E4B2BFDF353EDEE9212B42640FCFEC10F812F4F80F
|
||||
C306A166D86501F8C132E1829A1AA96222372D11BA6210B2493E58E3BFB6552B
|
||||
EAA8F6D8F32C68E1BD98CDFAB93CDBBF83BDFF1C1A879D16809F9DECB2BC7AE0
|
||||
8054AE805B92851C1F806C7A2F847F74EBD6AA7EDFA354B070C0C47F958F4336
|
||||
EEFEDB90389E183A75EAE43BBA76ED4AEBD6ADA3952B57063CD76E0BC00FFA0B
|
||||
CCD9BF5F4A09B8216DD8D13F2E5BD803B37FB49AF93DC7376CE2CF62F37E0E0B
|
||||
BD1D91FB86B464E1CDCCCCA45FFDEA57949595455D5898CE3CF34C6AD4200F64
|
||||
C28409F4C8238F047C7F382C003FB004E6B02520E30E385D40E4D81FB652D29B
|
||||
C73EBF4AEDF50E58A79F525747B359F043D9A9A721EDDAB5F3097A7676365D7C
|
||||
F1C5D4B3674F8A17C481CC1440B82C003F880920614806274B891DF9A3569A79
|
||||
A868BF77B053F021F003070EA44B2EB9C427F4DDBB773F697697C1290BC08F95
|
||||
D501A79A8A38A20034C9441FB5CEEF0DFC82FF3C36E90CE173E0C30F1932846E
|
||||
B8E106BAECB2CB8433BC08272D003F56F2043407E431E27F5036D14765F8B91F
|
||||
44F435BEB96760C38D103EA75FBF7E3EA1CFCBCBA3366DDAD8363EA72D003FB2
|
||||
19834EE40844F48FC976EF55B9FDEE6711FBB877D5D6069DB4939E9E4E23478E
|
||||
A4FCFC7C3AE79C73C232463758007E5E3F7850AA7620D2DD8623F68764FBF6A3
|
||||
AA0F413FB52D973B415E7E11CFFA4B83D85D0791FB2BAFBCD227F403060CB0EC
|
||||
D35BC52D16801FAC0CC854114672DF8188499926E1F7A39EFFA6D6AD95F0BB10
|
||||
98FBD3D9D49FCC87D5001F027877DF7DB7CFC46FDEBC79C4C6EC260B00E01ACE
|
||||
DEBF5FAA9F801621D98CC81F91F1FB91E8730BFB7FAA7F9FFB409EFE556CC26E
|
||||
B668EE43F0274E9C48D75D775DD867FB40B8CD0200682AF2BFD5D542251AA9C2
|
||||
A1B0FF01D94C3FA4F8AAFC7EF7F14A7D3D155ADC47CF69C1F7E3360BC0CF1676
|
||||
0390322C2212998261FD70D9F57ED5C0D37D208B6D6C6D2D3D67A1DEFDB4D34E
|
||||
A369D3A6392EF87EDC6801F8916D341AEEFC80B0FE4A9A84DF8F3DFA0AD8EF57
|
||||
B80704FA86F3AC2F5BA187F5FB5B6FBD951E7AE8214A4E4E767AF83FE2560BC0
|
||||
CFF3EC0AC8B41CD7C228A761FB6099DA7EE5F7BB0F2CEFDD5053235DB08335FC
|
||||
679F7D96FAF4E9E3F4D07F829B2D00201D0F08637E40583EB4243B5BFFB2BC5C
|
||||
789ECAF17717C8E6FBBD64D65A6BB6DA205C63C68C7185B91F08B75B0040B666
|
||||
E0ACEC6C2A282FB7FD4287E597D3244C7FE5F7BB8B89EC933E2CB9F945FFFEFD
|
||||
A9B4B4D4E7F3BB19B75B007E64E3015A18E4D5F60F9C9696A6D7EDDA657A0EB6
|
||||
EC1A6363CAA722347EC737E00C49E1BFEFBEFBE8E1871F76EDACDF102F58007E
|
||||
64E2012DD2D2E89E5DBB6CBDF0B67ED892A2227DF5CC99A6E720C9E776E5F7BB
|
||||
863B0F1DA2A72422FD30F9E7CD9B4783070F767AC8D278C5020088073CCD4A40
|
||||
D443A06F5111E5CC9C699BDCDAAA003409D35F95F7BA87DB59F89F95107E04FA
|
||||
5E7FFD755FFEBE97F092050064CB87351BE5D6B60F7AAE5F3FFDEB55AB4CCF51
|
||||
A6BF7BB8956F349935FEC2C2429AC9565DA8A5B94EE0250BC04FC9FEFDF46F41
|
||||
D6ECE9AC906F5EB5CA16D9B54D016812B3FFCD2CFCAAA79FF3C8CEFCE3C68DA3
|
||||
E9D3A73B3DDCA0F19A0500D053F0397605446836C9AE2D1F32B54D1BBD5E3068
|
||||
55DFEF0ED09F0FEBFC22EEBFFF7E9A32658AD3C30D092F5A0040A67F40224FA6
|
||||
13AAAB4396DF903F60514181BEAEA4C4F41C24FCDC959AAAAAFC1C660DCF2E97
|
||||
4874AC45461F72F9BD8E172D008040E0E37BF70A7FA75E050574654949484215
|
||||
B2446A12A6FFF0E464CA484CB4FB3A292C80DD73FBB0F08BBAF3C2E487E91F0D
|
||||
78D502009B8E1CA1D7241284B4106538A4373F9F95A5EFACA8303D070D3ED0D2
|
||||
5BE12C39070E089B783CF1C41374C71D77383D54DBF0AA05E047A68148C7AC2C
|
||||
1A535111B41C87A40034C1EC0F931F81BFB66ACDDF51FE5057477F12A4F8DE76
|
||||
DB6DF4F4D34F3B3D545BF1B20500F6B3B5364B2237400B418E837EA34C5F7F74
|
||||
F4CD565D7D1DE56D3625AF109892175E78212DE7DFD28B4B7D6678DD0200E828
|
||||
BC42A0BC43D957206805A00966FF563CEBFF96677F15F8730EF8FDDD7806D963
|
||||
B2BD36F2F9FFF9CF7FBA3EAF3F18BC6E0100CCFECFF26F784010BBD18294E5A0
|
||||
DE342F2747DFB26489E9392AE3CF794439FEA8E3FFF0C30F7D3BEE4423D16001
|
||||
00990CC1AE39393472C912CBF21C9402D02466FF3BDAB68DE435529C02FAF85D
|
||||
2058F283CF0FDF3F1A387AF428FDFDEF7FA7F2F272DAB06103AD5FBF9EB66CD9
|
||||
6278BE572C003F4FEEDB17162BC0F21B64DA7C21E1A7AF9AFD1D4514F52F2828
|
||||
A0175F7CD1E96186C461B66EDE7BEF3D5AB46891EFD8CF0A4F162F5900008941
|
||||
4B05564030EDC32C2B004D30FB23E9E79E76ED9CB8468A132C63C1FF8D49D349
|
||||
F8FB5BB76E8D688B6EBBD0D9A259BC7831BDF4D24BB46CD9323A24B9F7DEA978
|
||||
CD0200D3F6EC112607691665DAD2C90B468DD2D7CF9D6B7A0E9A7C5CE8C11B2B
|
||||
9AF87975357D6A525B3E977F43ECCAE32520F8A848449622CCFB50F19A0500D0
|
||||
3404CD43CCE8316A140D9F3B575AAE2D2900517F7F95F2EB3CA8EDBFD36456C4
|
||||
921F7C652F34F40010FC3973E6D0D4A95369E3C68DB67DAE172D00991461ABFB
|
||||
09489FF85661A1BEA6B8D8F41CB5EEEF2C58F6EBB26F1F551BDC20717C7CB46A
|
||||
15F5EDDBD7E9A14AF1C1071FF8BA0D9B05F382C58B160090C90BE85358485714
|
||||
174BC9B6B40210CDFE98F5C7F1EC9FE89199251A1165FC7925F0575353E3AB46
|
||||
7CE6996742FE2C28BDB39B34A1F39B36A55E7C9CC74737FE77778F96A5637BB1
|
||||
196C051CB3C90A9096564D10FC534D3E9DA713CFFE46BBF562634E04FEDAB76F
|
||||
EFF4304DF9EB5FFF4AB7DC720B6DDFBE3DA8F7A7B3700F8D8FA70B58083220F0
|
||||
FCEF689B94649A886A92B22D75527166A6FE5565A5E1EB98FDC7B66D4B498D1B
|
||||
3B7D6D62162CF9E59844FE911073EFBDF73A3D4C43E0EB1715150535EB63561F
|
||||
9E904043F9E8E3D199DD0A3256C019999954585929946F2905A009667FD5ECC3
|
||||
79AE397890CA0CF69FC7ECBF73E74E57EDDAD31098FCB9B9B9BE653D5960DA8F
|
||||
4A4CA4BBD9F2F4AA391F0A324D433409F9169EF0FEC489FADF264F363D47B5FA
|
||||
7216E4FA77C48C60F0BA9B7DFF6DDBB6D1E5975F2E1DE187E08FE109E76E16FE
|
||||
B3E3E29C1EBE63C8B40EBB64E2441A3879B2A98C0B15C0F4F474BD66C70EC3D7
|
||||
DBB3E0DFAA1A7D3ACA34F607EF33591F5EB972A52BF3FD57AF5E4D393939B467
|
||||
CF1EA9F30B58E8272525D119CAD5F48152E1DD26F91EC9E9E9347EC78ED01480
|
||||
2630FF07F20F72914AFC719473F7EDA3CD06C1BF1E3D7AD0279F7CE2F4107F02
|
||||
847FE0C08152997C1D58E05F60F7657094952B878A4C6290269071D317DFC8CF
|
||||
D73F9E3DDBF40F8C4F4D55C13F07A938768C2E32C9817763971F28A4ECEC6CA9
|
||||
DC7DCCFA7FE649A695BAC77E422DBB7ED3D9F533A3677E3E5D357BB6A19C9B2A
|
||||
80294949FA51130DA3DA7D39CF4D35355462B00B7333F69511FC6BE322170D3E
|
||||
FFC5175F4CDF7CF38DE979C82A9DCDB3FED56AF35853446DC3E259793E505B1B
|
||||
9C02D004E6BFAAF9779E54F69F8D32FFF2F2F2E8D5575F757A883F02A1472AB2
|
||||
688DBF1DCFF66FA7A450DF180EF2C922D32B40339173C3175E1E3448DF66B22C
|
||||
83B5FFBB55DEBFA3A0E63FC32412FCFEFBEFD3A5975EEAF4307D609D1F3EFF72
|
||||
411BB99F376D4A4BD9AA54813E39900BF0982027A0F3A04174FDB2650105D550
|
||||
7A35C1ECDF837DB3AB5CBAAE1C2B14B3F6BFC540FBB76BD78E76EFDEEDF4107F
|
||||
64C68C19347EFC78D37390D0F321CFFCAA89AC35DE603770BD811BE8473390F5
|
||||
A015C0B5ACA5BBAAA8ACA398F9FF575C7105BDF9E69B4E0FD107827E175C7001
|
||||
1D33A925410A6F45EBD6749A9AF92DF3055FD7398280AA664501BC9E97A76F28
|
||||
2D35FC30D5F4C31D982DFFB925F517ADBA20FC6635FCF0F92B79E68FE5C49E50
|
||||
11350BC9C8CBA3AB4B4B7F22EF0115C0B4B434BD6ED72EC30F53A9BFCE83D2DF
|
||||
36264B4068F6D9BF7F7FA787E933FB61FE1B81C6A4157C2FC5420E7F38111508
|
||||
B5E8D081EEA9AA9253009AC0FC1FCDA69AD2D6CE6256FC03A13AC0AF39DDF20B
|
||||
F5FC08FC998135FE712A912C64B6F0FDF0AA493118D002C87B500AE07E36FF55
|
||||
F4DF59CC6AFFFBF4E9E3EBF5EF24D5D5D5D4BB776FDA6192463E283E9EDE5579
|
||||
24B620B31AA0C92880D261C3F44D0B171A7EC8993CBB14B005A0709681ACED97
|
||||
1B24808C1D3B969E7CF24947C777EDB5D752A9491C097EFFBA366D54D0CF464A
|
||||
F6EFA77F9B045ACF1D368CF2162E3C49E67FA200A6B669A3D79BAC2DABC61FEE
|
||||
A08549D0C7E9A69F6BD6ACA15FFCE217A6E7CC4F4951597E36236A1796C80A77
|
||||
4275B5B902D094FFEF7A4409405F7EF925A5A7A73B36BEA14387D25B6FBD65F8
|
||||
3AF2FB5F503924B613CC72A02505A0B2FFDCC12BF5F534AAA626E06BE8F9FFF5
|
||||
D75F3B3636ACF9F7ECD9D3F0F54E4D9AD0273C89A80232FB09260E70D23F5E19
|
||||
3244DFBC78B1E19B95FFEF0E26D4D6D2A3064B3EC3D8CF5BB0608163631B3E7C
|
||||
382D3489217DC8F7CF25CA820C1BA238C0394386D0758B17FF28F727290051F5
|
||||
9F6AFBED0ECC0280D83863E2C4898E8CEBD34F3FA58C8C0CC3D755D43FFC88E2
|
||||
00A756079EA4003481FF7F236BEF8E4A7B3B8E5905E05FFEF2171A3C78B023E3
|
||||
1245FED5EC1F7EACC601A41580F2FFDD017EE09F99FCC0F0FF1107883498FD7B
|
||||
F5EA6598EF0FC1FF50B98F11E1619E2064E3003F3E11EDFCA39A7FB88345478E
|
||||
D0B0830703BEE66405E0F5D75FEFDBC2CB88F7F9DE19A08AC72282A84948C39D
|
||||
837E54002FF6EFAFEF58B1C2F04D6AFDDF1D986500C2F4870B1069D0D63B95AD
|
||||
43A3D93F8B67FF8FD4EC1F31447180F4FEFDE9C6152B4E5600D33A74D0EBAAAA
|
||||
0CDFA4BAFFB803E4FF2F35D0EED84E6BCA9429111F135A8EDF74D34D86AF2FE1
|
||||
D95F35F48C1CA22E412DD2D2E89E5DBB4E56009A0A007A82D3F7EEA5AAE3C703
|
||||
BE367FFE7CBAE69A6B223E26741D32EAF483FDF8D6B8A827612C20B367807642
|
||||
F6A515C0BDEC5F46DB1E6B5E031B80A49994007FFEF9E7D4B973E7888E09C53E
|
||||
679D7596E1EB4FB0E53856598E11055B873D2AD86B41B3A20054031077605602
|
||||
8CEDBF0E1E3C488D22ACA41F7DF451BAEFBEFB02BE067B717B6AAA2AF8710051
|
||||
8310ADA102106DFFA53200DDC1D4C38791C411F03534FF4013904873FEF9E71B
|
||||
76FB51893FCE21CA08F46F1BE65300F37373F58D65658627F766136E88EA00E4
|
||||
38B93CC32F34D80074DCB871347DFAF4888E4794F9F7627232E5272646744C8A
|
||||
1F587CE810AD35D93CB47B6E2E8D282BFB41013CD3A387BEDBA4671B96FF2E54
|
||||
5D5B1CA7F3BE7DB4DDA007E04B2FBDE45B8B8F24D8CAFBF6DB6F0FF81ADCC65D
|
||||
6ACB78C7106D1BD6BE470FBA6DFDFA1F14C0A4C444FDB8495B61D501D879443D
|
||||
003FFEF8639F391E49468C1841AFBDF65AC0D786252450594A4A44C7A3F80FA2
|
||||
16618DD9327BB0BEFE0705A00956006E674DAE7AB53BCBDFD89FFB95410A30B6
|
||||
00430FC0F8082BE9D34F3FDD708BAF67D865BCD562F41FD1EB437CF8B31C603B
|
||||
A0552882895881C21DA852D1E5D8C796E2D36C319AA111C9298007DBB777FAFB
|
||||
C43C33D8A4FB9D8149E7440FC0CD9B3753B76EDD0C5F47F61F76F769CEB7D861
|
||||
16EA3A3E0EF081C834FE5DC3079C995A7EFC8E8F63F27F9AFCD9284DF9B3FD2A
|
||||
269E9FE380D2883FF1EFF1ECB6C6720C6292202D5C935100AD78E6BF832D0085
|
||||
B3E4D7D4D0CB066E5A6161213DF7DC73111D4F717131DD7CF3CD4E5F1653A624
|
||||
25D184188E5D3DC916C001839811D06414C0E94D9BD21895C9E5384800DA6390
|
||||
01F8F4D34FD36DB7DD16D1F1888A7FDC40AC2B80E7ABABE9EBEFBE337C5D9351
|
||||
00AA0AD0792AD8FFBFC8A40418E63FDC804872F6D9670B77F9759A585700A2AA
|
||||
400D0A409404D42D218146A868AEA34C64DFFF618316604EF40044E00F0140B7
|
||||
13EB0A60FEC183F49941DE08403250A3254545FAEA99330D4F524940CE733E9B
|
||||
72FF3230E59CF0FFE7CD9B47A3468D72FAB20889750520DA35B86F5111357A23
|
||||
3F5FFF78F66CE393D43E808E22EA00841D80B113702441F20F9280DC4EAC2B80
|
||||
A5870ED16A936CC09EF9F9D4489406AC1A813ACB53FC03DE6950DB8D02A0AAAA
|
||||
AA88EF01880620C83BA8E7D9A596DD131C757575F42D8F15C7617657F088D771
|
||||
24262652120B63C303FF87FC85047631F11CDFA5499326BED7F0FF286AC2CEC2
|
||||
DFB1E5E33F8EB0398BA623FE7FE3B3274C98404B972E0D38CE585700A20D4391
|
||||
0EDCE8E54183F46DCB96199E04E1EFAF148063987500C6CC0F0B2096316B441A
|
||||
EB0AE02316FEF74DD2813B0F1A448D9ECFCAD2775654189E04F3BFAFAAE77684
|
||||
0327EAFF8D92645E78E105BAF1C61B9D1EA6A398A523C7BA0280F9BFD4A433D0
|
||||
199999D4E8E98C0C7DCF860D8627A95660CE61B6031070AA03B09B501680311B
|
||||
F8FE596072FFB4CBC8A046D3D3D3F51A932D9CAF4949A173D5268E8E702DFF78
|
||||
F30DA2B8FDFAF5A37FFCE31F4E0FD17194023066D39123F49A410769909C9E4E
|
||||
8D44BB01ABCD409D017DDD53D9FC3F64D0D5C5C91D80DC845200C6883609C16E
|
||||
C18D26C5C5E9C74D3A87DCCC277568DAD4E9EF127320F037D0A49CD389F25F37
|
||||
A21480313B59AE5F3451008D7962172A00D50DD819B0F4F794C11A6EA74E9DE8
|
||||
8B2FBE707A88AE4029006344DD817D0A40B900EEC4ACFBCFD8B163E9C9279F74
|
||||
7A88AE40AD021823E502A820A0FB40DAEFF9264AF9DD77DFA55FFFFAD74E0FD3
|
||||
15280BC018A920A068197078723265C47053052740E38F1906195CC898DBBB77
|
||||
6FC4BBFFB815A5008C11ED10E45B062CCECCD4BFAAAC343C4925024516B4C54A
|
||||
3389FE63E71FEC00A4F801A5008C914A0412A5020FE48B78510C5FC44853CC3F
|
||||
DA2D263F1A36FFC426A08A1F50310063A4528145C5406A57E0C8D2877DFF7506
|
||||
A5BF88FE6FDBB62DE2BBFFB81965011823550CA4CA81DD83A8F3CF238F3C42F7
|
||||
DE7BAFD3C374154A011823550EAC1A82B887913535F4AA41EA6F5C5C9CAFF4B7
|
||||
8DEACF78124A011823D51044B50473071BD9ECEFC5E6BF514AD6E8D1A3E9E597
|
||||
5F767A98AE43C5008C916A0986279A6A0AEA3866B33F58B97225656565393D4C
|
||||
D7A12C0063A49A829E78A2DA823B8868F67762E30FAFA0148031B6B405571B83
|
||||
841FD1EC8F757FACFF2B7E8A5200C6D8B23108505B83850FCCFE192669BF3D7A
|
||||
F4F055FEA9A5BFC0280560CCC37BF6F8CACA8DD0641580DA1C347CE4B09FB6D4
|
||||
C44F5BB060010D1B36CCE961BA16A5000263697350D1F6E0792929748E2A08B2
|
||||
9D45478ED03093620DE5FB8B510A20309BF9DE2A35B9B74EDA1EFC991E3DF4DD
|
||||
EBD71B9E8C4CC00B63F442860BE4FC9FCBA6FF0E131FCD899EFF5E432980C020
|
||||
03F03D9334E0F6EC5ADEB67EFD0F0A40940EAC9281EC6702FF388F9AA469AA9E
|
||||
7F7228051098C5870ED15A932C40A4018F282BFB4101889281CE8C8BA382D6AD
|
||||
9DFE4E518368D90F38B1E1A717510A203025FBF7D3BF4D3A7D210968E0E4C9FF
|
||||
092D6B2681C0667CDA3DEDDA39FD9DA20244652F3970805699FC38D8EA1B5B7E
|
||||
2BC4A84CC0C04CDBB387BE15AC00E0514A01807B590124AAA5A890316BF601D0
|
||||
E77FD3A64D949C9CECF4503D81B2007E0AE24B8FB2023043B3AA005477E0D079
|
||||
FBC811BAC224320BE6CE9D4B23478E74749C2B56ACF0EDBBF7FDF7DFFBF6EB6B
|
||||
F8084EFDBF501EC1A99FDFF06F3424D0FB27B3EB8AF10622561580A81B30D04E
|
||||
5500D3D2D2F4BA5DBB0CDFA076080A8DAF8E1FA79EFBF651B589593660C000FA
|
||||
E0830F1C1D2736FE4C4D4DF56DC2E975625501885A81B5484BA37B76ED3A5901
|
||||
BCD8BFBFBEC3409302B54B70F0608FBF4BD9EF5F6792978D5E7FEBD6ADA3CE9D
|
||||
3B3B3A56F8D3F0ABA381585500E57575B4820F23D2FBF7A71B57AC385901BC55
|
||||
58A8AF292E367C93AA0A0C8E5A16FEFE02E1076EC9F7C766A32525254E0FC316
|
||||
62550188AA00FB1416D215C5C5272B00A099C401E21A35A2FBD54A802520FCFF
|
||||
C53EFF2A81395DC83FC873CF3DE7F4707DB46FDF9EF60802485E211615005699
|
||||
1EC38ED2122B00405A0100B54B903C88C4FE8635F1DF04C28F629FCACA4A6AEE
|
||||
821B75F5EAD5BE04A468211615809500203849018876095271003920FC393CF3
|
||||
2F3731C300FC7E08FF79E79DE7F4907D4C9A3489FEF0873F383D0CDB88450520
|
||||
F2FFB11BD084EAEAC00AE0952143F4CD8B171BBE5965048A81E975250BFF5281
|
||||
F0376BD68CDE79E71DEADFBFBFD343FE915FFEF297B46AD5AA80AFB5611730B5
|
||||
7163A7876889DFB1F017C6D8CA952803F09C2143E8BAC58B032B00A009E20077
|
||||
A7A6FA1E153F05C29F5B53438B4DFAB00108FFDB6FBF4D975E7AA9D343FE91DD
|
||||
BB7753C78E1D0D97FFE6A7A4D0D5AA22D4D558F5FF81250500D466A181C152DF
|
||||
0D870E4909FFA2458B5CB7B71F1A8EDE70C30D015FC3AFBD8B157F2B8F5900B1
|
||||
86683350A08914808A035807FDFCAFE599DFACB417A0B5775959992B4B7CCD52
|
||||
6A07C4C7D3FB6A09D8F588360239D5FF073F5100A5C386E99B162E34FC101507
|
||||
3899297575F4473E447973107E08981BBBFB1CE69B06E6FF7E83D9E391A424BA
|
||||
27C682695E44E4FF9FCBF75EDEC285E60A0068023700F900B11E07406AEFF53C
|
||||
EB8B22FD00C28F1C7F3724FA04E2C9279FA43BEFBCD3F0F50D3C7374577520AE
|
||||
067EFFC39205400D094A015CCBE660D718DE9E1A453D37B1BFBF87958008083F
|
||||
32EB9C2EF031E2282BB06EDDBAD1F6EDDB03BEDEA94913DAA6BA42BB9E60FC7F
|
||||
1050014CEBD041AFABAA32FCA058DD3014EBFBF7B19FF59449A7958640F867CD
|
||||
9AE54BAF752B66C13FF03F2D5AD01F55CCC7F588F6016C5800D490800AE0F5BC
|
||||
3C7D83414008C46283106CDBFD07F6F5AB24667D809D7C5F79E51557EFE6A3B3
|
||||
42CBC8C8A08D1B37067C1DBFF30E36FF554768F723DA0320232F8FAE2E2D9553
|
||||
004053CB813ED0B917FDFB360B22FC0D81AF5F5C5CECFAA61E6FBDF5160D1D3A
|
||||
D4F0F5716CE9FD39062D3DAF11ACF90F0C15C0A4B838FDB84944B14762225DE5
|
||||
F21B3C1490C30FC1AFB050178F35FE993367BADAE46F8859E61F54FBB6D4543A
|
||||
43ADFDBB1ED12EC040B3AA005E1E3448DFB66C99E107466B56E0BFBEFBCEE7E7
|
||||
8B52794F05453D58E6734B5EBF08341E193870A0E1EB05ACE05F8862051F2DC8
|
||||
64FF751E3488AE5FB6CC9A02009AC00D88A62E4130A3FEC87E3EF6E8B3DA0B67
|
||||
ECD8B1F4D8638F51BC47564610F9EFD5AB97A1EF0FD4D29F371075FF019A899C
|
||||
9B2A80294949FA5193CD05A2A14908D6F11FE78B284AE10D44EBD6AD69F6ECD9
|
||||
AECCEC33E381071EA0871F7ED8F0F5DC84047A2D25C5E9612A241035FF884F4A
|
||||
A2076A6B8353006FE4E7EB1FF30D6EC6787603923CE62762396F0ECFF458CEFB
|
||||
97A0534F20B0BC57545444BFFFFDEFA98DC7B64E5FB3660D6566669AF6FCFB3F
|
||||
FE4E7DD4ECEF7AD070663A9BFF66F42A28A02B4B4A8253004013B8015EDA360C
|
||||
D97B4F1D3E4C252CFC32493CA702C1CFCBCB234DD31CEFDD170C30FD2FB8E002
|
||||
5A6FB20DDC109EFDDF54B3BF27106DFF0534818C0B15C0F4F474BD66C70EC3D7
|
||||
DBF34C71ABCB674144F2D18BFF4D36F383ED753B78F0609A3A752A9D7FFEF94E
|
||||
7F9DA079F0C107E94F7FFA93E1EB2D1B35A24D6DDBD2691EB3E8629559D5D5B4
|
||||
DBC4824D4E4FA7F13B7684A60044DB8601B7EE198035FC497575C2869C66A045
|
||||
16FC6537D5EE07838CE9FF627232E527263A3D548504557C4F3F6752B50BFCDB
|
||||
7F999D23B586A709DC80BECD9AD160176E1E3AF4E0C1A0827BA06BD7AEBE19DF
|
||||
8DD57B5641B51F84DFCCF41F141F4FEF7A3CA01B4B88527F812621DF520AA038
|
||||
3353FFAAB2D2F075E4028C4B4D75DDD661B9AC00165A540068D185CAB8ABAEBA
|
||||
8A1AB9ECFB0403D27D73727268E9D2A586E7C0F4FF944D7F95F4E30D10C49E21
|
||||
58FB3F83157E6165A53D0A0068022BC08D0542B2160032F810DCBBEBAEBB3CED
|
||||
E307E28E3BEEA0A79E7ACAF49C67D87ABB354AF239620151E30FA049CAB6B402
|
||||
989498A81F37493774A315205200D888F3F6DB6FF7F5E5473FFC6863C68C1934
|
||||
7EFC78D37354B71F6F2133FB378E8BA3078F1DB3570188760E026815D6DF45A5
|
||||
A3660A005B704340BC92BD671551A10F80E9BF8E853F168ABAA205B4FC2E3769
|
||||
FB0D1AEEFC23C2D2742D2A1042F9E85D2EAA0F3053004F3CF184CF3C8E4610F1
|
||||
CFCECEA6432629A210F97758F80744A9028C4630EB3FCEB3FFB736CDFEC092A4
|
||||
2E18354A5F3F77AEE9396E4A0C325300D3A74FA771E3C6393D44DBD9BC79B34F
|
||||
F8BFF9E61BD3F3D4929FF79049FCE9316A140D9F3B373C0A00C858016E691662
|
||||
B60A108D0A0033FF65975D26DCDB4F75F9F126D3F877359BFD816651A62D2B80
|
||||
F9B9B9FAC6B232D373DC5225184B2EC08A152BE8F2CB2F3735FBC1F53CEBCF56
|
||||
65BE9E036BFE4B05BF6DF7DC5C1A5156165E050034C19260AB264DE80E173492
|
||||
8C150580801F9631BF1524865CC2FEE17BECF7BB2546A39047D4F20B6841C873
|
||||
5077C2BC9C1C7DCB9225A6E7B8C10A888518C0BC79F3A8A0A0C034C5179CC34A
|
||||
B9B2756BB5BB8F0791A9F93F75CF3F59829E0A34092BE0B76DDA383ADB44BB02
|
||||
78F4D147E9BEFBEE139E87D6DEEFB3D9AF96FBBC0722FFCF56578765F607414B
|
||||
E7EC0103F4EDCB979B9EE3F43662D1EA02D4D4D4F866FD85263B38F939AF6953
|
||||
5F8EBF4AF3F526A2EDBE41A70103287FF9F2C82A00A009AC00CCFEBF6DDBD631
|
||||
B3D36C15C0AB0AE0934F3EA1DCDC5CDAB2658BF0DC7E3CE3BF9392A2CC7E8FB2
|
||||
8F677D54FC1DB339F2DF909014C0F35959FACE8A0AD3739C6C1B166D2EC08B2F
|
||||
BEE8EB44240AF60124F8BCC966BFD7BA3529FE83A8DD17E8989545632A2A9C51
|
||||
00401358016038DF88190E249D448B0B80725E083EB61893015D7DCAF89AAB68
|
||||
BF77D9505F4F0BD8D513A18528C321DF218B0A0AF475821B130141340D8974A1
|
||||
503458009F7EFAA96F89CFAC96BF21AA9DB7F79149F905A27E7F32D8229153DB
|
||||
B4D1EB05DD499C2817F6B20580FE7D0F3DF490AF298968890F20BEFF47BEBE13
|
||||
5C9286AD081E9972DF449E50275457872CBFB64DC99A842B10E9D6615EB5002A
|
||||
2A2AE8A69B6E32EDDBDF900EECE7CF4F49F125FA28BC8D4CAB2FA0D924BBB629
|
||||
0051D7207026DFA005AD5BDBF5278578AD1600CB7B68352E6AE0D11004FB4AD9
|
||||
E46FA7827D5141C9FEFDF46F81C527DBED47065B9D7251A110886486A0975C00
|
||||
A4F36287A11D261D984F4515F5441732197F40B3516E6D55004B8A8AF4D53367
|
||||
9A9E83C8F4EDEC0A244760CB692FB800AB57AFF665F32D1724553504B33D0A7A
|
||||
06AB5AFEA8A1E6FBEFE9698935FFBE4545943373A63B1500989696A6D7EDDA65
|
||||
7A4EA45C01375B00DBB66DA3FBEFBF9F5E7BED354BEF43F75ED4F2ABCCBEE8E2
|
||||
7916FEAF05EDEB5BA4A5D13DBB76D92AB3615997D3240282915815709B024087
|
||||
DEFDECE36167A159B3664945F7FD60D67F8CAFD768D5C423EA9089FA032D0CF2
|
||||
1A160550929DAD7F595E2E3CEFDA56ADA86B18CD5837B900E8D083E0DE4C7691
|
||||
4435FB3FB94E2CF48FB3F0AB405FF4B199EFCF52BE4F458492EF6F46D8327344
|
||||
5D8441B313B502E14A5775C32A0072F7B175786969A9A5191FA4376942CFB66C
|
||||
A97CFD28057EFFFFB2E92F4AF869CC13C083F5F56191D5B0A6E66912AEC0E94D
|
||||
9BD29830ED2DE8940B0053FF9D77DEA169D3A6590AEEF9C16AFE9866CDE8CF3C
|
||||
EBBBA9CDBAC25E64FC7EA085514EC37A77C9B40F03E18A07445A0120671F0D3A
|
||||
D06E5C3689E75490C73FB5450BEAEEC2BD1615F621EBF767E4E5D1D5A5A5DE54
|
||||
00E0892E5DF4FD5BB70ACF0B473C20523180DDBB77FB7C7B04F6440D398DE8C5
|
||||
02FF049BFB2A9B2FFAD972F428BD7AE080F0BCD65DBAD09D5BB786554623625F
|
||||
CAC6036EB1393F20DC0A00FEFDE38F3FEEF3EF654A7403816E3D0FF18C7F9D8A
|
||||
EEC704D27EBFC5FEFEC112310753938807B4E759F0A6D6AD6D2B630D870B80F5
|
||||
FB575F7D95E6CF9F2F5DA11708E4EF8F63D7E72EF6F555D96E6C80249F17F6EF
|
||||
A7DD0EFBFD0D89D89D573A6C98BE49A285959D0D44ECEA088425BC3973E6D082
|
||||
050B68D5AA55218DE9E7ACE4C6B3E08F645F5F097EEC00E1C7729FA8C1073877
|
||||
D830CA5BB830BA140078BC7367FD00CFA022BAB3705C9D9212F2DF0BC50580D0
|
||||
BFF1C61BBEA0DECA952B431E0B32F8EE66C11FA496F46292D7F95EDC28B15375
|
||||
ABCE9DE9AE6DDB222697119F8264E201A02F9BC6835BB60CE96F59550028C479
|
||||
F7DD777D267E30CB77A782705E017F8F3BF95051FDD8051B7AAC9688118573BD
|
||||
DF08476C504D221E0042DD6D58140340A79DF2F2727AEFBDF768D9B265B47DFB
|
||||
765BBE1F32F66E65A12FE24365EFC53632BBF9FAD11C90474714C0EB7979FA86
|
||||
D252A97343291F365300AD5BB7F6E5E5DB095A7063B647BEBE4AE051C896F782
|
||||
70AFF71BE1D85D2AB3AF809FBC94143A2721C1F2DF3053007681E5CB1CF6EB61
|
||||
EAAB945D851FD91C7F10AE3C7F191C9DA666F5EEAD57AD5D2B3C0FD172AC0C74
|
||||
B49824132E0580515CC60A69041F57B0D0ABD6DB8A86EC3C76CCD7D25B54DB0F
|
||||
3AF4EE4DB7AE5DEB981C3A6EA7CA660A62A61DCD66BB959E82762A0008FDC52C
|
||||
EC7958A1E0436DB6A108047AFACD61D75294E8032291E927C2710500A675E8A0
|
||||
D7555509CF8312B8D68225609607200B76D719C93E3D045F05F4146660E6478A
|
||||
AF8CF0B7E8D081EEA9AA725CFE1C1F809F294949FAD1DA5AE1797007B0D1884C
|
||||
4C20180BA0257F7E36CFF4D92CF8D7B0E0ABCE3B0A1990DF5FC6F79B8CD96F57
|
||||
4B6F3B70C520FCC8E6080099D5011905005B229385FD372CF4E8B09BA58A7114
|
||||
16B112ED7762ADDF0CD70CC48F4C67613FA23C01230580CABB5FB3B00FE403D5
|
||||
776AC94E112C56D6F92355E06305570DC68F26992804CC3206FD3100E4DF0FE0
|
||||
8B3FE08469AF02780A3B90CDF0F3A3B950DE5C37203F9A052560543BB0E6BBEF
|
||||
E84C167615BC53D88D6C6EBF1FCDA5B2E6CA41F9B1E20EA08A100943AAC24E11
|
||||
4EEA75DD27FC32557DC08D667F435C3B303F560283E827701D2B81486C3AA288
|
||||
3D6A8F1FA7B9070E48D5F303B705FC02E1EAC1F991D97DD80F7205AE642510CE
|
||||
76E38AD803A9BD6FD6D448ADF103372DF599E1FA01FA914D16F2E3C476E48AE8
|
||||
44B681A71FB724F9C8E08941FA914D1BF6832DC89034A45C024530A07FDF029E
|
||||
F545BBF536C40DE9BD56F0CC40FDC81610F9814B3054327350A1F083CCBE4507
|
||||
0F4A9BFCC0E9C29E60F0D460FD582925F663478721456C60D5E4074E96F48682
|
||||
E706ECC74A53113F7009AE4A495189408A80C0E47F8D677D99DD7A1AE254330F
|
||||
3BF0E4A01B62255700204F60705252D05D8614D109F2F997F2CC2F53CCE3C7ED
|
||||
6BFC32787AF07E64BB0D3704D6005C022BFD0514D107EAF791D26B25D00722DD
|
||||
BD375C78FE0BF891DD77E054101BC072A1CA208C2D30D3C3D7B792CBEF27927D
|
||||
FBC34D547C898658750900560AFE9BAD810CB53D574CB0A1BE9EFEC2B3BE9508
|
||||
3FF042669F55A2EACBF8B19A2FE007F5044392935590304AD9F7FDF7BE59FFB3
|
||||
20BA44796D7D5F96A8FB427E64B7263F15B80259CD9BD3457C28B7203A80B9FF
|
||||
D1E1C354C18795209F9FEEB9B934A2AC2C2A6F86A8FC520DB1524CD490564D9A
|
||||
D0C0162D945BE07110DD5FC1827F80677FAB44A3C97F2A51FDE5FC946467EB5F
|
||||
969707F55E280258047DD5B2A1A74070AF2248C1075E4DECB14AD47FC1864C4B
|
||||
4BD3EB76ED0AEABD500417B012E8ABB6F3762D30EF21F8FFC747B082EFA5421E
|
||||
3B88992FEA67495191BE7AE6CCA0DF8F1583BE6C1164F2A17A09BA0334E958C5
|
||||
B3FD3FF8B01AD96F48DFA222CA993933A67ED498FAB20D29CECCD4BFAAAC0CFA
|
||||
FDB002600D5CDCA28552040E01C1FF7B5D9D6FD60F26B8E7E7F47EFDE8E655AB
|
||||
62F2478CC92FDD102BCD46020145D02B31917AB3325059859101D97B6B59E8D7
|
||||
D5D78724F85E69DA114E62FACBFB595450A0AF2B2909F973D092EC7C560638D4
|
||||
7E81F682765C9FB0C0E3906DC96546AF8202BAB2A424E6EFFF98BF000D793E2B
|
||||
4BDF595161CB6721A9A84742826F1951050D8303B33B5A71AD61A1976DC229A2
|
||||
6356168DA9A8503FC809D485084030FD068C80F09FCB8A00D58767AB5D87A440
|
||||
338E7FB1D06F62E10FC5C46F48AC2CEB59455D10135E193244DFBC78B16D9F87
|
||||
1504C40ACE62EBA0132B036519FC00847CFBB163B495051EC21FEC125E20BAE6
|
||||
E4D0C8254BD48536405D18099056FCD99B6F92D52223112849C6F133B6103A36
|
||||
6D1A330A0102BF93FDF8CF59E0B7B3C0EF6181B76BA607A8D3EF367468D4A6EF
|
||||
DA89BA401658306A94BE61FE7CDB150180F0631501B1832E7CA4459942F882AF
|
||||
D9972CECF0E511C5B753E0FD40F033468CA0E173E746CF850B33EA4205C15B85
|
||||
85FABA397328981A035920FC1DF9863E8D15018E56AC14DAF2FFB93DE7006BF3
|
||||
30E1AB58E0F7F2E3372CEC3BF9793804DE0F04BF577E3E5D515CECEE8BE342D4
|
||||
050B9150138AAC8238422A2B041C6D9B34A176FC8823D225CC28ADDDC7C20D21
|
||||
C7F3BD78CE4728997856392333930A2B2BD53D1C02EAE2D9C4FB1327EA1FB355
|
||||
50B36387237F1F16430B5602CDF931811FE3F9B1393F363DF15AB313FF877588
|
||||
447E8E73A04CBE6381854373E4F871AAE703CF8FF2FF7D8BE7FC8815F7C3FC1C
|
||||
FF87730E9F98E19D22393D9D7A8E1E4D03274F56F7AE0DA88B1806DEC8CFF7F5
|
||||
22385A5BEBF450A282F8A4243AEFEAAB55E24E18501734CCBC3C6890BEBDBC3C
|
||||
2C81C368067E7DA7EC6CBA7ED932758F861175712308F6328032B0B2C7612C81
|
||||
525C08BD577BEC7B1175A11D04F9055F7CF00185528CE465508C03818F960EBB
|
||||
5E445D781781CCC31D1F7D14B50A01029F7ED14574DDE2C5EABE7309EA877031
|
||||
C837D8B7650BEDDDB4C9736E438BB4344AEDDE9DDA76EDAAD6E75D8CFA613C08
|
||||
961CF77EF619EDE3632F2B887026249981A699A92CE06DBB75A3543ED4D29CF7
|
||||
503F58940225517FF0201DABABA323870ED1117E8E65C9233535BE7FE3F9517E
|
||||
04F12D5BFA96DA12F8312139F987E72929BE7FC7A1E3113F57C21D9DFC3FB05B
|
||||
459D4B95757A0000000049454E44AE4260822800000030000000600000000100
|
||||
0800000000000000000000000000000000000000000000000000000000000202
|
||||
04000505070004040B0003030E0004040D0008080B000A0A0E000C0C0E000404
|
||||
1200050514000C0C100006061A0006061D001111160015151A00060621000707
|
||||
280007072C001B1B20001D1D22000808350008083B0022222800242429002828
|
||||
2E002E2E2F0036363A0039393D003C3C3C000808470008084B0008084D000707
|
||||
50000808530008085A0008085F003E3E42000909660009096A000A0A71000A0A
|
||||
76000B0B79000B0B7D004343470044444700464649004A4A4C00535354005757
|
||||
57005B5B5D00666667007171710077777700787878007D7D7D00000080000606
|
||||
83000B0B8100090984000C0C85000404890005058F000C0C890016168B001717
|
||||
8C00070790000D0D91000D0D96000606990006069D000D0D9900222291003434
|
||||
9A003E3E9E000707A3000E0EA0000E0EA6000707A9000909B1000F0FB2000909
|
||||
B5001010B4001010BA005050A7005757AB007272B8000E0ECE001111C2001111
|
||||
C9001212D1001212D6001010DA001010DE001313E1001414E3001212E6001414
|
||||
E7001414E9001515EE001414F3001515F5001616FA001515FE00808080008A8A
|
||||
8A008D8D8D00929292009A9A9A009E9E9E00A1A1A100A7A7A700AAAAAA00B0B0
|
||||
B000BDBDBD00C9C9C900D0D0D000D7D7D700D9D9D900DDDDDD00E2E2E200E5E5
|
||||
E500EBEBEB00EDEDED00F1F1F100F5F5F500F9F9F900FEFEFE00000000002F26
|
||||
000050410000705B000090740000B08E0000CFA90000F0C30000FFD21100FFD8
|
||||
3100FFDD5100FFE47100FFEA9100FFF0B100FFF6D100FFFFFF00000000002F14
|
||||
00005022000070300000903E0000B04D0000CF5B0000F0690000FF791100FF8A
|
||||
3100FF9D5100FFAF7100FFC19100FFD2B100FFE5D100FFFFFF00000000002F03
|
||||
0000500400007006000090090000B00A0000CF0C0000F00E0000FF201200FF3E
|
||||
3100FF5C5100FF7A7100FF979100FFB6B100FFD4D100FFFFFF00000000002F00
|
||||
0E00500017007000210090002B00B0003600CF004000F0004900FF115A00FF31
|
||||
7000FF518600FF719C00FF91B200FFB1C800FFD1DF00FFFFFF00000000002F00
|
||||
20005000360070004C0090006200B0007800CF008E00F000A400FF11B300FF31
|
||||
BE00FF51C700FF71D100FF91DC00FFB1E500FFD1F000FFFFFF00000000002C00
|
||||
2F004B0050006900700087009000A500B000C400CF00E100F000F011FF00F231
|
||||
FF00F451FF00F671FF00F791FF00F9B1FF00FBD1FF00FFFFFF00000000001B00
|
||||
2F002D0050003F007000520090006300B0007600CF008800F0009911FF00A631
|
||||
FF00B451FF00C271FF00CF91FF00DCB1FF00EBD1FF00FFFFFF00000000000800
|
||||
2F000E005000150070001B0090002100B0002600CF002C00F0003E11FF005831
|
||||
FF007151FF008C71FF00A691FF00BFB1FF00DAD1FF00FFFFFF00000000000000
|
||||
0000000000000000000000000056554A483B3B484A5556000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000543B383D4246
|
||||
4F52534E4B4339383B5400000000000000000000000000000000000000000000
|
||||
00000000000000003B393D505E676666666666666667665E513D383C00000000
|
||||
0000000000000000000000000000000000000000000040384B5E676766666666
|
||||
666666666666666666665F4D3841000000000000000000000000000000000000
|
||||
000000004938475F66666666666666666666666666666666666667675E453849
|
||||
0000000000000000000000000000000000000041395767676767666666666666
|
||||
66666666666666666666666666665A3941000000000000000000000000000000
|
||||
0000394261676767676767676666666666666666666666666666666666676761
|
||||
423B0000000000000000000000000000003846652923475F6767676767676766
|
||||
6666666666666666666666666666666666463800000000000000000000000000
|
||||
394C6667240807011F5266676767676666666666666666666666666666666667
|
||||
6766463900000000000000000000004142656767242E7E6F25000C2B63676767
|
||||
6766666666666666666666666666666666666642410000000000000000004939
|
||||
62666767242E8F8F8F77360E0A47666766666666666666666666666666666666
|
||||
6667676139490000000000000000385767676666262E8F8F8F8F8F7C34011662
|
||||
67676766666666666666666666666666666666665A3800000000000000414766
|
||||
66666767242E8F8F8F8F8F8F8F7414105B676666666666666666666666666666
|
||||
66666667674541000000000000385D6767666666262E8F8F8F8F8F8F8F8F7A1C
|
||||
055B676767666666666666666666666666666666665F3800000000003B4D6666
|
||||
66666667241A7B8F8F8F8F8F8F8F8F7E1B126567676767666666666666666666
|
||||
6666666767674B3C00000000385E6767666666664D0C08347A7F8F8F8F8F8F8F
|
||||
790B26676767676767676766666666666666666666665F380000005442666666
|
||||
666666666666430C026D8F8F8F8F8F8F8F70005E676767676767676766666666
|
||||
666666666767673D5400003B4F67676666666666666666663C02688F8F8F8F8F
|
||||
8F7F0F2A67676767676767676767676666666666666666503B0000385E666666
|
||||
6666666666666666674C01327F8F8F8F8F8F360C44444444444444475B666666
|
||||
666666666667675C38005638676767666666666666666666666658026D8F8F8F
|
||||
8F8F75080B0707080B0808004467676666666666666666673956554366666666
|
||||
6666666666666666666767270F7D8F8F8F8F8F8F8F8F8F8F8F8F8F0B47666666
|
||||
666666666666676742554A466767666666666666666666666666666306688F8F
|
||||
8F8F8F8F8F8F8F8F8F8F8F0B446767666666666666666667464A484E67666666
|
||||
6666666666666666666667673C06798F8F8F8F8F8F8F8F8F8F8F8F0B47666666
|
||||
66666666666767674E483B5167676766666666666666666666666666660B698F
|
||||
8F8F8F8F8F8F8F8F8F8F8F08446767666666666666666666533B3B5366666666
|
||||
66666666666666666666666767222F8F8F8F8F8F8F8F8F8F8F8F8F0847666666
|
||||
6666666666666767513B484E6767676666666666666666666666666666440B8F
|
||||
8F8F8F8F712D2C2D2D2E2E024467666666666666666666674E484A4667676666
|
||||
666666666666666666666667675A00748F8F8F8F730022262627272759666666
|
||||
6666666666676767464A5542676767666666666666666666666666666667076B
|
||||
8F8F8F8F7F0E2A67676766666666666666666666666666674355563966676666
|
||||
666666666666666666666667676720308F8F8F8F8F370A656766666666666666
|
||||
6666666666676767385600385C6767676766666666666666666666666666400E
|
||||
8F8F8F8F8F79023F6767676766666666666666666666675B3800003B4F676767
|
||||
66666666666666666666666666675A00738F8F8F8F8F69015267676666666666
|
||||
666666666767674F3B0000543D67676767666666666666666666666666666610
|
||||
687F8F8F8F8F8F330359676767676666666666666667663D54000000385E6767
|
||||
66666666666666666666666666676727198F8F8F8F8F8F7F2E01285F67666666
|
||||
6666666767675D38000000003C4B67676767666666666666666666666666665A
|
||||
026E8F8F8F8F8F8F7F6C0E000C3C66666666666667674B3C0000000000385E67
|
||||
67666666666666666666666666666767280B798F8F8F8F8F8F8F7E721D1F6666
|
||||
66676767675D3800000000000040456767676767666666666666666666666666
|
||||
66111D7C8F8F8F8F8F8F8F8F331E67666667676767454100000000000000385A
|
||||
67676766666666666666666666666666675B0D18778F8F8F8F8F8F8F331E6767
|
||||
6767676757380000000000000000493861676767676766666666666666666666
|
||||
666663150E6A7E8F8F8F8F8F331E676767676761384900000000000000000041
|
||||
3E656767676666666666666666666666666667662A021469768F8F8F331E6767
|
||||
6767643E41000000000000000000000039466767676767676666666666666666
|
||||
666666666661260C02183672311E676767674639000000000000000000000000
|
||||
00384665676767676766666666666666666666666666666658281100001E6767
|
||||
644638000000000000000000000000000000393E606767676767676767666666
|
||||
6666666666666666666667635958676142390000000000000000000000000000
|
||||
0000004138576767676767676767676767676767676767676767676767675738
|
||||
41000000000000000000000000000000000000004938455D6767676767676767
|
||||
6767676767676767676767675D45384900000000000000000000000000000000
|
||||
00000000000040384B5D676767676767676767676767676767675D4B38400000
|
||||
0000000000000000000000000000000000000000000000003B383D4F5C676767
|
||||
676767676767675C4F3D383B0000000000000000000000000000000000000000
|
||||
00000000000000000000543B38383E464E51514E464238383B54000000000000
|
||||
000000000000000000000000000000000000000000000000000000000056554A
|
||||
483B3B484A555600000000000000000000000000000000000000FFFFE007FFFF
|
||||
0000FFFF0000FFFF0000FFFC00003FFF0000FFF000000FFF0000FFC0000003FF
|
||||
0000FF80000001FF0000FF00000000FF0000FE000000007F0000FC000000003F
|
||||
0000F8000000001F0000F0000000000F0000F0000000000F0000E00000000007
|
||||
0000E000000000070000C000000000030000C000000000030000800000000001
|
||||
0000800000000001000080000000000100000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000800000000001000080000000000100008000000000010000C00000000003
|
||||
0000C000000000030000E000000000070000E000000000070000F0000000000F
|
||||
0000F0000000000F0000F8000000001F0000FC000000003F0000FE000000007F
|
||||
0000FF00000000FF0000FF80000001FF0000FFC0000003FF0000FFF000000FFF
|
||||
0000FFFC00003FFF0000FFFF0000FFFF0000FFFFE007FFFF0000280000002000
|
||||
0000400000000100080000000000000000000000000000000000000000000000
|
||||
000000000000030305000B0B14000C0C16000E0E1D0012121F000F0F22001313
|
||||
220017172300101024001919270012122D0014142F00191928001D1D29001E1E
|
||||
2F001313340014143A0012123C0015153F00222231002A2A3A002C2C39003131
|
||||
3D001212450010104B001616480012124E0013135200323243003A3A46001717
|
||||
660012126A001414690012126E000F0F7D001111700013137E00454554004B4B
|
||||
570050505E005E5E6A0063636F00676772006D6D77007373780078787F000606
|
||||
8400090987000A0A88000E0E8E0012128E0015158E000D0D95000E0E9D001010
|
||||
92001919910010109A0010109C002E2E9B0031319F000E0EA8001010A3001010
|
||||
A6000F0FB7001010BA001010BF006262B4007A7ABE000D0DC2001212CE000F0F
|
||||
D0001212D1001010DA001212E7001414E7001414E9001313EE001414EC001414
|
||||
F1001414F5001616FB001616FE00808085008C8C8F00969699009E9E9F00A0A0
|
||||
A100AEAEAE00B7B7B700BEBEBE00D6D6D600DADADA00E2E2E200E4E4E400E9E9
|
||||
E900EEEEEE00F0F0F000F6F6F600F8F8F800FEFEFE004CB0000059CF000067F0
|
||||
000078FF11008AFF31009CFF5100AEFF7100C0FF9100D2FFB100E4FFD100FFFF
|
||||
FF0000000000262F0000405000005A700000749000008EB00000A9CF0000C2F0
|
||||
0000D1FF1100D8FF3100DEFF5100E3FF7100E9FF9100EFFFB100F6FFD100FFFF
|
||||
FF00000000002F26000050410000705B000090740000B08E0000CFA90000F0C3
|
||||
0000FFD21100FFD83100FFDD5100FFE47100FFEA9100FFF0B100FFF6D100FFFF
|
||||
FF00000000002F1400005022000070300000903E0000B04D0000CF5B0000F069
|
||||
0000FF791100FF8A3100FF9D5100FFAF7100FFC19100FFD2B100FFE5D100FFFF
|
||||
FF00000000002F030000500400007006000090090000B00A0000CF0C0000F00E
|
||||
0000FF201200FF3E3100FF5C5100FF7A7100FF979100FFB6B100FFD4D100FFFF
|
||||
FF00000000002F000E00500017007000210090002B00B0003600CF004000F000
|
||||
4900FF115A00FF317000FF518600FF719C00FF91B200FFB1C800FFD1DF00FFFF
|
||||
FF00000000002F0020005000360070004C0090006200B0007800CF008E00F000
|
||||
A400FF11B300FF31BE00FF51C700FF71D100FF91DC00FFB1E500FFD1F000FFFF
|
||||
FF00000000002C002F004B0050006900700087009000A500B000C400CF00E100
|
||||
F000F011FF00F231FF00F451FF00F671FF00F791FF00F9B1FF00FBD1FF00FFFF
|
||||
FF00000000001B002F002D0050003F007000520090006300B0007600CF008800
|
||||
F0009911FF00A631FF00B451FF00C271FF00CF91FF00DCB1FF00EBD1FF00FFFF
|
||||
FF000000000008002F000E005000150070001B0090002100B0002600CF002C00
|
||||
F0003E11FF005831FF007151FF008C71FF00A691FF00BFB1FF00DAD1FF00FFFF
|
||||
FF00000000000000000000000000433C382F2F383C4300000000000000000000
|
||||
000000000000000000000043313945494A50504A494539314300000000000000
|
||||
0000000000000000004431404F525252525252525252524F4031440000000000
|
||||
00000000000000003B3F4F52525252525252525252525252524D3F3B00000000
|
||||
0000000000000034414952525252525252525252525252525252524234000000
|
||||
00000000000034474B0110324B52525252525252525252525252525247340000
|
||||
00000000003B42524B0F5C2E0A1A485252525252525252525252525252423B00
|
||||
00000000443F52524B0F6F6F6F5A0A3352525252525252525252525252523F44
|
||||
00000000314D52524B0F6F6F6F6F6127184B5252525252525252525252524D31
|
||||
00000043405252524B08626F6F6F6F6F55125252525252525252525252525240
|
||||
430000314F52525250220553636F6F6F6F2B255252525252525252525252524F
|
||||
300000395252525252524E2017606F6F6F610451525252525252525252525252
|
||||
390043455252525252525252370E616F6F6F281B1F1F1F1F2452525252525252
|
||||
45433C49525252525252525252232C6F6F6F5E59595959590352525252525252
|
||||
493C384A52525252525252525250065D6F6F6F6F6F6F6F6F0352525252525252
|
||||
4A382F505252525252525252525236296F6F6F6F6F6F6F6F0352525252525252
|
||||
502F2F50525252525252525252524E0D6F6F6F615B5C5B5B0352525252525252
|
||||
502F384A52525252525252525252520B5F6F6F5B011313131952525252525252
|
||||
4A383C49525252525252525252525221586F6F6F144952525252525252525252
|
||||
493C434552525252525252525252523D2A6F6F6F542452525252525252525252
|
||||
4543003952525252525252525252524E0D6F6F6F63163E525252525252525252
|
||||
390000304F5252525252525252525252115C6F6F6F5F0E21465252525252524F
|
||||
300000434052525252525252525252523E266F6F6F6F6257151C525252525240
|
||||
43000000314D52525252525252525252521B53646F6F6F6F610C525252524D31
|
||||
00000000443F52525252525252525252524E1C1E5F6F6F6F610C525252523F44
|
||||
00000000003B425252525252525252525252523A0756616F610C525252423B00
|
||||
00000000000034475252525252525252525252524922091D2D0C525247340000
|
||||
0000000000000034425252525252525252525252525252483532524234000000
|
||||
00000000000000003B3F4D52525252525252525252525252524D3F3B00000000
|
||||
0000000000000000004431404F525252525252525252524F4031440000000000
|
||||
000000000000000000000043303945494A50504A494539304300000000000000
|
||||
0000000000000000000000000000433C382F2F383C4300000000000000000000
|
||||
0000FFF00FFFFF8001FFFE00007FFC00003FF800001FF000000FE0000007C000
|
||||
0003C00000038000000180000001800000010000000000000000000000000000
|
||||
000000000000000000000000000000000000800000018000000180000001C000
|
||||
0003C0000003E0000007F000000FF800001FFC00003FFE00007FFF8001FFFFF0
|
||||
0FFF280000001000000020000000010008000000000000000000000000000000
|
||||
00000000000000000000000000003F3F69002A2A720044447700272784002323
|
||||
8F002C2C8F003535870033338C0035358E002A2A91002D2D910023239A001F1F
|
||||
A1001F1FB1001C1CBF002323A0002525A4003333BE0040408700515181005555
|
||||
86005F5F80006363870062628E0066668E00696989004747B4004A4ABC001515
|
||||
C3001515D4001919D6002828C5001717E5001515F3001515FA001616FE006969
|
||||
C1007E7EC8009797AA00AFAFBB00BABAC700C2C2C800CDCDD400D1D1D300D5D5
|
||||
D800DDDDE000E4E4E500F1F1F100F9F9F900FFFFFF0000704C000090630000B0
|
||||
790000CF8F0000F0A60011FFB40031FFBE0051FFC80071FFD30091FFDC00B1FF
|
||||
E500D1FFF000FFFFFF0000000000002F0E00005018000070220000902C0000B0
|
||||
360000CF400000F04A0011FF5B0031FF710051FF870071FF9D0091FFB200B1FF
|
||||
C900D1FFDF00FFFFFF0000000000022F00000450000006700000089000000AB0
|
||||
00000BCF00000EF0000020FF12003DFF31005BFF510079FF710098FF9100B5FF
|
||||
B100D4FFD100FFFFFF0000000000142F000022500000307000003D9000004CB0
|
||||
000059CF000067F0000078FF11008AFF31009CFF5100AEFF7100C0FF9100D2FF
|
||||
B100E4FFD100FFFFFF0000000000262F0000405000005A700000749000008EB0
|
||||
0000A9CF0000C2F00000D1FF1100D8FF3100DEFF5100E3FF7100E9FF9100EFFF
|
||||
B100F6FFD100FFFFFF00000000002F26000050410000705B000090740000B08E
|
||||
0000CFA90000F0C30000FFD21100FFD83100FFDD5100FFE47100FFEA9100FFF0
|
||||
B100FFF6D100FFFFFF00000000002F1400005022000070300000903E0000B04D
|
||||
0000CF5B0000F0690000FF791100FF8A3100FF9D5100FFAF7100FFC19100FFD2
|
||||
B100FFE5D100FFFFFF00000000002F030000500400007006000090090000B00A
|
||||
0000CF0C0000F00E0000FF201200FF3E3100FF5C5100FF7A7100FF979100FFB6
|
||||
B100FFD4D100FFFFFF00000000002F000E00500017007000210090002B00B000
|
||||
3600CF004000F0004900FF115A00FF317000FF518600FF719C00FF91B200FFB1
|
||||
C800FFD1DF00FFFFFF00000000002F0020005000360070004C0090006200B000
|
||||
7800CF008E00F000A400FF11B300FF31BE00FF51C700FF71D100FF91DC00FFB1
|
||||
E500FFD1F000FFFFFF00000000002C002F004B0050006900700087009000A500
|
||||
B000C400CF00E100F000F011FF00F231FF00F451FF00F671FF00F791FF00F9B1
|
||||
FF00FBD1FF00FFFFFF00000000001B002F002D0050003F007000520090006300
|
||||
B0007600CF008800F0009911FF00A631FF00B451FF00C271FF00CF91FF00DCB1
|
||||
FF00EBD1FF00FFFFFF000000000008002F000E005000150070001B0090002100
|
||||
B0002600CF002C00F0003E11FF005831FF007151FF008C71FF00A691FF00BFB1
|
||||
FF00DAD1FF00FFFFFF000000000000251C12121C250000000000000000262023
|
||||
2424242423202600000000001B0D0E23242424242424211B0000002621092C17
|
||||
112424242424242126000020240832322B0724242424242420002523241F032E
|
||||
32280F242424242423251C24242424042D321A1515102424241C122424242424
|
||||
143232323206242424121224242424240B313016180C242424121C2424242424
|
||||
1D2A321324242424241C25232424242424153229052224242325002024242424
|
||||
240C2E322F012424200000262124242424240A2731192421260000001B212424
|
||||
2424241E0A02211B000000000026202324242424232026000000000000000025
|
||||
1C12121C250000000000F81F0000E0070000C003000080010000800100000000
|
||||
000000000000000000000000000000000000000000008001000080010000C003
|
||||
0000E0070000F81F0000}
|
||||
OldCreateOrder = False
|
||||
OnCreate = FormCreate
|
||||
OnResize = FormResize
|
||||
PixelsPerInch = 96
|
||||
TextHeight = 13
|
||||
end
|
||||
94
libsrc/Swf2Exe/uMain.pas
Normal file
94
libsrc/Swf2Exe/uMain.pas
Normal file
@@ -0,0 +1,94 @@
|
||||
unit uMain;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
|
||||
Dialogs, OleCtrls, ShockwaveFlashObjects_TLB, StdCtrls, ExtCtrls;
|
||||
|
||||
type
|
||||
TfrmMain = class(TForm)
|
||||
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure FormResize(Sender: TObject);
|
||||
private
|
||||
{ Private declarations }
|
||||
public
|
||||
{ Public declarations }
|
||||
end;
|
||||
|
||||
type
|
||||
TMySWF = class(TShockwaveFlash)
|
||||
public
|
||||
procedure CreateWnd; override;
|
||||
end;
|
||||
|
||||
var
|
||||
frmMain: TfrmMain;
|
||||
flaPreview: TMySWF;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.dfm}
|
||||
|
||||
procedure TMySWF.CreateWnd;
|
||||
begin
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.FormCreate(Sender: TObject);
|
||||
const
|
||||
exeSize = 470016;
|
||||
var
|
||||
stream: TFileStream;
|
||||
buffer: array of byte;
|
||||
tempFile: array[0..MAX_PATH - 1] of char;
|
||||
tempPath: array[0..MAX_PATH - 1] of char;
|
||||
flashVarData: TVarData;
|
||||
Width: integer;
|
||||
Height: integer;
|
||||
scaleMode: byte;
|
||||
begin
|
||||
flaPreview := TMySWF.Create(frmMain);
|
||||
flaPreview.Parent := frmMain;
|
||||
flaPreview.Anchors := [akLeft, akRight, akTop, akBottom];
|
||||
flaPreview.Align := alClient;
|
||||
GetTempPath(MAX_PATH, TempPath);
|
||||
if GetTempFileName(TempPath, PAnsiChar('ffd'), 0, TempFile) = 0 then
|
||||
raise Exception.Create('GetTempFileName API failed. ' +
|
||||
SysErrorMessage(GetLastError));
|
||||
try
|
||||
stream := TFileStream.Create(ParamStr(0), fmOpenRead);
|
||||
stream.Seek(exeSize, soBeginning);
|
||||
stream.Read(Width, 4);
|
||||
stream.Read(Height, 4);
|
||||
stream.Read(scaleMode, 1);
|
||||
SetLength(buffer, stream.Size - exeSize);
|
||||
try
|
||||
stream.Read(buffer[0], Length(buffer));
|
||||
finally
|
||||
stream.Free;
|
||||
end;
|
||||
except
|
||||
Width := 12800;
|
||||
Height := 9600;
|
||||
scaleMode := 3;
|
||||
end;
|
||||
ClientWidth := Width div 20;
|
||||
ClientHeight := Height div 20;
|
||||
stream := TFileStream.Create(tempFile, fmOpenWrite);
|
||||
try
|
||||
stream.Write(buffer[0], Length(buffer));
|
||||
finally
|
||||
stream.Free;
|
||||
end;
|
||||
flaPreview.Movie := tempFile;
|
||||
flaPreview.ScaleMode := scaleMode;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.FormResize(Sender: TObject);
|
||||
begin
|
||||
flaPreview.CreateWnd;
|
||||
end;
|
||||
|
||||
end.
|
||||
73
libsrc/avi/build.xml
Normal file
73
libsrc/avi/build.xml
Normal file
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- You may freely edit this file. See commented blocks below for -->
|
||||
<!-- some examples of how to customize the build. -->
|
||||
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||
<!-- the Compile on Save feature is turned off for the project. -->
|
||||
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||
<!-- in the project's Project Properties dialog box.-->
|
||||
<project name="avi" default="default" basedir=".">
|
||||
<description>Builds, tests, and runs the project avi.</description>
|
||||
<import file="nbproject/build-impl.xml"/>
|
||||
<!--
|
||||
|
||||
There exist several targets which are by default empty and which can be
|
||||
used for execution of your tasks. These targets are usually executed
|
||||
before and after some main targets. They are:
|
||||
|
||||
-pre-init: called before initialization of project properties
|
||||
-post-init: called after initialization of project properties
|
||||
-pre-compile: called before javac compilation
|
||||
-post-compile: called after javac compilation
|
||||
-pre-compile-single: called before javac compilation of single file
|
||||
-post-compile-single: called after javac compilation of single file
|
||||
-pre-compile-test: called before javac compilation of JUnit tests
|
||||
-post-compile-test: called after javac compilation of JUnit tests
|
||||
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||
-pre-jar: called before JAR building
|
||||
-post-jar: called after JAR building
|
||||
-post-clean: called after cleaning build products
|
||||
|
||||
(Targets beginning with '-' are not intended to be called on their own.)
|
||||
|
||||
Example of inserting an obfuscator after compilation could look like this:
|
||||
|
||||
<target name="-post-compile">
|
||||
<obfuscate>
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
</obfuscate>
|
||||
</target>
|
||||
|
||||
For list of available properties check the imported
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
|
||||
Another way to customize the build is by overriding existing main targets.
|
||||
The targets of interest are:
|
||||
|
||||
-init-macrodef-javac: defines macro for javac compilation
|
||||
-init-macrodef-junit: defines macro for junit execution
|
||||
-init-macrodef-debug: defines macro for class debugging
|
||||
-init-macrodef-java: defines macro for class execution
|
||||
-do-jar: JAR building
|
||||
run: execution of project
|
||||
-javadoc-build: Javadoc generation
|
||||
test-report: JUnit report generation
|
||||
|
||||
An example of overriding the target for project execution could look like this:
|
||||
|
||||
<target name="run" depends="avi-impl.jar">
|
||||
<exec dir="bin" executable="launcher.exe">
|
||||
<arg file="${dist.jar}"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
Notice that the overridden target depends on the jar target and not only on
|
||||
the compile target as the regular run target does. Again, for a list of available
|
||||
properties which you can use, check the target you are overriding in the
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
-->
|
||||
</project>
|
||||
1413
libsrc/avi/nbproject/build-impl.xml
Normal file
1413
libsrc/avi/nbproject/build-impl.xml
Normal file
File diff suppressed because it is too large
Load Diff
8
libsrc/avi/nbproject/genfiles.properties
Normal file
8
libsrc/avi/nbproject/genfiles.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
build.xml.data.CRC32=505ab359
|
||||
build.xml.script.CRC32=fa68b8cb
|
||||
build.xml.stylesheet.CRC32=8064a381@1.68.1.46
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=505ab359
|
||||
nbproject/build-impl.xml.script.CRC32=3d5c3ae5
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.74.1.48
|
||||
72
libsrc/avi/nbproject/project.properties
Normal file
72
libsrc/avi/nbproject/project.properties
Normal file
@@ -0,0 +1,72 @@
|
||||
annotation.processing.enabled=true
|
||||
annotation.processing.enabled.in.editor=false
|
||||
annotation.processing.processor.options=
|
||||
annotation.processing.processors.list=
|
||||
annotation.processing.run.all.processors=true
|
||||
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
||||
build.classes.dir=${build.dir}/classes
|
||||
build.classes.excludes=**/*.java,**/*.form
|
||||
# This directory is removed when the project is cleaned:
|
||||
build.dir=build
|
||||
build.generated.dir=${build.dir}/generated
|
||||
build.generated.sources.dir=${build.dir}/generated-sources
|
||||
# Only compile against the classpath explicitly listed here:
|
||||
build.sysclasspath=ignore
|
||||
build.test.classes.dir=${build.dir}/test/classes
|
||||
build.test.results.dir=${build.dir}/test/results
|
||||
# Uncomment to specify the preferred debugger connection transport:
|
||||
#debug.transport=dt_socket
|
||||
debug.classpath=\
|
||||
${run.classpath}
|
||||
debug.test.classpath=\
|
||||
${run.test.classpath}
|
||||
# Files in build.classes.dir which should be excluded from distribution jar
|
||||
dist.archive.excludes=
|
||||
# This directory is removed when the project is cleaned:
|
||||
dist.dir=dist
|
||||
dist.jar=../../lib/avi.jar
|
||||
dist.javadoc.dir=${dist.dir}/javadoc
|
||||
excludes=
|
||||
includes=**
|
||||
jar.compress=false
|
||||
javac.classpath=
|
||||
# Space-separated list of extra javac options
|
||||
javac.compilerargs=
|
||||
javac.deprecation=false
|
||||
javac.processorpath=\
|
||||
${javac.classpath}
|
||||
javac.source=1.7
|
||||
javac.target=1.7
|
||||
javac.test.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
javac.test.processorpath=\
|
||||
${javac.test.classpath}
|
||||
javadoc.additionalparam=
|
||||
javadoc.author=false
|
||||
javadoc.encoding=${source.encoding}
|
||||
javadoc.noindex=false
|
||||
javadoc.nonavbar=false
|
||||
javadoc.notree=false
|
||||
javadoc.private=false
|
||||
javadoc.splitindex=true
|
||||
javadoc.use=true
|
||||
javadoc.version=false
|
||||
javadoc.windowtitle=
|
||||
main.class=org.monte.media.math.IntMath
|
||||
meta.inf.dir=${src.dir}/META-INF
|
||||
mkdist.disabled=true
|
||||
platform.active=default_platform
|
||||
run.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
# Space-separated list of JVM arguments used when running the project.
|
||||
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
|
||||
# To set system properties for unit tests define test-sys-prop.name=value:
|
||||
run.jvmargs=
|
||||
run.test.classpath=\
|
||||
${javac.test.classpath}:\
|
||||
${build.test.classes.dir}
|
||||
source.encoding=UTF-8
|
||||
src.dir=src
|
||||
test.src.dir=test
|
||||
15
libsrc/avi/nbproject/project.xml
Normal file
15
libsrc/avi/nbproject/project.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.java.j2seproject</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<name>avi</name>
|
||||
<source-roots>
|
||||
<root id="src.dir"/>
|
||||
</source-roots>
|
||||
<test-roots>
|
||||
<root id="test.src.dir"/>
|
||||
</test-roots>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
39
libsrc/avi/src/org/monte/media/AbortException.java
Normal file
39
libsrc/avi/src/org/monte/media/AbortException.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* @(#)AbortException.java
|
||||
*
|
||||
* Copyright (c) 1999-2012 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media;
|
||||
|
||||
/**
|
||||
* This exception is thrown when the production of an image
|
||||
* has been aborted.
|
||||
*
|
||||
* @author Werner Randelshofer, Hausmatt 10, CH-6405 Goldau, Switzerland
|
||||
*
|
||||
* @version $Id: AbortException.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class AbortException extends Exception {
|
||||
|
||||
public static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
Creates a new exception.
|
||||
*/
|
||||
public AbortException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a new exception.
|
||||
|
||||
*/
|
||||
public AbortException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
99
libsrc/avi/src/org/monte/media/AbstractCodec.java
Normal file
99
libsrc/avi/src/org/monte/media/AbstractCodec.java
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.monte.media;
|
||||
|
||||
import java.util.ArrayList;
|
||||
/**
|
||||
* {@code AbstractCodec}.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version 1.0 2011-03-12 Created.
|
||||
*/
|
||||
public abstract class AbstractCodec implements Codec {
|
||||
|
||||
protected Format[] inputFormats;
|
||||
protected Format[] outputFormats;
|
||||
protected Format inputFormat;
|
||||
protected Format outputFormat;
|
||||
protected String name="unnamed codec";
|
||||
|
||||
public AbstractCodec(Format[] supportedInputFormats, Format[] supportedOutputFormats) {
|
||||
this.inputFormats = supportedInputFormats;
|
||||
this.outputFormats = supportedOutputFormats;
|
||||
}
|
||||
public AbstractCodec(Format[] supportedInputOutputFormats) {
|
||||
this.inputFormats = supportedInputOutputFormats;
|
||||
this.outputFormats = supportedInputOutputFormats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Format[] getInputFormats() {
|
||||
return inputFormats.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Format[] getOutputFormats(Format input) {
|
||||
ArrayList<Format>of=new ArrayList<Format>(outputFormats.length);
|
||||
for (Format f:outputFormats) {
|
||||
of.add(input==null?f:f.append(input));
|
||||
}
|
||||
return of.toArray(new Format[of.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Format setInputFormat(Format f) {
|
||||
if (f!=null)
|
||||
for (Format sf : getInputFormats()) {
|
||||
if (sf.matches(f)) {
|
||||
this.inputFormat = sf.append(f);
|
||||
return inputFormat;
|
||||
}
|
||||
}
|
||||
this.inputFormat=null;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Format setOutputFormat(Format f) {
|
||||
for (Format sf : getOutputFormats(f)) {
|
||||
if (sf.matches(f)) {
|
||||
this.outputFormat = f;
|
||||
return sf;
|
||||
}
|
||||
}
|
||||
this.outputFormat=null;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Format getInputFormat() {
|
||||
return inputFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Format getOutputFormat() {
|
||||
return outputFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** Empty implementation of the reset method. Don't call super. */
|
||||
@Override
|
||||
public void reset() {
|
||||
// empty
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String className=getClass().getName();
|
||||
int p=className.lastIndexOf('.');
|
||||
return className.substring(p+1)+"{" + "inputFormat=" + inputFormat + ", outputFormat=" + outputFormat+'}';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
226
libsrc/avi/src/org/monte/media/AbstractVideoCodec.java
Normal file
226
libsrc/avi/src/org/monte/media/AbstractVideoCodec.java
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* @(#)AbstractVideoCodec.java
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.awt.image.DataBufferShort;
|
||||
import java.awt.image.DataBufferUShort;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import static org.monte.media.VideoFormatKeys.*;
|
||||
|
||||
/**
|
||||
* {@code AbstractVideoCodec}.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: AbstractVideoCodec.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public abstract class AbstractVideoCodec extends AbstractCodec {
|
||||
|
||||
private BufferedImage imgConverter;
|
||||
|
||||
public AbstractVideoCodec(Format[] supportedInputFormats, Format[] supportedOutputFormats) {
|
||||
super(supportedInputFormats, supportedOutputFormats);
|
||||
}
|
||||
|
||||
/** Gets 8-bit indexed pixels from a buffer. Returns null if conversion failed. */
|
||||
protected byte[] getIndexed8(Buffer buf) {
|
||||
if (buf.data instanceof byte[]) {
|
||||
return (byte[]) buf.data;
|
||||
}
|
||||
if (buf.data instanceof BufferedImage) {
|
||||
BufferedImage image = (BufferedImage) buf.data;
|
||||
if (image.getRaster().getDataBuffer() instanceof DataBufferByte) {
|
||||
return ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Gets 15-bit RGB pixels from a buffer. Returns null if conversion failed. */
|
||||
protected short[] getRGB15(Buffer buf) {
|
||||
if (buf.data instanceof int[]) {
|
||||
return (short[]) buf.data;
|
||||
}
|
||||
if (buf.data instanceof BufferedImage) {
|
||||
BufferedImage image = (BufferedImage) buf.data;
|
||||
if (image.getColorModel() instanceof DirectColorModel) {
|
||||
DirectColorModel dcm = (DirectColorModel) image.getColorModel();
|
||||
if (image.getRaster().getDataBuffer() instanceof DataBufferShort) {
|
||||
// FIXME - Implement additional checks
|
||||
return ((DataBufferShort) image.getRaster().getDataBuffer()).getData();
|
||||
} else if (image.getRaster().getDataBuffer() instanceof DataBufferUShort) {
|
||||
// FIXME - Implement additional checks
|
||||
return ((DataBufferUShort) image.getRaster().getDataBuffer()).getData();
|
||||
}
|
||||
}
|
||||
if (imgConverter == null) {
|
||||
int width = outputFormat.get(WidthKey);
|
||||
int height = outputFormat.get(HeightKey);
|
||||
imgConverter = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_555_RGB);
|
||||
}
|
||||
Graphics2D g = imgConverter.createGraphics();
|
||||
g.drawImage(image, 0, 0, null);
|
||||
g.dispose();
|
||||
return ((DataBufferUShort) imgConverter.getRaster().getDataBuffer()).getData();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/** Gets 16-bit RGB-5-6-5 pixels from a buffer. Returns null if conversion failed. */
|
||||
protected short[] getRGB16(Buffer buf) {
|
||||
if (buf.data instanceof int[]) {
|
||||
return (short[]) buf.data;
|
||||
}
|
||||
if (buf.data instanceof BufferedImage) {
|
||||
BufferedImage image = (BufferedImage) buf.data;
|
||||
if (image.getColorModel() instanceof DirectColorModel) {
|
||||
DirectColorModel dcm = (DirectColorModel) image.getColorModel();
|
||||
if (image.getRaster().getDataBuffer() instanceof DataBufferShort) {
|
||||
// FIXME - Implement additional checks
|
||||
return ((DataBufferShort) image.getRaster().getDataBuffer()).getData();
|
||||
} else if (image.getRaster().getDataBuffer() instanceof DataBufferUShort) {
|
||||
// FIXME - Implement additional checks
|
||||
return ((DataBufferUShort) image.getRaster().getDataBuffer()).getData();
|
||||
}
|
||||
}
|
||||
if (imgConverter == null) {
|
||||
int width = outputFormat.get(WidthKey);
|
||||
int height = outputFormat.get(HeightKey);
|
||||
imgConverter = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_565_RGB);
|
||||
}
|
||||
Graphics2D g = imgConverter.createGraphics();
|
||||
g.drawImage(image, 0, 0, null);
|
||||
g.dispose();
|
||||
return ((DataBufferUShort) imgConverter.getRaster().getDataBuffer()).getData();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/** Gets 24-bit RGB pixels from a buffer. Returns null if conversion failed. */
|
||||
protected int[] getRGB24(Buffer buf) {
|
||||
if (buf.data instanceof int[]) {
|
||||
return (int[]) buf.data;
|
||||
}
|
||||
if (buf.data instanceof BufferedImage) {
|
||||
BufferedImage image = (BufferedImage) buf.data;
|
||||
if (image.getColorModel() instanceof DirectColorModel) {
|
||||
DirectColorModel dcm = (DirectColorModel) image.getColorModel();
|
||||
if (dcm.getBlueMask() == 0xff && dcm.getGreenMask() == 0xff00 && dcm.getRedMask() == 0xff0000) {
|
||||
if (image.getRaster().getDataBuffer() instanceof DataBufferInt) {
|
||||
return ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
|
||||
}
|
||||
}
|
||||
}
|
||||
return image.getRGB(0, 0, //
|
||||
outputFormat.get(WidthKey), outputFormat.get(HeightKey), //
|
||||
null, 0, outputFormat.get(WidthKey));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Gets 32-bit ARGB pixels from a buffer. Returns null if conversion failed. */
|
||||
protected int[] getARGB32(Buffer buf) {
|
||||
if (buf.data instanceof int[]) {
|
||||
return (int[]) buf.data;
|
||||
}
|
||||
if (buf.data instanceof BufferedImage) {
|
||||
BufferedImage image = (BufferedImage) buf.data;
|
||||
if (image.getColorModel() instanceof DirectColorModel) {
|
||||
DirectColorModel dcm = (DirectColorModel) image.getColorModel();
|
||||
if (dcm.getBlueMask() == 0xff && dcm.getGreenMask() == 0xff00 && dcm.getRedMask() == 0xff0000) {
|
||||
if (image.getRaster().getDataBuffer() instanceof DataBufferInt) {
|
||||
return ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
|
||||
}
|
||||
}
|
||||
}
|
||||
return image.getRGB(0, 0, //
|
||||
outputFormat.get(WidthKey), outputFormat.get(HeightKey), //
|
||||
null, 0, outputFormat.get(WidthKey));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Gets a buffered image from a buffer. Returns null if conversion failed. */
|
||||
protected BufferedImage getBufferedImage(Buffer buf) {
|
||||
if (buf.data instanceof BufferedImage) {
|
||||
return (BufferedImage) buf.data;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private byte[] byteBuf = new byte[4];
|
||||
|
||||
protected void writeInt24(ImageOutputStream out, int v) throws IOException {
|
||||
byteBuf[0] = (byte) (v >>> 16);
|
||||
byteBuf[1] = (byte) (v >>> 8);
|
||||
byteBuf[2] = (byte) (v >>> 0);
|
||||
out.write(byteBuf, 0, 3);
|
||||
}
|
||||
|
||||
protected void writeInt24LE(ImageOutputStream out, int v) throws IOException {
|
||||
byteBuf[2] = (byte) (v >>> 16);
|
||||
byteBuf[1] = (byte) (v >>> 8);
|
||||
byteBuf[0] = (byte) (v >>> 0);
|
||||
out.write(byteBuf, 0, 3);
|
||||
}
|
||||
|
||||
protected void writeInts24(ImageOutputStream out, int[] i, int off, int len) throws IOException {
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if (off < 0 || len < 0 || off + len > i.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException("off < 0 || len < 0 || off + len > i.length!");
|
||||
}
|
||||
|
||||
byte[] b = new byte[len * 3];
|
||||
int boff = 0;
|
||||
for (int j = 0; j < len; j++) {
|
||||
int v = i[off + j];
|
||||
//b[boff++] = (byte)(v >>> 24);
|
||||
b[boff++] = (byte) (v >>> 16);
|
||||
b[boff++] = (byte) (v >>> 8);
|
||||
b[boff++] = (byte) (v >>> 0);
|
||||
}
|
||||
|
||||
out.write(b, 0, len * 3);
|
||||
}
|
||||
|
||||
protected void writeInts24LE(ImageOutputStream out, int[] i, int off, int len) throws IOException {
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if (off < 0 || len < 0 || off + len > i.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException("off < 0 || len < 0 || off + len > i.length!");
|
||||
}
|
||||
|
||||
byte[] b = new byte[len * 3];
|
||||
int boff = 0;
|
||||
for (int j = 0; j < len; j++) {
|
||||
int v = i[off + j];
|
||||
b[boff++] = (byte) (v >>> 0);
|
||||
b[boff++] = (byte) (v >>> 8);
|
||||
b[boff++] = (byte) (v >>> 16);
|
||||
//b[boff++] = (byte)(v >>> 24);
|
||||
}
|
||||
|
||||
out.write(b, 0, len * 3);
|
||||
}
|
||||
|
||||
/** Copies a buffered image. */
|
||||
protected static BufferedImage copyImage(BufferedImage img) {
|
||||
ColorModel cm = img.getColorModel();
|
||||
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
|
||||
WritableRaster raster = img.copyData(null);
|
||||
return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
|
||||
}
|
||||
}
|
||||
126
libsrc/avi/src/org/monte/media/AudioFormatKeys.java
Normal file
126
libsrc/avi/src/org/monte/media/AudioFormatKeys.java
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* @(#)AudioFormatKeys.java
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance onlyWith the
|
||||
* license agreement you entered into onlyWith Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media;
|
||||
|
||||
import org.monte.media.math.Rational;
|
||||
import java.nio.ByteOrder;
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioFormat.Encoding;
|
||||
|
||||
/**
|
||||
* Defines common format keys for audio media.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: AudioFormatKeys.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class AudioFormatKeys extends FormatKeys {
|
||||
// Standard video EncodingKey strings for use onlyWith FormatKey.Encoding.
|
||||
|
||||
/**
|
||||
* Specifies SignedKey, linear PCM data.
|
||||
*/
|
||||
public static final String ENCODING_PCM_SIGNED = javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED.toString();
|
||||
/**
|
||||
* Specifies unsigned, linear PCM data.
|
||||
*/
|
||||
public static final String ENCODING_PCM_UNSIGNED = javax.sound.sampled.AudioFormat.Encoding.PCM_UNSIGNED.toString();
|
||||
/**
|
||||
* Specifies u-law encoded data.
|
||||
*/
|
||||
public static final String ENCODING_ULAW = javax.sound.sampled.AudioFormat.Encoding.ULAW.toString();
|
||||
/**
|
||||
* Specifies a-law encoded data.
|
||||
*/
|
||||
public static final String ENCODING_ALAW = javax.sound.sampled.AudioFormat.Encoding.ALAW.toString();
|
||||
/**
|
||||
* AVI PCM encoding.
|
||||
*/
|
||||
public static final String ENCODING_AVI_PCM = "\u0000\u0000\u0000\u0001";
|
||||
/**
|
||||
* QuickTime 16-bit big endian signed PCM encoding.
|
||||
*/
|
||||
public static final String ENCODING_QUICKTIME_TWOS_PCM = "twos";
|
||||
/**
|
||||
* QuickTime 16-bit little endian signed PCM encoding.
|
||||
*/
|
||||
public static final String ENCODING_QUICKTIME_SOWT_PCM = "sowt";
|
||||
/**
|
||||
* QuickTime 24-bit big endian signed PCM encoding.
|
||||
*/
|
||||
public static final String ENCODING_QUICKTIME_IN24_PCM = "in24";
|
||||
/**
|
||||
* QuickTime 32-bit big endian signed PCM encoding.
|
||||
*/
|
||||
public static final String ENCODING_QUICKTIME_IN32_PCM = "in32";
|
||||
/**
|
||||
* QuickTime 8-bit unsigned PCM encoding.
|
||||
*/
|
||||
public static final String ENCODING_QUICKTIME_RAW_PCM = "raw ";
|
||||
/**
|
||||
* Specifies MP3 encoded data.
|
||||
*/
|
||||
public static final String ENCODING_MP3 = "MP3";
|
||||
/**
|
||||
* The sample size in bits.
|
||||
*/
|
||||
public final static FormatKey<Integer> SampleSizeInBitsKey = new FormatKey<Integer>("sampleSizeInBits", Integer.class);
|
||||
/**
|
||||
* The numer of ChannelsKey.
|
||||
*/
|
||||
public final static FormatKey<Integer> ChannelsKey = new FormatKey<Integer>("channels", Integer.class);
|
||||
/**
|
||||
* The size of a frame.
|
||||
*/
|
||||
public final static FormatKey<Integer> FrameSizeKey = new FormatKey<Integer>("frameSize", Integer.class);
|
||||
/**
|
||||
* The compressor name.
|
||||
*/
|
||||
public final static FormatKey<ByteOrder> ByteOrderKey = new FormatKey<ByteOrder>("byteOrder", ByteOrder.class);
|
||||
/**
|
||||
* The number of frames per second.
|
||||
*/
|
||||
public final static FormatKey<Rational> SampleRateKey = new FormatKey<Rational>("sampleRate", Rational.class);
|
||||
/**
|
||||
* Whether values are signed.
|
||||
*/
|
||||
public final static FormatKey<Boolean> SignedKey = new FormatKey<Boolean>("signed", Boolean.class);
|
||||
/**
|
||||
* Whether silence is encoded as -128 instead of 0.
|
||||
*/
|
||||
public final static FormatKey<Boolean> SilenceBugKey = new FormatKey<Boolean>("silenceBug", Boolean.class);
|
||||
|
||||
public static Format fromAudioFormat(javax.sound.sampled.AudioFormat fmt) {
|
||||
return new Format(
|
||||
MediaTypeKey, MediaType.AUDIO,
|
||||
EncodingKey, fmt.getEncoding().toString(),
|
||||
SampleRateKey, Rational.valueOf(fmt.getSampleRate()),
|
||||
SampleSizeInBitsKey, fmt.getSampleSizeInBits(),
|
||||
ChannelsKey, fmt.getChannels(),
|
||||
FrameSizeKey, fmt.getFrameSize(),
|
||||
FrameRateKey, Rational.valueOf(fmt.getFrameRate()),
|
||||
ByteOrderKey, fmt.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN,
|
||||
SignedKey, AudioFormat.Encoding.PCM_SIGNED.equals(fmt.getEncoding())//,
|
||||
//
|
||||
);
|
||||
}
|
||||
|
||||
public static javax.sound.sampled.AudioFormat toAudioFormat(Format fmt) {
|
||||
// We always use PCM_SIGNED or PCM_UNSIGNED
|
||||
return new javax.sound.sampled.AudioFormat(
|
||||
!fmt.containsKey(SignedKey) || fmt.get(SignedKey) ? Encoding.PCM_SIGNED : Encoding.PCM_UNSIGNED,
|
||||
fmt.get(SampleRateKey).floatValue(),
|
||||
fmt.get(SampleSizeInBitsKey, 16),
|
||||
fmt.get(ChannelsKey, 1),
|
||||
fmt.containsKey(FrameSizeKey) ? fmt.get(FrameSizeKey) : (fmt.get(SampleSizeInBitsKey, 16) + 7) / 8 * fmt.get(ChannelsKey, 1),
|
||||
fmt.containsKey(FrameRateKey) ? fmt.get(FrameRateKey).floatValue() : fmt.get(SampleRateKey).floatValue(),
|
||||
fmt.containsKey(ByteOrderKey) ? fmt.get(ByteOrderKey) == ByteOrder.BIG_ENDIAN : true);
|
||||
}
|
||||
}
|
||||
164
libsrc/avi/src/org/monte/media/Buffer.java
Normal file
164
libsrc/avi/src/org/monte/media/Buffer.java
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.monte.media;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.monte.media.math.Rational;
|
||||
import org.monte.media.util.Methods;
|
||||
|
||||
/**
|
||||
* A {@code Buffer} carries media data from one media processing unit to another.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version 1.0 2011-03-12 Created.
|
||||
*/
|
||||
public class Buffer {
|
||||
|
||||
/** A flag mask that describes the boolean attributes for this buffer.
|
||||
*/
|
||||
public EnumSet<BufferFlag> flags = EnumSet.noneOf(BufferFlag.class);
|
||||
/** Values which are not specified must have this value. */
|
||||
public static final int NOT_SPECIFIED = -1;
|
||||
/** The track number.
|
||||
* This can be set to NOT_SPECIFIED or to a number >= 0.
|
||||
*/
|
||||
public int track;
|
||||
/** Header information, such as RTP header for this chunk. */
|
||||
public Object header;
|
||||
/** The media data. */
|
||||
public Object data;
|
||||
/** The data offset. This field is only used if {@code data} is an array. */
|
||||
public int offset;
|
||||
/** The data length. This field is only used if {@code data} is an array. */
|
||||
public int length;
|
||||
/** Duration of a sample in seconds.
|
||||
* Multiply this with {@code sampleCount} to get the buffer duration.
|
||||
*/
|
||||
public Rational sampleDuration;
|
||||
/** The time stamp of this buffer in seconds. */
|
||||
public Rational timeStamp;
|
||||
/** The format of the data in this buffer. */
|
||||
public Format format;
|
||||
/** The number of samples in the data field. */
|
||||
public int sampleCount = 1;
|
||||
|
||||
/** Sequence number of the buffer. This can be used for debugging. */
|
||||
public long sequenceNumber;
|
||||
|
||||
/** Sets all variables of this buffer to that buffer except for {@code data},
|
||||
* {@code offset}, {@code length} and {@code header}.
|
||||
*/
|
||||
public void setMetaTo(Buffer that) {
|
||||
this.flags = EnumSet.copyOf(that.flags);
|
||||
//this.data=that.data;
|
||||
//this.offset=that.offset;
|
||||
//this.length=that.length;
|
||||
//this.header=that.header;
|
||||
this.track = that.track;
|
||||
this.sampleDuration = that.sampleDuration;
|
||||
this.timeStamp = that.timeStamp;
|
||||
this.format = that.format;
|
||||
this.sampleCount = that.sampleCount;
|
||||
this.format = that.format;
|
||||
this.sequenceNumber=that.sequenceNumber;
|
||||
}
|
||||
|
||||
/** Sets {@code data}, {@code offset}, {@code length} and {@code header}
|
||||
* of this buffer to that buffer.
|
||||
* Note that this method creates copies of the {@code data} and
|
||||
* {@code header}, so that these fields in that buffer can be discarded
|
||||
* without affecting the contents of this buffer.
|
||||
* <p>
|
||||
* FIXME - This method does not always create a copy!!
|
||||
*/
|
||||
public void setDataTo(Buffer that) {
|
||||
this.offset = that.offset;
|
||||
this.length = that.length;
|
||||
this.data = copy(that.data, this.data);
|
||||
this.header = copy(that.header, this.header);
|
||||
|
||||
}
|
||||
|
||||
private Object copy(Object from, Object into) {
|
||||
if (from instanceof byte[]) {
|
||||
byte[] b=(byte[])from;
|
||||
if (!(into instanceof byte[]) || ((byte[]) into).length < b.length) {
|
||||
into = new byte[b.length];
|
||||
}
|
||||
System.arraycopy(b, 0, (byte[])into, 0, b.length);
|
||||
} else if (from instanceof BufferedImage) {
|
||||
// FIXME - Try to reuse BufferedImage in output!
|
||||
BufferedImage img = (BufferedImage) from;
|
||||
ColorModel cm = img.getColorModel();
|
||||
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
|
||||
WritableRaster raster = img.copyData(null);
|
||||
into = new BufferedImage(cm, raster, isAlphaPremultiplied, null);
|
||||
} else if (from instanceof Cloneable) {
|
||||
try {
|
||||
into=Methods.invoke(from, "clone");
|
||||
} catch (NoSuchMethodException ex) {
|
||||
into=from;
|
||||
}
|
||||
} else {
|
||||
// FIXME - This is very fragile, since we do not know, if the
|
||||
// input data stays valid until the output data is processed!
|
||||
into = from;
|
||||
}
|
||||
|
||||
return into;
|
||||
}
|
||||
|
||||
/** Returns true if the specified flag is set. */
|
||||
public boolean isFlag(BufferFlag flag) {
|
||||
return flags.contains(flag);
|
||||
}
|
||||
|
||||
/** Convenience method for setting a flag. */
|
||||
public void setFlag(BufferFlag flag) {
|
||||
setFlag(flag, true);
|
||||
}
|
||||
|
||||
/** Convenience method for clearing a flag. */
|
||||
public void clearFlag(BufferFlag flag) {
|
||||
setFlag(flag, false);
|
||||
}
|
||||
|
||||
/** Sets or clears the specified flag. */
|
||||
public void setFlag(BufferFlag flag, boolean value) {
|
||||
if (value) {
|
||||
flags.add(flag);
|
||||
} else {
|
||||
flags.remove(flag);
|
||||
}
|
||||
}
|
||||
|
||||
/** Clears all flags, and then sets the specified flag. */
|
||||
public void setFlagsTo(BufferFlag... flags) {
|
||||
if (flags.length == 0) {
|
||||
this.flags = EnumSet.noneOf(BufferFlag.class);
|
||||
} else {
|
||||
this.flags = EnumSet.copyOf(Arrays.asList(flags));
|
||||
}
|
||||
}
|
||||
|
||||
/** Clears all flags, and then sets the specified flag. */
|
||||
public void setFlagsTo(EnumSet<BufferFlag> flags) {
|
||||
if (flags == null) {
|
||||
this.flags = EnumSet.noneOf(BufferFlag.class);
|
||||
} else {
|
||||
this.flags = EnumSet.copyOf(flags);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearFlags() {
|
||||
flags.clear();
|
||||
}
|
||||
}
|
||||
42
libsrc/avi/src/org/monte/media/BufferFlag.java
Normal file
42
libsrc/avi/src/org/monte/media/BufferFlag.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* @(#)BufferFlag.java
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media;
|
||||
|
||||
/**
|
||||
* {@code BufferFlag}.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: BufferFlag.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public enum BufferFlag {
|
||||
|
||||
/** Indicates that the data in this buffer should be ignored. */
|
||||
DISCARD,
|
||||
/** Indicates that this Buffer holds an intra-coded picture, which can be
|
||||
* decoded independently. */
|
||||
KEYFRAME,
|
||||
/** Indicates that the data in this buffer is at the end of the media. */
|
||||
END_OF_MEDIA,
|
||||
/** Indicates that the data in this buffer is used for initializing the
|
||||
* decoding queue.
|
||||
* <p>
|
||||
* This flag is used when the media time of a track is set to a non-keyframe
|
||||
* sample. Thus decoding must start at a keyframe at an earlier time.
|
||||
* <p>
|
||||
* Decoders should decode the buffer.
|
||||
* Encoders and Multiplexers should discard the buffer.
|
||||
*/
|
||||
PREFETCH,
|
||||
/** Indicates that this buffer is known to have the same data as the
|
||||
* previous buffer. This may improve encoding performance.
|
||||
*/
|
||||
SAME_DATA;
|
||||
}
|
||||
73
libsrc/avi/src/org/monte/media/Codec.java
Normal file
73
libsrc/avi/src/org/monte/media/Codec.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.monte.media;
|
||||
|
||||
/**
|
||||
* A {@code Codec} processes a {@code Buffer} and stores the result in another
|
||||
* {@code Buffer}.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version 1.0 2011-03-12 Created.
|
||||
*/
|
||||
public interface Codec {
|
||||
|
||||
/** The codec successfully converted the input to output. */
|
||||
public final static int CODEC_OK = 0;
|
||||
/** The codec could not handle the input. */
|
||||
public final static int CODEC_FAILED = 1;
|
||||
/** The codec did not fully consume the input buffer.
|
||||
* The codec has updated the input buffer to
|
||||
* reflect the amount of data that it has processed.
|
||||
* The codec must be called again with the same input buffer.
|
||||
*/
|
||||
public final static int CODEC_INPUT_NOT_CONSUMED = 2;
|
||||
/** The codec did not fully fill the output buffer.
|
||||
* The codec has updated the output buffer to
|
||||
* reflect the amount of data that it has processed.
|
||||
* The codec must be called again with the same output buffer.
|
||||
*/
|
||||
public final static int CODEC_OUTPUT_NOT_FILLED = 4;
|
||||
|
||||
/** Lists all of the input formats that this codec accepts. */
|
||||
public Format[] getInputFormats();
|
||||
|
||||
/** Lists all of the output formats that this codec can generate
|
||||
* with the provided input format. If the input format is null, returns
|
||||
* all supported output formats.
|
||||
*/
|
||||
public Format[] getOutputFormats(Format input);
|
||||
|
||||
/** Sets the input format.
|
||||
* Returns the format that was actually set. This is the closest format
|
||||
* that the Codec supports. Returns null if the specified format is not
|
||||
* supported and no reasonable match could be found.
|
||||
*/
|
||||
public Format setInputFormat(Format input);
|
||||
|
||||
public Format getInputFormat();
|
||||
|
||||
/** Sets the output format.
|
||||
* Returns the format that was actually set. This is the closest format
|
||||
* that the Codec supports. Returns null if the specified format is not
|
||||
* supported and no reasonable match could be found.
|
||||
*/
|
||||
public Format setOutputFormat(Format output);
|
||||
|
||||
public Format getOutputFormat();
|
||||
|
||||
/** Performs the media processing defined by this codec.
|
||||
* <p>
|
||||
* Copies the data from the input buffer into the output buffer.
|
||||
*
|
||||
* @return A combination of processing flags.
|
||||
*/
|
||||
public int process(Buffer in, Buffer out);
|
||||
|
||||
/** Returns a human readable name of the codec. */
|
||||
public String getName();
|
||||
|
||||
/** Resets the state of the codec. */
|
||||
public void reset();
|
||||
}
|
||||
395
libsrc/avi/src/org/monte/media/DefaultRegistry.java
Normal file
395
libsrc/avi/src/org/monte/media/DefaultRegistry.java
Normal file
@@ -0,0 +1,395 @@
|
||||
/*
|
||||
* @(#)DefaultRegistry.java
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance onlyWith the
|
||||
* license agreement you entered into onlyWith Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import static org.monte.media.VideoFormatKeys.*;
|
||||
import static org.monte.media.AudioFormatKeys.*;
|
||||
|
||||
/**
|
||||
* {@code DefaultRegistry}.
|
||||
* <p>
|
||||
* FIXME - The registry should be read from a file.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: DefaultRegistry.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class DefaultRegistry extends Registry {
|
||||
|
||||
private HashMap<String, LinkedList<RegistryEntry>> codecMap;
|
||||
private HashMap<String, LinkedList<RegistryEntry>> readerMap;
|
||||
private HashMap<String, LinkedList<RegistryEntry>> writerMap;
|
||||
private HashMap<String, Format> fileFormatMap;
|
||||
|
||||
@Override
|
||||
public Format[] getReaderFormats() {
|
||||
return getFileFormats();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Format[] getWriterFormats() {
|
||||
return getFileFormats();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Format[] getFileFormats() {
|
||||
return fileFormatMap.values().toArray(new Format[fileFormatMap.size()]);
|
||||
}
|
||||
|
||||
private static class RegistryEntry {
|
||||
|
||||
Format inputFormat;
|
||||
Format outputFormat;
|
||||
String className;
|
||||
|
||||
public RegistryEntry(Format inputFormat, Format outputFormat, String className) {
|
||||
this.inputFormat = inputFormat;
|
||||
this.outputFormat = outputFormat;
|
||||
this.className = className;
|
||||
}
|
||||
}
|
||||
|
||||
public DefaultRegistry() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
codecMap = new HashMap<String, LinkedList<RegistryEntry>>();
|
||||
readerMap = new HashMap<String, LinkedList<RegistryEntry>>();
|
||||
writerMap = new HashMap<String, LinkedList<RegistryEntry>>();
|
||||
fileFormatMap = new HashMap<String, Format>();
|
||||
|
||||
// IFF ANIM
|
||||
// --------
|
||||
putCodec(
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_BUFFERED_IMAGE),
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_ANIM, EncodingKey, ENCODING_BITMAP_IMAGE),
|
||||
"org.monte.media.anim.BitmapCodec");
|
||||
|
||||
// AVI
|
||||
// --------
|
||||
putBidiCodec(
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_BUFFERED_IMAGE),
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI, EncodingKey, ENCODING_AVI_DIB),
|
||||
"org.monte.media.avi.DIBCodec");
|
||||
|
||||
putBidiCodec(
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_BUFFERED_IMAGE),
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI, EncodingKey, ENCODING_AVI_MJPG),
|
||||
"org.monte.media.jpeg.JPEGCodec");
|
||||
|
||||
putCodec(
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_BUFFERED_IMAGE),
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI, EncodingKey, ENCODING_AVI_PNG),
|
||||
"org.monte.media.png.PNGCodec");
|
||||
|
||||
putCodec(
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_BUFFERED_IMAGE),
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI, EncodingKey, ENCODING_AVI_RLE),
|
||||
"org.monte.media.avi.RunLengthCodec");
|
||||
|
||||
putBidiCodec(
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI, EncodingKey, ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE),
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_BUFFERED_IMAGE),
|
||||
"org.monte.media.avi.TechSmithCodec");
|
||||
|
||||
putCodec(
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI, EncodingKey, ENCODING_AVI_DOSBOX_SCREEN_CAPTURE),
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_BUFFERED_IMAGE),
|
||||
"org.monte.media.avi.ZMBVCodec");
|
||||
|
||||
putBidiCodec(
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_PCM_SIGNED),
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_AVI, EncodingKey, ENCODING_AVI_PCM),
|
||||
"org.monte.media.avi.AVIPCMAudioCodec");
|
||||
putBidiCodec(
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_PCM_UNSIGNED),
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_AVI, EncodingKey, ENCODING_AVI_PCM),
|
||||
"org.monte.media.avi.AVIPCMAudioCodec");
|
||||
|
||||
// QuickTime
|
||||
// --------
|
||||
putCodec(
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_BUFFERED_IMAGE),
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_QUICKTIME, EncodingKey, ENCODING_QUICKTIME_RAW),
|
||||
"org.monte.media.quicktime.RawCodec");
|
||||
|
||||
putCodec(
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_BUFFERED_IMAGE),
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_QUICKTIME, EncodingKey, ENCODING_QUICKTIME_ANIMATION),
|
||||
"org.monte.media.quicktime.AnimationCodec");
|
||||
|
||||
putBidiCodec(
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_BUFFERED_IMAGE),
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_QUICKTIME, EncodingKey, ENCODING_QUICKTIME_JPEG),
|
||||
"org.monte.media.jpeg.JPEGCodec");
|
||||
putBidiCodec(
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_BUFFERED_IMAGE),
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI, EncodingKey, ENCODING_AVI_MJPG),
|
||||
"org.monte.media.jpeg.JPEGCodec");
|
||||
|
||||
putCodec(
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_BUFFERED_IMAGE),
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_QUICKTIME, EncodingKey, ENCODING_QUICKTIME_PNG),
|
||||
"org.monte.media.png.PNGCodec");
|
||||
|
||||
putBidiCodec(
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_QUICKTIME,
|
||||
EncodingKey, ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE, CompressorNameKey, COMPRESSOR_NAME_AVI_TECHSMITH_SCREEN_CAPTURE),
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_BUFFERED_IMAGE),
|
||||
"org.monte.media.avi.TechSmithCodec");
|
||||
|
||||
putCodec(
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_PCM_SIGNED),
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_QUICKTIME, EncodingKey, ENCODING_QUICKTIME_TWOS_PCM),
|
||||
"org.monte.media.quicktime.QuickTimePCMAudioCodec");
|
||||
putCodec(
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_PCM_UNSIGNED),
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_QUICKTIME, EncodingKey, ENCODING_QUICKTIME_TWOS_PCM),
|
||||
"org.monte.media.quicktime.QuickTimePCMAudioCodec");
|
||||
|
||||
putCodec(
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_PCM_SIGNED),
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_QUICKTIME, EncodingKey, ENCODING_QUICKTIME_SOWT_PCM),
|
||||
"org.monte.media.quicktime.QuickTimePCMAudioCodec");
|
||||
putCodec(
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_PCM_UNSIGNED),
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_QUICKTIME, EncodingKey, ENCODING_QUICKTIME_SOWT_PCM),
|
||||
"org.monte.media.quicktime.QuickTimePCMAudioCodec");
|
||||
|
||||
putBidiCodec(
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_PCM_SIGNED),
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_QUICKTIME, EncodingKey, ENCODING_QUICKTIME_IN24_PCM),
|
||||
"org.monte.media.quicktime.QuickTimePCMAudioCodec");
|
||||
putBidiCodec(
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_PCM_UNSIGNED),
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_QUICKTIME, EncodingKey, ENCODING_QUICKTIME_IN24_PCM),
|
||||
"org.monte.media.quicktime.QuickTimePCMAudioCodec");
|
||||
|
||||
putBidiCodec(
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_PCM_SIGNED),
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_QUICKTIME, EncodingKey, ENCODING_QUICKTIME_IN32_PCM),
|
||||
"org.monte.media.quicktime.QuickTimePCMAudioCodec");
|
||||
putBidiCodec(
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_PCM_UNSIGNED),
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_QUICKTIME, EncodingKey, ENCODING_QUICKTIME_IN32_PCM),
|
||||
"org.monte.media.quicktime.QuickTimePCMAudioCodec");
|
||||
|
||||
putBidiCodec(
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_PCM_SIGNED),
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_QUICKTIME, EncodingKey, ENCODING_QUICKTIME_RAW_PCM),
|
||||
"org.monte.media.quicktime.QuickTimePCMAudioCodec");
|
||||
putBidiCodec(
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_JAVA, EncodingKey, ENCODING_PCM_UNSIGNED),
|
||||
new Format(MediaTypeKey, MediaType.AUDIO, MimeTypeKey, MIME_QUICKTIME, EncodingKey, ENCODING_QUICKTIME_RAW_PCM),
|
||||
"org.monte.media.quicktime.QuickTimePCMAudioCodec");
|
||||
|
||||
|
||||
putReader(new Format(MediaTypeKey, MediaType.FILE, MimeTypeKey, MIME_AVI), "org.monte.media.avi.AVIReader");
|
||||
putReader(new Format(MediaTypeKey, MediaType.FILE, MimeTypeKey, MIME_QUICKTIME), "org.monte.media.quicktime.QuickTimeReader");
|
||||
putReader(new Format(MediaTypeKey, MediaType.FILE, MimeTypeKey, MIME_ANIM), "org.monte.media.anim.ANIMReader");
|
||||
putWriter(new Format(MediaTypeKey, MediaType.FILE, MimeTypeKey, MIME_AVI), "org.monte.media.avi.AVIWriter");
|
||||
putWriter(new Format(MediaTypeKey, MediaType.FILE, MimeTypeKey, MIME_QUICKTIME), "org.monte.media.quicktime.QuickTimeWriter");
|
||||
putWriter(new Format(MediaTypeKey, MediaType.FILE, MimeTypeKey, MIME_ANIM), "org.monte.media.anim.ANIMWriter");
|
||||
|
||||
putFileFormat("avi", new Format(MediaTypeKey, MediaType.FILE, MimeTypeKey, MIME_AVI));
|
||||
putFileFormat("mov", new Format(MediaTypeKey, MediaType.FILE, MimeTypeKey, MIME_QUICKTIME));
|
||||
putFileFormat("anim", new Format(MediaTypeKey, MediaType.FILE, MimeTypeKey, MIME_ANIM));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param inputFormat Must have {@code MediaTypeKey}, {@code EncodingKey}, {@code MimeTypeKey}.
|
||||
* @param outputFormat Must have {@code MediaTypeKey}, {@code EncodingKey}, {@code MimeTypeKey}.
|
||||
* @param codecClass
|
||||
*/
|
||||
public void putBidiCodec(Format inputFormat, Format outputFormat, String codecClass) {
|
||||
putCodec(inputFormat, outputFormat, codecClass);
|
||||
putCodec(outputFormat, inputFormat, codecClass);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param inputFormat Must have {@code MediaTypeKey}, {@code EncodingKey}, {@code MimeTypeKey}.
|
||||
* @param outputFormat Must have {@code MediaTypeKey}, {@code EncodingKey}, {@code MimeTypeKey}.
|
||||
* @param codecClass
|
||||
*/
|
||||
@Override
|
||||
public void putCodec(Format inputFormat, Format outputFormat, String codecClass) {
|
||||
RegistryEntry entry = new RegistryEntry(inputFormat, outputFormat, codecClass);
|
||||
addCodecEntry(inputFormat.get(EncodingKey), entry);
|
||||
addCodecEntry(outputFormat.get(EncodingKey), entry);
|
||||
}
|
||||
|
||||
private void addCodecEntry(String key, RegistryEntry entry) {
|
||||
LinkedList<RegistryEntry> list = codecMap.get(key);
|
||||
if (list == null) {
|
||||
list = new LinkedList<RegistryEntry>();
|
||||
codecMap.put(key, list);
|
||||
}
|
||||
list.add(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param fileFormat Must have {@code MediaTypeKey}, {@code MimeTypeKey}.
|
||||
* @param readerClass
|
||||
*/
|
||||
@Override
|
||||
public void putReader(Format fileFormat, String readerClass) {
|
||||
RegistryEntry entry = new RegistryEntry(null, fileFormat, readerClass);
|
||||
String key = fileFormat.get(MimeTypeKey);
|
||||
LinkedList<RegistryEntry> list = readerMap.get(key);
|
||||
if (list == null) {
|
||||
list = new LinkedList<RegistryEntry>();
|
||||
readerMap.put(key, list);
|
||||
}
|
||||
list.add(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param fileFormat Must have {@code MediaTypeKey}, {@code MimeTypeKey}.
|
||||
* @param writerClass
|
||||
*/
|
||||
@Override
|
||||
public void putWriter(Format fileFormat, String writerClass) {
|
||||
RegistryEntry entry = new RegistryEntry(fileFormat, null, writerClass);
|
||||
String key = fileFormat.get(MimeTypeKey);
|
||||
LinkedList<RegistryEntry> list = writerMap.get(key);
|
||||
if (list == null) {
|
||||
list = new LinkedList<RegistryEntry>();
|
||||
writerMap.put(key, list);
|
||||
}
|
||||
list.add(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getCodecClasses(Format inputFormat, Format outputFormat) {
|
||||
HashSet<String> classNames = new HashSet<String>();
|
||||
HashSet<RegistryEntry> entries = new HashSet<RegistryEntry>();
|
||||
if (inputFormat != null) {
|
||||
LinkedList<RegistryEntry> re;
|
||||
if (inputFormat.get(EncodingKey) == null) {
|
||||
re = new LinkedList<RegistryEntry>();
|
||||
for (Map.Entry<String, LinkedList<RegistryEntry>> i : codecMap.entrySet()) {
|
||||
for (RegistryEntry j : i.getValue()) {
|
||||
if (inputFormat.matches(j.inputFormat)) {
|
||||
re.add(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
re = codecMap.get(inputFormat.get(EncodingKey));
|
||||
}
|
||||
if (re != null) {
|
||||
entries.addAll(re);
|
||||
}
|
||||
}
|
||||
if (outputFormat != null) {
|
||||
LinkedList<RegistryEntry> re;
|
||||
if (outputFormat.get(EncodingKey) == null) {
|
||||
re = new LinkedList<RegistryEntry>();
|
||||
for (Map.Entry<String, LinkedList<RegistryEntry>> i : codecMap.entrySet()) {
|
||||
for (RegistryEntry j : i.getValue()) {
|
||||
if (outputFormat.matches(j.outputFormat)) {
|
||||
re.add(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
re = codecMap.get(outputFormat.get(EncodingKey));
|
||||
}
|
||||
if (re != null) {
|
||||
entries.addAll(re);
|
||||
}
|
||||
}
|
||||
for (RegistryEntry e : entries) {
|
||||
if ((inputFormat == null || e.inputFormat == null || inputFormat.matches(e.inputFormat))
|
||||
&& (outputFormat == null || e.outputFormat == null || outputFormat.matches(e.outputFormat))) {
|
||||
classNames.add(e.className);
|
||||
}
|
||||
}
|
||||
return classNames.toArray(new String[classNames.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getReaderClasses(Format fileFormat) {
|
||||
LinkedList<RegistryEntry> rr = readerMap.get(fileFormat.get(MimeTypeKey));
|
||||
String[] names = new String[rr == null ? 0 : rr.size()];
|
||||
if (rr != null) {
|
||||
int i = 0;
|
||||
for (RegistryEntry e : rr) {
|
||||
names[i++] = e.className;
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Format getFileFormat(File file) {
|
||||
String ext = file.getName();
|
||||
int p = ext.lastIndexOf('.');
|
||||
if (p != -1) {
|
||||
ext = ext.substring(p + 1);
|
||||
}
|
||||
ext = ext.toLowerCase();
|
||||
return fileFormatMap.get(ext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getWriterClasses(Format fileFormat) {
|
||||
LinkedList<RegistryEntry> rr = writerMap.get(fileFormat.get(MimeTypeKey));
|
||||
String[] names = new String[rr == null ? 0 : rr.size()];
|
||||
if (rr != null) {
|
||||
int i = 0;
|
||||
for (RegistryEntry e : rr) {
|
||||
names[i++] = e.className;
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putFileFormat(String extension, Format format) {
|
||||
fileFormatMap.put(extension.toLowerCase(), format);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExtension(Format ff) {
|
||||
for (Map.Entry<String, Format> e : fileFormatMap.entrySet()) {
|
||||
if (e.getValue().get(MimeTypeKey).equals(ff.get(MimeTypeKey))) {
|
||||
return e.getKey();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterCodec(String codecClass) {
|
||||
for (Map.Entry<String, LinkedList<RegistryEntry>> i:codecMap.entrySet()) {
|
||||
LinkedList<RegistryEntry> ll=i.getValue();
|
||||
for (Iterator<RegistryEntry> j=ll.iterator();j.hasNext();) {
|
||||
RegistryEntry e=j.next();
|
||||
if (e.className.equals(codecClass)) {
|
||||
j.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
325
libsrc/avi/src/org/monte/media/Format.java
Normal file
325
libsrc/avi/src/org/monte/media/Format.java
Normal file
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* @(#)Format.java
|
||||
*
|
||||
* Copyright (c) 2011-2012 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance onlyWith the
|
||||
* license agreement you entered into onlyWith Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Specifies the format of a media, for example of audio and video.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: Format.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class Format {
|
||||
|
||||
/**
|
||||
* Holds the properties of the format.
|
||||
*/
|
||||
private HashMap<FormatKey, Object> properties;
|
||||
|
||||
/**
|
||||
* Creates a new format onlyWith the specified properties.
|
||||
*/
|
||||
public Format(Map<FormatKey, Object> properties) {
|
||||
this(properties, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new format onlyWith the specified properties.
|
||||
*/
|
||||
private Format(Map<FormatKey, Object> properties, boolean copy) {
|
||||
if (copy || ! (properties instanceof HashMap)) {
|
||||
for (Map.Entry<FormatKey, Object> e : properties.entrySet()) {
|
||||
if (!e.getKey().isAssignable(e.getValue())) {
|
||||
throw new ClassCastException(e.getValue() + " must be of type " + e.getKey().getValueClass());
|
||||
}
|
||||
}
|
||||
this.properties = new HashMap< FormatKey, Object>(properties);
|
||||
} else {
|
||||
this.properties = (HashMap< FormatKey, Object>) properties;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new format onlyWith the specified properties. The properties
|
||||
* must be given as key value pairs.
|
||||
*/
|
||||
public Format(Object... p) {
|
||||
this.properties = new HashMap< FormatKey, Object>();
|
||||
for (int i = 0; i < p.length; i += 2) {
|
||||
FormatKey key = (FormatKey) p[i];
|
||||
if (!key.isAssignable(p[i + 1])) {
|
||||
throw new ClassCastException(key + ": " + p[i + 1] + " must be of type " + key.getValueClass());
|
||||
}
|
||||
this.properties.put(key, p[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T get(FormatKey<T> key) {
|
||||
return (T) properties.get(key);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T get(FormatKey<T> key, T defaultValue) {
|
||||
return (properties.containsKey(key)) ? (T) properties.get(key) : defaultValue;
|
||||
}
|
||||
|
||||
public boolean containsKey(FormatKey key) {
|
||||
return properties.containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the properties of the format as an unmodifiable map.
|
||||
*/
|
||||
public Map<FormatKey, Object> getProperties() {
|
||||
return Collections.unmodifiableMap(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the keys of the format as an unmodifiable set.
|
||||
*/
|
||||
public Set<FormatKey> getKeys() {
|
||||
return Collections.unmodifiableSet(properties.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if that format matches this format. That is iff all
|
||||
* properties defined in both format objects are identical. Properties which
|
||||
* are only defined in one of the format objects are not considered.
|
||||
*
|
||||
* @param that Another format.
|
||||
* @return True if the other format matches this format.
|
||||
*/
|
||||
public boolean matches(Format that) {
|
||||
for (Map.Entry<FormatKey, Object> e : properties.entrySet()) {
|
||||
if (!e.getKey().isComment()) {
|
||||
if (that.properties.containsKey(e.getKey())) {
|
||||
Object a = e.getValue();
|
||||
Object b = that.properties.get(e.getKey());
|
||||
if (a != b && a == null || !a.equals(b)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean matchesWithout(Format that, FormatKey... without) {
|
||||
OuterLoop:
|
||||
for (Map.Entry<FormatKey, Object> e : properties.entrySet()) {
|
||||
FormatKey k = e.getKey();
|
||||
if (!e.getKey().isComment()) {
|
||||
if (that.properties.containsKey(k)) {
|
||||
for (int i = 0; i < without.length; i++) {
|
||||
if (without[i] == k) {
|
||||
continue OuterLoop;
|
||||
}
|
||||
}
|
||||
Object a = e.getValue();
|
||||
Object b = that.properties.get(k);
|
||||
if (a != b && a == null || !a.equals(b)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new format which contains all properties from this format and
|
||||
* additional properties from that format. <p> If a property is specified in
|
||||
* both formats, then the property value from this format is used. It
|
||||
* overwrites that format. <p> If one of the format has more properties than
|
||||
* the other, then the new format is more specific than this format.
|
||||
*
|
||||
* @param that
|
||||
* @return That format with properties overwritten by this format.
|
||||
*/
|
||||
public Format append(Format that) {
|
||||
HashMap<FormatKey, Object> m = new HashMap<FormatKey, Object>(this.properties);
|
||||
for (Map.Entry<FormatKey, Object> e : that.properties.entrySet()) {
|
||||
if (!m.containsKey(e.getKey())) {
|
||||
m.put(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
return new Format(m,false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new format which contains all properties from this format and
|
||||
* additional properties listed. <p> If a property is specified in both
|
||||
* formats, then the property value from this format is used. It overwrites
|
||||
* that format. <p> If one of the format has more properties than the other,
|
||||
* then the new format is more specific than this format.
|
||||
*
|
||||
* @param p The properties must be given as key value pairs.
|
||||
* @return That format with properties overwritten by this format.
|
||||
*/
|
||||
public Format append(Object... p) {
|
||||
HashMap<FormatKey, Object> m = new HashMap<FormatKey, Object>(this.properties);
|
||||
for (int i = 0; i < p.length; i += 2) {
|
||||
FormatKey key = (FormatKey) p[i];
|
||||
if (!key.isAssignable(p[i + 1])) {
|
||||
throw new ClassCastException(key + ": " + p[i + 1] + " must be of type " + key.getValueClass());
|
||||
}
|
||||
m.put(key, p[i + 1]);
|
||||
}
|
||||
return new Format(m,false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new format which contains all properties from the specified
|
||||
* format and additional properties from this format.
|
||||
* <p> If a property is specified in both formats, then the property value
|
||||
* from this format is used. It overwrites that format.
|
||||
* <p> If one of the format has more properties than the other, then the new
|
||||
* format is more specific than this format.
|
||||
*
|
||||
* @param that
|
||||
* @return That format with properties overwritten by this format.
|
||||
*/
|
||||
public Format prepend(Format that) {
|
||||
HashMap<FormatKey, Object> m = new HashMap<FormatKey, Object>(that.properties);
|
||||
for (Map.Entry<FormatKey, Object> e : this.properties.entrySet()) {
|
||||
if (!m.containsKey(e.getKey())) {
|
||||
m.put(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
return new Format(m,false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new format which contains all specified properties and
|
||||
* additional properties from this format.
|
||||
* <p> If a property is specified in both formats, then the property value
|
||||
* from this format is used. It overwrites that format.
|
||||
* <p> If one of the format has more properties than the other, then the new
|
||||
* format is more specific than this format.
|
||||
*
|
||||
* @param p The properties must be given as key value pairs.
|
||||
* @return That format with properties overwritten by this format.
|
||||
*/
|
||||
public Format prepend(Object... p) {
|
||||
HashMap<FormatKey, Object> m = new HashMap<FormatKey, Object>();
|
||||
for (int i = 0; i < p.length; i += 2) {
|
||||
FormatKey key = (FormatKey) p[i];
|
||||
if (!key.isAssignable(p[i + 1])) {
|
||||
throw new ClassCastException(key + ": " + p[i + 1] + " must be of type " + key.getValueClass());
|
||||
}
|
||||
m.put(key, p[i + 1]);
|
||||
}
|
||||
for (Map.Entry<FormatKey, Object> e : this.properties.entrySet()) {
|
||||
if (!m.containsKey(e.getKey())) {
|
||||
m.put(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
return new Format(m,false);
|
||||
}
|
||||
/**
|
||||
* Creates a new format which only has the specified keys (or less). <p> If
|
||||
* the keys are reduced, then the new format is less specific than this
|
||||
* format.
|
||||
*/
|
||||
public Format intersectKeys(FormatKey... keys) {
|
||||
HashMap<FormatKey, Object> m = new HashMap<FormatKey, Object>();
|
||||
for (FormatKey k : keys) {
|
||||
if (properties.containsKey(k)) {
|
||||
m.put(k, properties.get(k));
|
||||
}
|
||||
}
|
||||
return new Format(m,false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new format without the specified keys. <p> If the keys are
|
||||
* reduced, then the new format is less specific than this format.
|
||||
*/
|
||||
public Format removeKeys(FormatKey... keys) {
|
||||
boolean needsRemoval = false;
|
||||
for (FormatKey k : keys) {
|
||||
if (properties.containsKey(k)) {
|
||||
needsRemoval = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!needsRemoval) {
|
||||
return this;
|
||||
}
|
||||
|
||||
HashMap<FormatKey, Object> m = new HashMap<FormatKey, Object>(properties);
|
||||
for (FormatKey k : keys) {
|
||||
m.remove(k);
|
||||
}
|
||||
return new Format(m,false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the format has the specified keys.
|
||||
*/
|
||||
public Format containsKeys(FormatKey... keys) {
|
||||
HashMap<FormatKey, Object> m = new HashMap<FormatKey, Object>(properties);
|
||||
for (FormatKey k : keys) {
|
||||
m.remove(k);
|
||||
}
|
||||
return new Format(m,false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder("Format{");
|
||||
boolean isFirst = true;
|
||||
for (Map.Entry<FormatKey, Object> e : properties.entrySet()) {
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
} else {
|
||||
buf.append(',');
|
||||
}
|
||||
buf.append(e.getKey().toString());
|
||||
buf.append(':');
|
||||
appendStuffedString(e.getValue(), buf);
|
||||
}
|
||||
buf.append('}');
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used by #toString.
|
||||
*/
|
||||
private static void appendStuffedString(Object value, StringBuilder stuffed) {
|
||||
if (value == null) {
|
||||
stuffed.append("null");
|
||||
}
|
||||
value = value.toString();
|
||||
if (value instanceof String) {
|
||||
for (char ch : ((String) value).toCharArray()) {
|
||||
if (ch >= ' ') {
|
||||
stuffed.append(ch);
|
||||
} else {
|
||||
String hex = Integer.toHexString(ch);
|
||||
stuffed.append("\\u");
|
||||
for (int i = hex.length(); i < 4; i++) {
|
||||
stuffed.append('0');
|
||||
}
|
||||
stuffed.append(hex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
112
libsrc/avi/src/org/monte/media/FormatKey.java
Normal file
112
libsrc/avi/src/org/monte/media/FormatKey.java
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* @(#)FormatKey.java
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* A <em>FormatKey</em> provides type-safe access to an attribute of
|
||||
* a {@link Format}.
|
||||
* <p>
|
||||
* A format key has a name, a type and a value.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: FormatKey.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class FormatKey<T> implements Serializable, Comparable {
|
||||
|
||||
public static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* Holds a String representation of the attribute key.
|
||||
*/
|
||||
private String key;
|
||||
/**
|
||||
* Holds a pretty name. This can be null, if the value is self-explaining.
|
||||
*/
|
||||
private String name;
|
||||
/** This variable is used as a "type token" so that we can check for
|
||||
* assignability of attribute values at runtime.
|
||||
*/
|
||||
private Class<T> clazz;
|
||||
|
||||
/** Comment keys are ignored when matching two media formats with each other. */
|
||||
private boolean comment;
|
||||
|
||||
/** Creates a new instance with the specified attribute key, type token class,
|
||||
* default value null, and allowing null values. */
|
||||
public FormatKey(String key, Class<T> clazz) {
|
||||
this(key, key, clazz);
|
||||
}
|
||||
|
||||
/** Creates a new instance with the specified attribute key, type token class,
|
||||
* default value null, and allowing null values. */
|
||||
public FormatKey(String key, String name, Class<T> clazz) {
|
||||
this(key,name,clazz,false);
|
||||
}
|
||||
/** Creates a new instance with the specified attribute key, type token class,
|
||||
* default value null, and allowing null values. */
|
||||
public FormatKey(String key, String name, Class<T> clazz, boolean comment) {
|
||||
this.key = key;
|
||||
this.name = name;
|
||||
this.clazz = clazz;
|
||||
this.comment=comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key string.
|
||||
* @return key string.
|
||||
*/
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pretty name string.
|
||||
* @return name string.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** Returns the key string. */
|
||||
@Override
|
||||
public String toString() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified value is assignable with this key.
|
||||
*
|
||||
* @param value
|
||||
* @return True if assignable.
|
||||
*/
|
||||
public boolean isAssignable(Object value) {
|
||||
return clazz.isInstance(value);
|
||||
}
|
||||
|
||||
public boolean isComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
|
||||
public Class getValueClass() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Object o) {
|
||||
return compareTo((FormatKey) o);
|
||||
}
|
||||
|
||||
public int compareTo(FormatKey that) {
|
||||
return this.key.compareTo(that.key);
|
||||
}
|
||||
}
|
||||
61
libsrc/avi/src/org/monte/media/FormatKeys.java
Normal file
61
libsrc/avi/src/org/monte/media/FormatKeys.java
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* @(#)FormatKeys.java
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media;
|
||||
|
||||
import org.monte.media.math.Rational;
|
||||
|
||||
/**
|
||||
* Defines common {@code FormatKey}'s.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: FormatKeys.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class FormatKeys {
|
||||
public static enum MediaType {
|
||||
AUDIO,
|
||||
VIDEO,
|
||||
MIDI,
|
||||
TEXT,
|
||||
META,
|
||||
FILE
|
||||
}
|
||||
/**
|
||||
* The media MediaTypeKey.
|
||||
*/
|
||||
public final static FormatKey<MediaType> MediaTypeKey = new FormatKey<MediaType>("mediaType", MediaType.class);
|
||||
/**
|
||||
* The EncodingKey.
|
||||
*/
|
||||
public final static FormatKey<String> EncodingKey = new FormatKey<String>("encoding", String.class);
|
||||
|
||||
//
|
||||
public final static String MIME_AVI = "video/avi";
|
||||
public final static String MIME_QUICKTIME = "video/quicktime";
|
||||
public final static String MIME_MP4 = "video/mp4";
|
||||
public final static String MIME_JAVA = "Java";
|
||||
public final static String MIME_ANIM = "x-iff/anim";
|
||||
public final static String MIME_IMAGE_SEQUENCE = "ImageSequence";
|
||||
/**
|
||||
* The mime type.
|
||||
*/
|
||||
public final static FormatKey<String> MimeTypeKey = new FormatKey<String>("mimeType", String.class);
|
||||
/**
|
||||
* The number of frames per second.
|
||||
*/
|
||||
public final static FormatKey<Rational> FrameRateKey = new FormatKey<Rational>("frameRate", Rational.class);
|
||||
|
||||
/**
|
||||
* The interval between key frames.
|
||||
* If this value is not specified, most codecs will use {@code FrameRateKey}
|
||||
* as a hint and try to produce one key frame per second.
|
||||
*/
|
||||
public final static FormatKey<Integer> KeyFrameIntervalKey = new FormatKey<Integer>("keyFrameInterval", Integer.class);
|
||||
}
|
||||
93
libsrc/avi/src/org/monte/media/MovieReader.java
Normal file
93
libsrc/avi/src/org/monte/media/MovieReader.java
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* @(#)MovieReader.java
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media;
|
||||
|
||||
import org.monte.media.math.Rational;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A simple API for reading movie data (audio and video) from a file.
|
||||
*
|
||||
* <p>
|
||||
* FIXME - MovieReader should extend Demultiplexer
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: MovieReader.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public interface MovieReader {
|
||||
/** Returns the number of tracks. */
|
||||
public int getTrackCount() throws IOException;
|
||||
|
||||
/** Finds a track with the specified format.
|
||||
*
|
||||
* @param fromTrack the start track number.
|
||||
* @param format A format specification.
|
||||
* @return The track number >= fromTrack or -1 if no track has been found.
|
||||
*/
|
||||
public int findTrack(int fromTrack, Format format) throws IOException;
|
||||
|
||||
/** Returns the total duration of the movie . */
|
||||
public Rational getDuration() throws IOException;
|
||||
/** Returns the duration of the specified track. */
|
||||
public Rational getDuration(int track) throws IOException;
|
||||
|
||||
/** Returns the sample number for the specified time. */
|
||||
public long timeToSample(int track, Rational seconds) throws IOException;
|
||||
/** Returns the time for the specified sample number. */
|
||||
public Rational sampleToTime(int track, long sample) throws IOException;
|
||||
|
||||
/** Returns the file format. */
|
||||
public Format getFileFormat() throws IOException;
|
||||
|
||||
/** Returns the media format of the specified track.
|
||||
*
|
||||
* @param track Track number.
|
||||
* @return The media format of the track.
|
||||
*/
|
||||
public Format getFormat(int track) throws IOException;
|
||||
|
||||
/** Returns the number of media data chunks in the specified track.
|
||||
* A chunk contains one or more samples.
|
||||
*/
|
||||
public long getChunkCount(int track) throws IOException;
|
||||
|
||||
/** Reads the next sample chunk from the specified track.
|
||||
*
|
||||
* @param track Track number.
|
||||
* @param buffer The buffer into which to store the sample data.
|
||||
*/
|
||||
public void read(int track, Buffer buffer) throws IOException;
|
||||
/** Reads the next sample chunk from the next track in playback sequence.
|
||||
* The variable buffer.track contains the track number.
|
||||
*
|
||||
* @param buf The buffer into which to store the sample data.
|
||||
*/
|
||||
//public void read(Buffer buffer) throws IOException;
|
||||
|
||||
/** Returns the index of the next track in playback sequence.
|
||||
*
|
||||
* @return Index of next track or -1 if end of media reached.
|
||||
*/
|
||||
public int nextTrack() throws IOException;
|
||||
|
||||
public void close() throws IOException;
|
||||
|
||||
/** Sets the read time of all tracks to the closest sync sample before or
|
||||
* at the specified time.
|
||||
*
|
||||
* @param newValue Time in seconds.
|
||||
*/
|
||||
public void setMovieReadTime(Rational newValue) throws IOException;
|
||||
|
||||
/** Returns the current time of the track. */
|
||||
public Rational getReadTime(int track) throws IOException;
|
||||
|
||||
}
|
||||
82
libsrc/avi/src/org/monte/media/MovieWriter.java
Normal file
82
libsrc/avi/src/org/monte/media/MovieWriter.java
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* @(#)MovieWriter.java
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media;
|
||||
|
||||
import org.monte.media.math.Rational;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A simple API for writing movie data (audio and video) into a file.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: MovieWriter.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public interface MovieWriter extends Multiplexer {
|
||||
/** Returns the file format. */
|
||||
public Format getFileFormat() throws IOException;
|
||||
|
||||
/** Adds a track to the writer for a suggested input format.
|
||||
* <p>
|
||||
* The format should at least specify the desired {@link FormatKeys.MediaType}.
|
||||
* The actual input format is a refined version of the suggested format. For
|
||||
* example, if a MovieWriter only supports fixed frame rate video, then the
|
||||
* MovieWriter will extend the format with that information.
|
||||
* <p>
|
||||
* If the suggested input format is not compatible, then an IOException is
|
||||
* thrown. For example, if a MovieWriter only supports fixed frame rate video,
|
||||
* but a format with variable frame rate was requested.
|
||||
*
|
||||
* @param format The desired input format of the track. The actual input
|
||||
* format may be a refined version of the specified format.
|
||||
* @return The track number.
|
||||
*/
|
||||
public int addTrack(Format format) throws IOException;
|
||||
|
||||
/** Returns the media format of the specified track.
|
||||
* This is a refined version of the format that was requested when the
|
||||
* track was added. See {@link #addTrack}.
|
||||
*
|
||||
* @param track Track number.
|
||||
* @return The media format of the track.
|
||||
*/
|
||||
public Format getFormat(int track);
|
||||
|
||||
/** Returns the number of tracks. */
|
||||
public int getTrackCount();
|
||||
|
||||
/** Writes a sample into the specified track.
|
||||
* Does nothing if the discard-flag in the buffer is set to true.
|
||||
*
|
||||
* @param track The track number.
|
||||
* @param buf The buffer containing the sample data.
|
||||
*/
|
||||
@Override
|
||||
public void write(int track, Buffer buf) throws IOException;
|
||||
|
||||
/** Closes the writer. */
|
||||
@Override
|
||||
public void close() throws IOException;
|
||||
|
||||
/** Returns true if the limit for media data has been reached.
|
||||
* If this limit is reached, no more samples should be added to the movie.
|
||||
* <p>
|
||||
* This limit is imposed by data structures of the movie file
|
||||
* which will overflow if more samples are added to the movie.
|
||||
* <p>
|
||||
* FIXME - Maybe replace by getCapacity():long.
|
||||
*/
|
||||
public boolean isDataLimitReached();
|
||||
|
||||
/** Returns the duration of the track in seconds. */
|
||||
public Rational getDuration(int track);
|
||||
/** Returns true if the specified track has no samples. */
|
||||
public boolean isEmpty(int track);
|
||||
}
|
||||
34
libsrc/avi/src/org/monte/media/Multiplexer.java
Normal file
34
libsrc/avi/src/org/monte/media/Multiplexer.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* @(#)Multiplexer.java 1.0 2011-02-19
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
|
||||
package org.monte.media;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A {@code Multiplexer} can write multiple media tracks into a
|
||||
* single output stream.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version 1.0 2011-02-19 Created.
|
||||
*/
|
||||
public interface Multiplexer {
|
||||
/** Writes a sample.
|
||||
* Does nothing if the discard-flag in the buffer is set to true.
|
||||
*
|
||||
* @param track The track number.
|
||||
* @param buf The buffer containing the sample data.
|
||||
*/
|
||||
public void write(int track, Buffer buf) throws IOException;
|
||||
|
||||
/** Closes the Multiplexer. */
|
||||
public void close() throws IOException;
|
||||
}
|
||||
30
libsrc/avi/src/org/monte/media/ParseException.java
Normal file
30
libsrc/avi/src/org/monte/media/ParseException.java
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* @(#)ParseException.java
|
||||
*
|
||||
* Copyright (c) 1999-2012 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media;
|
||||
|
||||
/**
|
||||
* Exception thrown by IFFParse.
|
||||
*
|
||||
* @author Werner Randelshofer, Hausmatt 10, CH-6405 Goldau, Switzerland
|
||||
* @version $Id: ParseException.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class ParseException extends Exception {
|
||||
|
||||
public static final long serialVersionUID = 1L;
|
||||
|
||||
public ParseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ParseException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
310
libsrc/avi/src/org/monte/media/Registry.java
Normal file
310
libsrc/avi/src/org/monte/media/Registry.java
Normal file
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* @(#)Registry.java
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import static org.monte.media.FormatKeys.*;
|
||||
|
||||
/**
|
||||
* The {@code Registry} for audio and video codecs.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: Registry.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public abstract class Registry {
|
||||
|
||||
private static Registry instance;
|
||||
|
||||
public static Registry getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new DefaultRegistry();
|
||||
instance.init();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the registry.
|
||||
*/
|
||||
protected abstract void init();
|
||||
|
||||
/**
|
||||
* Puts a codec into the registry.
|
||||
*
|
||||
* @param inputFormat The input format. Must not be null.
|
||||
* @param outputFormat The output format. Must not be null.
|
||||
* @param codecClass The codec class name. Must not be null.
|
||||
*/
|
||||
public abstract void putCodec(Format inputFormat, Format outputFormat, String codecClass);
|
||||
|
||||
/**
|
||||
* Gets all codecs which can decode the specified format.
|
||||
*
|
||||
* @param format The format.
|
||||
* @return An array of codec class names. If no codec was found, an empty
|
||||
* array is returned.
|
||||
*/
|
||||
public final String[] getDecoderClasses(Format format) {
|
||||
return getCodecClasses(format, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all codecs which can decode the specified format.
|
||||
*
|
||||
* @param format The format.
|
||||
* @return An array of codec class names. If no codec was found, an empty
|
||||
* array is returned.
|
||||
*/
|
||||
public final String[] getEncoderClasses(Format format) {
|
||||
return getCodecClasses(null, format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all codecs which can transcode from the specified input format to
|
||||
* the specified output format.
|
||||
*
|
||||
* @param inputFormat The input format.
|
||||
* @param outputFormat The output format.
|
||||
* @return An array of codec class names. If no codec was found, an empty
|
||||
* array is returned.
|
||||
*/
|
||||
public abstract String[] getCodecClasses(//
|
||||
Format inputFormat,
|
||||
Format outputFormat);
|
||||
|
||||
/**
|
||||
* Gets all codecs which can decode the specified format.
|
||||
*
|
||||
* @param inputFormat The input format.
|
||||
* @return An array of codec class names. If no codec was found, an empty
|
||||
* array is returned.
|
||||
*/
|
||||
public final Codec[] getDecoders(Format inputFormat) {
|
||||
return getCodecs(inputFormat, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first codec which can decode the specified format.
|
||||
*
|
||||
* @param inputFormat The output format.
|
||||
* @return A codec. Returns null if no codec was found.
|
||||
*/
|
||||
public Codec getDecoder(Format inputFormat) {
|
||||
return getCodec(inputFormat, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all codecs which can encode the specified format.
|
||||
*
|
||||
* @param outputFormat The output format.
|
||||
* @return An array of codecs. If no codec was found, an empty array is
|
||||
* returned.
|
||||
*/
|
||||
public final Codec[] getEncoders(Format outputFormat) {
|
||||
return getCodecs(null, outputFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first codec which can encode the specified foramt.
|
||||
*
|
||||
* @param outputFormat The output format.
|
||||
* @return A codec. Returns null if no codec was found.
|
||||
*/
|
||||
public Codec getEncoder(Format outputFormat) {
|
||||
return getCodec(null, outputFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all codecs which can transcode from the specified input format to
|
||||
* the specified output format.
|
||||
*
|
||||
* @param inputFormat The input format.
|
||||
* @param outputFormat The output format.
|
||||
* @return An array of codec class names. If no codec was found, an empty
|
||||
* array is returned.
|
||||
*/
|
||||
public Codec[] getCodecs(Format inputFormat, Format outputFormat) {
|
||||
String[] clazz = getCodecClasses(inputFormat, outputFormat);
|
||||
ArrayList<Codec> codecs = new ArrayList<Codec>(clazz.length);
|
||||
for (int i = 0; i < clazz.length; i++) {
|
||||
try {
|
||||
codecs.add((Codec) Class.forName(clazz[i]).newInstance());
|
||||
} catch (Exception ex) {
|
||||
//ex.printStackTrace();
|
||||
System.err.println("Monte Registry. Codec class not found: " + clazz[i]);
|
||||
unregisterCodec(clazz[i]);
|
||||
}
|
||||
}
|
||||
return codecs.toArray(new Codec[codecs.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a codec which can transcode from the specified input format to the
|
||||
* specified output format.
|
||||
*
|
||||
* @param inputFormat The input format.
|
||||
* @param outputFormat The output format.
|
||||
* @return A codec or null.
|
||||
*/
|
||||
public Codec getCodec(Format inputFormat, Format outputFormat) {
|
||||
String[] clazz = getCodecClasses(inputFormat, outputFormat);
|
||||
for (int i = 0; i < clazz.length; i++) {
|
||||
try {
|
||||
Codec codec = ((Codec) Class.forName(clazz[i]).newInstance());
|
||||
codec.setInputFormat(inputFormat);
|
||||
if (outputFormat != null) {
|
||||
codec.setOutputFormat(outputFormat);
|
||||
}
|
||||
return codec;
|
||||
} catch (Exception ex) {
|
||||
//ex.printStackTrace();
|
||||
System.err.println("Monte Registry. Codec class not found: " + clazz[i]);
|
||||
unregisterCodec(clazz[i]);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a reader into the registry.
|
||||
*
|
||||
* @param fileFormat The file format, e.g."video/avi", "video/quicktime".
|
||||
* Use "Java" for formats which are not tied to a file format. Must not be
|
||||
* null.
|
||||
* @param readerClass The reader class name. Must not be null.
|
||||
*/
|
||||
public abstract void putReader(Format fileFormat, String readerClass);
|
||||
|
||||
/**
|
||||
* Puts a writer into the registry.
|
||||
*
|
||||
* @param fileFormat The file format, e.g."video/avi", "video/quicktime".
|
||||
* Use "Java" for formats which are not tied to a file format. Must not be
|
||||
* null.
|
||||
* @param writerClass The writer class name. Must not be null.
|
||||
*/
|
||||
public abstract void putWriter(Format fileFormat, String writerClass);
|
||||
|
||||
/**
|
||||
* Gets all reader class names from the registry for the specified file
|
||||
* format.
|
||||
*
|
||||
* @param fileFormat The file format, e.g."AVI", "QuickTime".
|
||||
* @return The reader class names.
|
||||
*/
|
||||
public abstract String[] getReaderClasses(Format fileFormat);
|
||||
|
||||
/**
|
||||
* Gets all writer class names from the registry for the specified file
|
||||
* format.
|
||||
*
|
||||
* @param fileFormat The file format, e.g."AVI", "QuickTime".
|
||||
* @return The writer class names.
|
||||
*/
|
||||
public abstract String[] getWriterClasses(Format fileFormat);
|
||||
|
||||
public MovieReader getReader(Format fileFormat, File file) {
|
||||
String[] clazz = getReaderClasses(fileFormat);
|
||||
for (int i = 0; i < clazz.length; i++) {
|
||||
try {
|
||||
return ((MovieReader) Class.forName(clazz[i]).getConstructor(File.class).newInstance(file));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public MovieWriter getWriter(File file) {
|
||||
Format format = getFileFormat(file);
|
||||
return format == null ? null : getWriter(format, file);
|
||||
}
|
||||
|
||||
public MovieWriter getWriter(Format fileFormat, File file) {
|
||||
String[] clazz = getWriterClasses(fileFormat);
|
||||
for (int i = 0; i < clazz.length; i++) {
|
||||
try {
|
||||
return ((MovieWriter) Class.forName(clazz[i]).getConstructor(File.class).newInstance(file));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public MovieReader getReader(File file) {
|
||||
Format format = getFileFormat(file);
|
||||
return format == null ? null : getReader(format, file);
|
||||
}
|
||||
|
||||
public abstract void putFileFormat(String extension, Format format);
|
||||
|
||||
public abstract Format getFileFormat(File file);
|
||||
|
||||
public abstract Format[] getReaderFormats();
|
||||
|
||||
public abstract Format[] getWriterFormats();
|
||||
|
||||
public abstract Format[] getFileFormats();
|
||||
|
||||
public abstract String getExtension(Format ff);
|
||||
|
||||
/**
|
||||
* Suggests output formats for the given input media format and specified
|
||||
* file format.
|
||||
*
|
||||
* @param inputMediaFormat
|
||||
* @param outputFileFormat
|
||||
* @return List of output media formats.
|
||||
*/
|
||||
public ArrayList<Format> suggestOutputFormats(Format inputMediaFormat, Format outputFileFormat) {
|
||||
ArrayList<Format> formats = new ArrayList<Format>();
|
||||
Format matchFormat = new Format(//
|
||||
MimeTypeKey, outputFileFormat.get(MimeTypeKey),//
|
||||
MediaTypeKey, inputMediaFormat.get(MediaTypeKey));
|
||||
Codec[] codecs = getEncoders(matchFormat);
|
||||
int matchingCount = 0;
|
||||
for (Codec c : codecs) {
|
||||
for (Format mf : c.getOutputFormats(null)) {
|
||||
if (mf.matches(matchFormat)) {
|
||||
if (inputMediaFormat.matchesWithout(mf, MimeTypeKey)) {
|
||||
// add matching formats first
|
||||
formats.add(0, mf.append(inputMediaFormat));
|
||||
matchingCount++;
|
||||
} else if (inputMediaFormat.matchesWithout(mf, MimeTypeKey, EncodingKey)) {
|
||||
// add formats which match everything but the encoding second
|
||||
formats.add(matchingCount, mf.append(inputMediaFormat));
|
||||
} else {
|
||||
// add remaining formats last
|
||||
formats.add(mf.append(inputMediaFormat));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove duplicates
|
||||
for (int i = formats.size() - 1; i >= 0; i--) {
|
||||
Format fi = formats.get(i);
|
||||
for (int j = i - 1; j >= 0; j--) {
|
||||
Format fj = formats.get(j);
|
||||
if (fi.matches(fj)) {
|
||||
formats.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return formats;
|
||||
}
|
||||
|
||||
public abstract void unregisterCodec(String codecClass);
|
||||
}
|
||||
77
libsrc/avi/src/org/monte/media/VideoFormatKeys.java
Normal file
77
libsrc/avi/src/org/monte/media/VideoFormatKeys.java
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* @(#)VideoFormatKeys.java
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media;
|
||||
|
||||
import org.monte.media.math.Rational;
|
||||
|
||||
/**
|
||||
* Defines common format keys for video media.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: VideoFormatKeys.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class VideoFormatKeys extends FormatKeys {
|
||||
// Standard video ENCODING strings for use with FormatKey.Encoding.
|
||||
public static final String ENCODING_BUFFERED_IMAGE = "image";
|
||||
/** Cinepak format. */
|
||||
public static final String ENCODING_QUICKTIME_CINEPAK = "cvid";
|
||||
public static final String COMPRESSOR_NAME_QUICKTIME_CINEPAK = "Cinepak";
|
||||
/** JPEG format. */
|
||||
public static final String ENCODING_QUICKTIME_JPEG = "jpeg";
|
||||
public static final String COMPRESSOR_NAME_QUICKTIME_JPEG = "Photo - JPEG";
|
||||
/** PNG format. */
|
||||
public static final String ENCODING_QUICKTIME_PNG = "png ";
|
||||
public static final String COMPRESSOR_NAME_QUICKTIME_PNG = "PNG";
|
||||
/** Animation format. */
|
||||
public static final String ENCODING_QUICKTIME_ANIMATION = "rle ";
|
||||
public static final String COMPRESSOR_NAME_QUICKTIME_ANIMATION = "Animation";
|
||||
/** Raw format. */
|
||||
public static final String ENCODING_QUICKTIME_RAW = "raw ";
|
||||
public static final String COMPRESSOR_NAME_QUICKTIME_RAW = "NONE";
|
||||
// AVI Formats
|
||||
/** Microsoft Device Independent Bitmap (DIB) format. */
|
||||
public static final String ENCODING_AVI_DIB = "DIB ";
|
||||
/** Microsoft Run Length format. */
|
||||
public static final String ENCODING_AVI_RLE = "RLE ";
|
||||
/** Techsmith Screen Capture format. */
|
||||
public static final String ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE = "tscc";
|
||||
public static final String COMPRESSOR_NAME_AVI_TECHSMITH_SCREEN_CAPTURE = "Techsmith Screen Capture";
|
||||
/** DosBox Screen Capture format. */
|
||||
public static final String ENCODING_AVI_DOSBOX_SCREEN_CAPTURE = "ZMBV";
|
||||
/** JPEG format. */
|
||||
public static final String ENCODING_AVI_MJPG = "MJPG";
|
||||
/** PNG format. */
|
||||
public static final String ENCODING_AVI_PNG = "png ";
|
||||
/** Interleaved planar bitmap format. */
|
||||
public static final String ENCODING_BITMAP_IMAGE = "ILBM";
|
||||
|
||||
//
|
||||
|
||||
/** The WidthKey of a video frame. */
|
||||
public final static FormatKey<Integer> WidthKey = new FormatKey<Integer>("dimX","width", Integer.class);
|
||||
/** The HeightKey of a video frame. */
|
||||
public final static FormatKey<Integer> HeightKey = new FormatKey<Integer>("dimY","height", Integer.class);
|
||||
/** The number of bits per pixel. */
|
||||
public final static FormatKey<Integer> DepthKey = new FormatKey<Integer>("dimZ","depth", Integer.class);
|
||||
/** The data class. */
|
||||
public final static FormatKey<Class> DataClassKey = new FormatKey<Class>("dataClass", Class.class);
|
||||
/** The compressor name. */
|
||||
public final static FormatKey<String> CompressorNameKey = new FormatKey<String>("compressorName", "compressorName",String.class, true);
|
||||
/** The pixel aspect ratio WidthKey : HeightKey;
|
||||
*/
|
||||
public final static FormatKey<Rational> PixelAspectRatioKey = new FormatKey<Rational>("pixelAspectRatio", Rational.class);
|
||||
/** Whether the frame rate must be fixed. False means variable frame rate. */
|
||||
public final static FormatKey<Boolean> FixedFrameRateKey = new FormatKey<Boolean>("fixedFrameRate", Boolean.class);
|
||||
/** Whether the video is interlaced. */
|
||||
public final static FormatKey<Boolean> InterlaceKey = new FormatKey<Boolean>("interlace", Boolean.class);
|
||||
/** Encoding quality. Value between 0 and 1. */
|
||||
public final static FormatKey<Float> QualityKey = new FormatKey<Float>("quality", Float.class);
|
||||
}
|
||||
106
libsrc/avi/src/org/monte/media/avi/AVIBMPDIB.java
Normal file
106
libsrc/avi/src/org/monte/media/avi/AVIBMPDIB.java
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* @(#)AVIBMPDIB.java 1.0 2009-12-30
|
||||
*
|
||||
* Copyright (c) 2009 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media.avi;
|
||||
|
||||
import org.monte.media.io.ImageInputStreamAdapter;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.SequenceInputStream;
|
||||
import java.util.*;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.stream.MemoryCacheImageInputStream;
|
||||
|
||||
/**
|
||||
* This class defines the JPEG Huffman table, which is omitted in AVI MJPEG
|
||||
* files.
|
||||
* <p>
|
||||
* Source:
|
||||
* Microsoft Windows Bitmap Format.
|
||||
* Multimedia Technical Note: JPEG DIB Format.
|
||||
* (c) 1993 Microsoft Corporation. All rights reserved.
|
||||
* <a href="http://www.fileformat.info/format/bmp/spec/b7c72ebab8064da48ae5ed0c053c67a4/BMPDIB.TXT">BMPDIB.txt</a>
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version 1.0 2009-12-30 Created.
|
||||
*/
|
||||
public class AVIBMPDIB {
|
||||
|
||||
/** MJPG DHT Segment */
|
||||
private static byte[] MJPGDHTSeg = {
|
||||
/* JPEG DHT Segment for YCrCb omitted from MJPG data */
|
||||
(byte) 0xFF, (byte) 0xC4, (byte) 0x01, (byte) 0xA2,
|
||||
(byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x05, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
|
||||
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0A, (byte) 0x0B, (byte) 0x01,
|
||||
(byte) 0x00, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
|
||||
(byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0A, (byte) 0x0B, (byte) 0x10, (byte) 0x00,
|
||||
(byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x03, (byte) 0x02, (byte) 0x04, (byte) 0x03, (byte) 0x05, (byte) 0x05, (byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x7D,
|
||||
(byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x00, (byte) 0x04, (byte) 0x11, (byte) 0x05, (byte) 0x12, (byte) 0x21, (byte) 0x31, (byte) 0x41, (byte) 0x06, (byte) 0x13, (byte) 0x51, (byte) 0x61,
|
||||
(byte) 0x07, (byte) 0x22, (byte) 0x71, (byte) 0x14, (byte) 0x32, (byte) 0x81, (byte) 0x91, (byte) 0xA1, (byte) 0x08, (byte) 0x23, (byte) 0x42, (byte) 0xB1, (byte) 0xC1, (byte) 0x15, (byte) 0x52,
|
||||
(byte) 0xD1, (byte) 0xF0, (byte) 0x24, (byte) 0x33, (byte) 0x62, (byte) 0x72, (byte) 0x82, (byte) 0x09, (byte) 0x0A, (byte) 0x16, (byte) 0x17, (byte) 0x18, (byte) 0x19, (byte) 0x1A, (byte) 0x25,
|
||||
(byte) 0x26, (byte) 0x27, (byte) 0x28, (byte) 0x29, (byte) 0x2A, (byte) 0x34, (byte) 0x35, (byte) 0x36, (byte) 0x37, (byte) 0x38, (byte) 0x39, (byte) 0x3A, (byte) 0x43, (byte) 0x44, (byte) 0x45,
|
||||
(byte) 0x46, (byte) 0x47, (byte) 0x48, (byte) 0x49, (byte) 0x4A, (byte) 0x53, (byte) 0x54, (byte) 0x55, (byte) 0x56, (byte) 0x57, (byte) 0x58, (byte) 0x59, (byte) 0x5A, (byte) 0x63, (byte) 0x64,
|
||||
(byte) 0x65, (byte) 0x66, (byte) 0x67, (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x83,
|
||||
(byte) 0x84, (byte) 0x85, (byte) 0x86, (byte) 0x87, (byte) 0x88, (byte) 0x89, (byte) 0x8A, (byte) 0x92, (byte) 0x93, (byte) 0x94, (byte) 0x95, (byte) 0x96, (byte) 0x97, (byte) 0x98, (byte) 0x99,
|
||||
(byte) 0x9A, (byte) 0xA2, (byte) 0xA3, (byte) 0xA4, (byte) 0xA5, (byte) 0xA6, (byte) 0xA7, (byte) 0xA8, (byte) 0xA9, (byte) 0xAA, (byte) 0xB2, (byte) 0xB3, (byte) 0xB4, (byte) 0xB5, (byte) 0xB6,
|
||||
(byte) 0xB7, (byte) 0xB8, (byte) 0xB9, (byte) 0xBA, (byte) 0xC2, (byte) 0xC3, (byte) 0xC4, (byte) 0xC5, (byte) 0xC6, (byte) 0xC7, (byte) 0xC8, (byte) 0xC9, (byte) 0xCA, (byte) 0xD2, (byte) 0xD3,
|
||||
(byte) 0xD4, (byte) 0xD5, (byte) 0xD6, (byte) 0xD7, (byte) 0xD8, (byte) 0xD9, (byte) 0xDA, (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, (byte) 0xE8,
|
||||
(byte) 0xE9, (byte) 0xEA, (byte) 0xF1, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0xF7, (byte) 0xF8, (byte) 0xF9, (byte) 0xFA, (byte) 0x11, (byte) 0x00, (byte) 0x02,
|
||||
(byte) 0x01, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x03, (byte) 0x04, (byte) 0x07, (byte) 0x05, (byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x77, (byte) 0x00,
|
||||
(byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x11, (byte) 0x04, (byte) 0x05, (byte) 0x21, (byte) 0x31, (byte) 0x06, (byte) 0x12, (byte) 0x41, (byte) 0x51, (byte) 0x07, (byte) 0x61, (byte) 0x71,
|
||||
(byte) 0x13, (byte) 0x22, (byte) 0x32, (byte) 0x81, (byte) 0x08, (byte) 0x14, (byte) 0x42, (byte) 0x91, (byte) 0xA1, (byte) 0xB1, (byte) 0xC1, (byte) 0x09, (byte) 0x23, (byte) 0x33, (byte) 0x52,
|
||||
(byte) 0xF0, (byte) 0x15, (byte) 0x62, (byte) 0x72, (byte) 0xD1, (byte) 0x0A, (byte) 0x16, (byte) 0x24, (byte) 0x34, (byte) 0xE1, (byte) 0x25, (byte) 0xF1, (byte) 0x17, (byte) 0x18, (byte) 0x19,
|
||||
(byte) 0x1A, (byte) 0x26, (byte) 0x27, (byte) 0x28, (byte) 0x29, (byte) 0x2A, (byte) 0x35, (byte) 0x36, (byte) 0x37, (byte) 0x38, (byte) 0x39, (byte) 0x3A, (byte) 0x43, (byte) 0x44, (byte) 0x45,
|
||||
(byte) 0x46, (byte) 0x47, (byte) 0x48, (byte) 0x49, (byte) 0x4A, (byte) 0x53, (byte) 0x54, (byte) 0x55, (byte) 0x56, (byte) 0x57, (byte) 0x58, (byte) 0x59, (byte) 0x5A, (byte) 0x63, (byte) 0x64,
|
||||
(byte) 0x65, (byte) 0x66, (byte) 0x67, (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x82,
|
||||
(byte) 0x83, (byte) 0x84, (byte) 0x85, (byte) 0x86, (byte) 0x87, (byte) 0x88, (byte) 0x89, (byte) 0x8A, (byte) 0x92, (byte) 0x93, (byte) 0x94, (byte) 0x95, (byte) 0x96, (byte) 0x97, (byte) 0x98,
|
||||
(byte) 0x99, (byte) 0x9A, (byte) 0xA2, (byte) 0xA3, (byte) 0xA4, (byte) 0xA5, (byte) 0xA6, (byte) 0xA7, (byte) 0xA8, (byte) 0xA9, (byte) 0xAA, (byte) 0xB2, (byte) 0xB3, (byte) 0xB4, (byte) 0xB5,
|
||||
(byte) 0xB6, (byte) 0xB7, (byte) 0xB8, (byte) 0xB9, (byte) 0xBA, (byte) 0xC2, (byte) 0xC3, (byte) 0xC4, (byte) 0xC5, (byte) 0xC6, (byte) 0xC7, (byte) 0xC8, (byte) 0xC9, (byte) 0xCA, (byte) 0xD2,
|
||||
(byte) 0xD3, (byte) 0xD4, (byte) 0xD5, (byte) 0xD6, (byte) 0xD7, (byte) 0xD8, (byte) 0xD9, (byte) 0xDA, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, (byte) 0xE8,
|
||||
(byte) 0xE9, (byte) 0xEA, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0xF7, (byte) 0xF8, (byte) 0xF9, (byte) 0xFA
|
||||
};
|
||||
/** JFIF Start of Image (SOI) segment. */
|
||||
private static byte[] JFIFSOISeg = {
|
||||
(byte) 0xff,
|
||||
(byte) 0xd8
|
||||
};
|
||||
|
||||
public static InputStream prependDHTSeg(byte[] jpgWithoutDHT) {
|
||||
return prependDHTSeg(jpgWithoutDHT, 0, jpgWithoutDHT.length);
|
||||
}
|
||||
public static InputStream prependDHTSeg(byte[] jpgWithoutDHT, int offset, int length) {
|
||||
|
||||
// FIXME - Only add DHT Segment if none is present
|
||||
|
||||
Vector<InputStream> v = new Vector<InputStream>();
|
||||
v.add(new ByteArrayInputStream(JFIFSOISeg));
|
||||
v.add(new ByteArrayInputStream(MJPGDHTSeg));
|
||||
v.add(new ByteArrayInputStream(jpgWithoutDHT,offset+JFIFSOISeg.length,length-JFIFSOISeg.length));
|
||||
return new SequenceInputStream(v.elements());
|
||||
}
|
||||
|
||||
public static ImageInputStream prependDHTSeg(ImageInputStream iisWithoutDHT) throws IOException {
|
||||
Vector<InputStream> v = new Vector<InputStream>();
|
||||
v.add(new ByteArrayInputStream(JFIFSOISeg));
|
||||
v.add(new ByteArrayInputStream(MJPGDHTSeg));
|
||||
iisWithoutDHT.seek(2);// skip JFIF SOI
|
||||
v.add(new ImageInputStreamAdapter(iisWithoutDHT));
|
||||
return new MemoryCacheImageInputStream(new SequenceInputStream(v.elements()));
|
||||
}
|
||||
public static ImageInputStream prependDHTSeg(InputStream inWithoutDHT) throws IOException {
|
||||
Vector<InputStream> v = new Vector<InputStream>();
|
||||
v.add(new ByteArrayInputStream(JFIFSOISeg));
|
||||
v.add(new ByteArrayInputStream(MJPGDHTSeg));
|
||||
inWithoutDHT.skip(2);// skip JFIF SOI
|
||||
v.add(inWithoutDHT);
|
||||
return new MemoryCacheImageInputStream(new SequenceInputStream(v.elements()));
|
||||
}
|
||||
}
|
||||
1117
libsrc/avi/src/org/monte/media/avi/AVIOutputStream.java
Normal file
1117
libsrc/avi/src/org/monte/media/avi/AVIOutputStream.java
Normal file
File diff suppressed because it is too large
Load Diff
517
libsrc/avi/src/org/monte/media/avi/AVIWriter.java
Normal file
517
libsrc/avi/src/org/monte/media/avi/AVIWriter.java
Normal file
@@ -0,0 +1,517 @@
|
||||
/**
|
||||
* @(#)AVIWriter.java
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland. All rights
|
||||
* reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance onlyWith the
|
||||
* license agreement you entered into onlyWith Werner Randelshofer. For details
|
||||
* see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media.avi;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import org.monte.media.math.Rational;
|
||||
import org.monte.media.Format;
|
||||
import org.monte.media.Codec;
|
||||
import org.monte.media.Buffer;
|
||||
import org.monte.media.MovieWriter;
|
||||
import org.monte.media.Registry;
|
||||
import org.monte.media.io.ByteArrayImageOutputStream;
|
||||
import org.monte.media.riff.RIFFParser;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.io.*;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Arrays;
|
||||
import javax.imageio.stream.*;
|
||||
import static org.monte.media.AudioFormatKeys.*;
|
||||
import static org.monte.media.VideoFormatKeys.*;
|
||||
import org.monte.media.BufferFlag;
|
||||
import static org.monte.media.BufferFlag.*;
|
||||
|
||||
/**
|
||||
* Provides high-level support for encoding and writing audio and video samples
|
||||
* into an AVI 1.0 file.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: AVIWriter.java 306 2013-01-04 16:19:29Z werner $
|
||||
*/
|
||||
public class AVIWriter extends AVIOutputStream implements MovieWriter {
|
||||
|
||||
public final static Format AVI = new Format(MediaTypeKey, MediaType.FILE, MimeTypeKey, MIME_AVI);
|
||||
public final static Format VIDEO_RAW = new Format(
|
||||
MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI,
|
||||
EncodingKey, ENCODING_AVI_DIB, CompressorNameKey, COMPRESSOR_NAME_QUICKTIME_RAW);
|
||||
public final static Format VIDEO_JPEG = new Format(
|
||||
MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI,
|
||||
EncodingKey, ENCODING_AVI_MJPG, CompressorNameKey, COMPRESSOR_NAME_QUICKTIME_RAW);
|
||||
public final static Format VIDEO_PNG = new Format(
|
||||
MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI,
|
||||
EncodingKey, ENCODING_AVI_PNG, CompressorNameKey, COMPRESSOR_NAME_QUICKTIME_RAW);
|
||||
public final static Format VIDEO_RLE = new Format(
|
||||
MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI,
|
||||
EncodingKey, ENCODING_AVI_RLE, CompressorNameKey, COMPRESSOR_NAME_QUICKTIME_RAW);
|
||||
public final static Format VIDEO_SCREEN_CAPTURE = new Format(
|
||||
MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI,
|
||||
EncodingKey, ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE, CompressorNameKey, COMPRESSOR_NAME_QUICKTIME_RAW);
|
||||
|
||||
/**
|
||||
* Creates a new AVI writer.
|
||||
*
|
||||
* @param file the output file
|
||||
*/
|
||||
public AVIWriter(File file) throws IOException {
|
||||
super(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new AVI writer.
|
||||
*
|
||||
* @param out the output stream.
|
||||
*/
|
||||
public AVIWriter(ImageOutputStream out) throws IOException {
|
||||
super(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Format getFileFormat() throws IOException {
|
||||
return AVI;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Format getFormat(int track) {
|
||||
return tracks.get(track).format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the media duration of the track in seconds.
|
||||
*/
|
||||
@Override
|
||||
public Rational getDuration(int track) {
|
||||
Track tr = tracks.get(track);
|
||||
long duration = getMediaDuration(track);
|
||||
return new Rational(duration * tr.scale, tr.rate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a track.
|
||||
*
|
||||
* @param format The format of the track.
|
||||
* @return The track number.
|
||||
*/
|
||||
@Override
|
||||
public int addTrack(Format format) throws IOException {
|
||||
if (format.get(MediaTypeKey) == MediaType.VIDEO) {
|
||||
return addVideoTrack(format);
|
||||
} else {
|
||||
return addAudioTrack(format);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a video track.
|
||||
*
|
||||
* @param format The format of the track.
|
||||
* @return The track number.
|
||||
*/
|
||||
private int addVideoTrack(Format vf) throws IOException {
|
||||
if (!vf.containsKey(EncodingKey)) {
|
||||
throw new IllegalArgumentException("EncodingKey missing in " + vf);
|
||||
}
|
||||
if (!vf.containsKey(FrameRateKey)) {
|
||||
throw new IllegalArgumentException("FrameRateKey missing in " + vf);
|
||||
}
|
||||
if (!vf.containsKey(WidthKey)) {
|
||||
throw new IllegalArgumentException("WidthKey missing in " + vf);
|
||||
}
|
||||
if (!vf.containsKey(HeightKey)) {
|
||||
throw new IllegalArgumentException("HeightKey missing in " + vf);
|
||||
}
|
||||
if (!vf.containsKey(DepthKey)) {
|
||||
throw new IllegalArgumentException("DepthKey missing in " + vf);
|
||||
}
|
||||
int tr = addVideoTrack(vf.get(EncodingKey),
|
||||
vf.get(FrameRateKey).getDenominator(), vf.get(FrameRateKey).getNumerator(),
|
||||
vf.get(WidthKey), vf.get(HeightKey), vf.get(DepthKey),
|
||||
vf.get(FrameRateKey).floor(1).intValue());
|
||||
setCompressionQuality(tr, vf.get(QualityKey, 1.0f));
|
||||
return tr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an audio track.
|
||||
*
|
||||
* @param format The format of the track.
|
||||
* @return The track number.
|
||||
*/
|
||||
private int addAudioTrack(Format format) throws IOException {
|
||||
int waveFormatTag = 0x0001; // WAVE_FORMAT_PCM
|
||||
|
||||
|
||||
long timeScale = 1;
|
||||
long sampleRate = format.get(SampleRateKey, new Rational(41000, 0)).longValue();
|
||||
int numberOfChannels = format.get(ChannelsKey, 1);
|
||||
int sampleSizeInBits = format.get(SampleSizeInBitsKey, 16); //
|
||||
boolean isCompressed = false; // FIXME
|
||||
int frameDuration = 1;
|
||||
int frameSize = format.get(FrameSizeKey, (sampleSizeInBits + 7) / 8 * numberOfChannels);
|
||||
|
||||
|
||||
String enc = format.get(EncodingKey);
|
||||
if (enc == null) {
|
||||
waveFormatTag = 0x0001; // WAVE_FORMAT_PCM
|
||||
} else if (enc.equals(ENCODING_ALAW)) {
|
||||
waveFormatTag = 0x0001; // WAVE_FORMAT_PCM
|
||||
} else if (enc.equals(ENCODING_PCM_SIGNED)) {
|
||||
waveFormatTag = 0x0001; // WAVE_FORMAT_PCM
|
||||
} else if (enc.equals(ENCODING_PCM_UNSIGNED)) {
|
||||
waveFormatTag = 0x0001; // WAVE_FORMAT_PCM
|
||||
} else if (enc.equals(ENCODING_ULAW)) {
|
||||
waveFormatTag = 0x0001; // WAVE_FORMAT_PCM
|
||||
} else if (enc.equals(ENCODING_MP3)) {
|
||||
waveFormatTag = 0x0001; // WAVE_FORMAT_PCM - FIXME
|
||||
} else {
|
||||
waveFormatTag = RIFFParser.stringToID(format.get(EncodingKey)) & 0xffff;
|
||||
}
|
||||
|
||||
return addAudioTrack(waveFormatTag, //
|
||||
timeScale, sampleRate, //
|
||||
numberOfChannels, sampleSizeInBits, //
|
||||
isCompressed, //
|
||||
frameDuration, frameSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the codec of the specified track.
|
||||
*/
|
||||
public Codec getCodec(int track) {
|
||||
return tracks.get(track).codec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the codec for the specified track.
|
||||
*/
|
||||
public void setCodec(int track, Codec codec) {
|
||||
tracks.get(track).codec = codec;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTrackCount() {
|
||||
return tracks.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the provided image and writes its sample data into the specified
|
||||
* track.
|
||||
*
|
||||
* @param track The track index.
|
||||
* @param image The image of the video frame.
|
||||
* @param duration Duration given in media time units.
|
||||
*
|
||||
* @throws IndexOutofBoundsException if the track index is out of bounds.
|
||||
* @throws if the duration is less than 1, or if the dimension of the frame
|
||||
* does not match the dimension of the video.
|
||||
* @throws UnsupportedOperationException if the {@code MovieWriter} does not
|
||||
* have a built-in encoder for this video format.
|
||||
* @throws IOException if writing the sample data failed.
|
||||
*/
|
||||
public void write(int track, BufferedImage image, long duration) throws IOException {
|
||||
ensureStarted();
|
||||
|
||||
VideoTrack vt = (VideoTrack) tracks.get(track);
|
||||
if (vt.codec == null) {
|
||||
createCodec(track);
|
||||
}
|
||||
if (vt.codec == null) {
|
||||
throw new UnsupportedOperationException("No codec for this format: " + vt.format);
|
||||
}
|
||||
|
||||
// The dimension of the image must match the dimension of the video track
|
||||
Format fmt = vt.format;
|
||||
if (fmt.get(WidthKey) != image.getWidth() || fmt.get(HeightKey) != image.getHeight()) {
|
||||
throw new IllegalArgumentException("Dimensions of image[" + vt.samples.size()
|
||||
+ "] (width=" + image.getWidth() + ", height=" + image.getHeight()
|
||||
+ ") differs from video format of track: " + fmt);
|
||||
}
|
||||
|
||||
// Encode pixel data
|
||||
{
|
||||
if (vt.outputBuffer == null) {
|
||||
vt.outputBuffer = new Buffer();
|
||||
}
|
||||
|
||||
boolean isKeyframe = vt.syncInterval == 0 ? false : vt.samples.size() % vt.syncInterval == 0;
|
||||
|
||||
Buffer inputBuffer = new Buffer();
|
||||
inputBuffer.flags = (isKeyframe) ? EnumSet.of(KEYFRAME) : EnumSet.noneOf(BufferFlag.class);
|
||||
inputBuffer.data = image;
|
||||
vt.codec.process(inputBuffer, vt.outputBuffer);
|
||||
if (vt.outputBuffer.flags.contains(DISCARD)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Encode palette data
|
||||
isKeyframe = vt.outputBuffer.flags.contains(KEYFRAME);
|
||||
boolean paletteChange = writePalette(track, image, isKeyframe);
|
||||
writeSample(track, (byte[]) vt.outputBuffer.data, vt.outputBuffer.offset, vt.outputBuffer.length, isKeyframe && !paletteChange);
|
||||
/*
|
||||
long offset = getRelativeStreamPosition();
|
||||
|
||||
DataChunk videoFrameChunk = new DataChunk(vt.getSampleChunkFourCC(isKeyframe));
|
||||
moviChunk.add(videoFrameChunk);
|
||||
videoFrameChunk.getOutputStream().write((byte[]) vt.outputBuffer.data, vt.outputBuffer.offset, vt.outputBuffer.length);
|
||||
videoFrameChunk.finish();
|
||||
long length = getRelativeStreamPosition() - offset;
|
||||
|
||||
Sample s=new Sample(videoFrameChunk.chunkType, 1, offset, length, isKeyframe&&!paletteChange);
|
||||
vt.addSample(s);
|
||||
idx1.add(s);
|
||||
|
||||
if (getRelativeStreamPosition() > 1L << 32) {
|
||||
throw new IOException("AVI file is larger than 4 GB");
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the data provided in the buffer and then writes it into the
|
||||
* specified track. <p> Does nothing if the discard-flag in the buffer is
|
||||
* set to true.
|
||||
*
|
||||
* @param track The track number.
|
||||
* @param buf The buffer containing a data sample.
|
||||
*/
|
||||
@Override
|
||||
public void write(int track, Buffer buf) throws IOException {
|
||||
ensureStarted();
|
||||
if (buf.flags.contains(DISCARD)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Track tr = tracks.get(track);
|
||||
|
||||
boolean isKeyframe = buf.flags.contains(KEYFRAME);
|
||||
if (buf.data instanceof BufferedImage) {
|
||||
if (tr.syncInterval != 0) {
|
||||
isKeyframe = buf.flags.contains(KEYFRAME) | (tr.samples.size() % tr.syncInterval == 0);
|
||||
}
|
||||
}
|
||||
// Encode palette data
|
||||
boolean paletteChange = false;
|
||||
if (buf.data instanceof BufferedImage && tr instanceof VideoTrack) {
|
||||
paletteChange = writePalette(track, (BufferedImage) buf.data, isKeyframe);
|
||||
} else if (buf.header instanceof IndexColorModel) {
|
||||
paletteChange = writePalette(track, (IndexColorModel) buf.header, isKeyframe);
|
||||
}
|
||||
// Encode sample data
|
||||
{
|
||||
if (buf.format == null) {
|
||||
throw new IllegalArgumentException("Buffer.format must not be null");
|
||||
}
|
||||
if (buf.format.matchesWithout(tr.format, FrameRateKey) && buf.data instanceof byte[]) {
|
||||
writeSamples(track, buf.sampleCount, (byte[]) buf.data, buf.offset, buf.length,
|
||||
buf.isFlag(KEYFRAME) && !paletteChange);
|
||||
return;
|
||||
}
|
||||
|
||||
// We got here, because the buffer format does not match the track
|
||||
// format. Lets see if we can create a codec which can perform the
|
||||
// encoding for us.
|
||||
|
||||
if (tr.codec == null) {
|
||||
createCodec(track);
|
||||
if (tr.codec == null) {
|
||||
throw new UnsupportedOperationException("No codec for this format " + tr.format);
|
||||
}
|
||||
}
|
||||
|
||||
if (tr.outputBuffer == null) {
|
||||
tr.outputBuffer = new Buffer();
|
||||
}
|
||||
Buffer outBuf = tr.outputBuffer;
|
||||
if (tr.codec.process(buf, outBuf) != Codec.CODEC_OK) {
|
||||
throw new IOException("Codec failed or could not encode the sample in a single step.");
|
||||
}
|
||||
if (outBuf.isFlag(DISCARD)) {
|
||||
return;
|
||||
}
|
||||
writeSamples(track, outBuf.sampleCount, (byte[]) outBuf.data, outBuf.offset, outBuf.length,
|
||||
isKeyframe && !paletteChange);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean writePalette(int track, BufferedImage image, boolean isKeyframe) throws IOException {
|
||||
if ((image.getColorModel() instanceof IndexColorModel)) {
|
||||
return writePalette(track, (IndexColorModel) image.getColorModel(), isKeyframe);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean writePalette(int track, IndexColorModel imgPalette, boolean isKeyframe) throws IOException {
|
||||
ensureStarted();
|
||||
|
||||
VideoTrack vt = (VideoTrack) tracks.get(track);
|
||||
int imgDepth = vt.bitCount;
|
||||
ByteArrayImageOutputStream tmp = null;
|
||||
boolean paletteChange = false;
|
||||
switch (imgDepth) {
|
||||
case 4: {
|
||||
//IndexColorModel imgPalette = (IndexColorModel) image.getColorModel();
|
||||
int[] imgRGBs = new int[16];
|
||||
imgPalette.getRGBs(imgRGBs);
|
||||
int[] previousRGBs = new int[16];
|
||||
if (vt.previousPalette == null) {
|
||||
vt.previousPalette = vt.palette;
|
||||
}
|
||||
vt.previousPalette.getRGBs(previousRGBs);
|
||||
if (isKeyframe || !Arrays.equals(imgRGBs, previousRGBs)) {
|
||||
paletteChange = true;
|
||||
vt.previousPalette = imgPalette;
|
||||
/*
|
||||
int first = imgPalette.getMapSize();
|
||||
int last = -1;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (previousRGBs[i] != imgRGBs[i] && i < first) {
|
||||
first = i;
|
||||
}
|
||||
if (previousRGBs[i] != imgRGBs[i] && i > last) {
|
||||
last = i;
|
||||
}
|
||||
}*/
|
||||
int first = 0;
|
||||
int last = imgPalette.getMapSize() - 1;
|
||||
/*
|
||||
* typedef struct {
|
||||
BYTE bFirstEntry;
|
||||
BYTE bNumEntries;
|
||||
WORD wFlags;
|
||||
PALETTEENTRY peNew[];
|
||||
} AVIPALCHANGE;
|
||||
*
|
||||
* typedef struct tagPALETTEENTRY {
|
||||
BYTE peRed;
|
||||
BYTE peGreen;
|
||||
BYTE peBlue;
|
||||
BYTE peFlags;
|
||||
} PALETTEENTRY;
|
||||
*/
|
||||
tmp = new ByteArrayImageOutputStream(ByteOrder.LITTLE_ENDIAN);
|
||||
tmp.writeByte(first);//bFirstEntry
|
||||
tmp.writeByte(last - first + 1);//bNumEntries
|
||||
tmp.writeShort(0);//wFlags
|
||||
|
||||
for (int i = first; i <= last; i++) {
|
||||
tmp.writeByte((imgRGBs[i] >>> 16) & 0xff); // red
|
||||
tmp.writeByte((imgRGBs[i] >>> 8) & 0xff); // green
|
||||
tmp.writeByte(imgRGBs[i] & 0xff); // blue
|
||||
tmp.writeByte(0); // reserved*/
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
//IndexColorModel imgPalette = (IndexColorModel) image.getColorModel();
|
||||
int[] imgRGBs = new int[256];
|
||||
imgPalette.getRGBs(imgRGBs);
|
||||
int[] previousRGBs = new int[256];
|
||||
if (vt.previousPalette != null) {
|
||||
vt.previousPalette.getRGBs(previousRGBs);
|
||||
}
|
||||
if (isKeyframe || !Arrays.equals(imgRGBs, previousRGBs)) {
|
||||
paletteChange = true;
|
||||
vt.previousPalette = imgPalette;
|
||||
/*
|
||||
int first = imgPalette.getMapSize();
|
||||
int last = -1;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (previousRGBs[i] != imgRGBs[i] && i < first) {
|
||||
first = i;
|
||||
}
|
||||
if (previousRGBs[i] != imgRGBs[i] && i > last) {
|
||||
last = i;
|
||||
}
|
||||
}*/
|
||||
int first = 0;
|
||||
int last = imgPalette.getMapSize() - 1;
|
||||
/*
|
||||
* typedef struct {
|
||||
BYTE bFirstEntry;
|
||||
BYTE bNumEntries;
|
||||
WORD wFlags;
|
||||
PALETTEENTRY peNew[];
|
||||
} AVIPALCHANGE;
|
||||
*
|
||||
* typedef struct tagPALETTEENTRY {
|
||||
BYTE peRed;
|
||||
BYTE peGreen;
|
||||
BYTE peBlue;
|
||||
BYTE peFlags;
|
||||
} PALETTEENTRY;
|
||||
*/
|
||||
tmp = new ByteArrayImageOutputStream(ByteOrder.LITTLE_ENDIAN);
|
||||
tmp.writeByte(first);//bFirstEntry
|
||||
tmp.writeByte(last - first + 1);//bNumEntries
|
||||
tmp.writeShort(0);//wFlags
|
||||
for (int i = first; i <= last; i++) {
|
||||
tmp.writeByte((imgRGBs[i] >>> 16) & 0xff); // red
|
||||
tmp.writeByte((imgRGBs[i] >>> 8) & 0xff); // green
|
||||
tmp.writeByte(imgRGBs[i] & 0xff); // blue
|
||||
tmp.writeByte(0); // reserved*/
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tmp != null) {
|
||||
tmp.close();
|
||||
writePalette(track, tmp.toByteArray(), 0, (int) tmp.length(), isKeyframe);
|
||||
}
|
||||
return paletteChange;
|
||||
}
|
||||
|
||||
private Codec createCodec(Format fmt) {
|
||||
return Registry.getInstance().getEncoder(fmt.prepend(MimeTypeKey, MIME_AVI));
|
||||
}
|
||||
|
||||
private void createCodec(int track) {
|
||||
Track tr = tracks.get(track);
|
||||
Format fmt = tr.format;
|
||||
tr.codec = createCodec(fmt);
|
||||
String enc = fmt.get(EncodingKey);
|
||||
if (tr.codec != null) {
|
||||
if (fmt.get(MediaTypeKey) == MediaType.VIDEO) {
|
||||
tr.codec.setInputFormat(fmt.prepend(
|
||||
EncodingKey, ENCODING_BUFFERED_IMAGE,
|
||||
DataClassKey, BufferedImage.class));
|
||||
if (null == tr.codec.setOutputFormat(
|
||||
fmt.prepend(FixedFrameRateKey, true,
|
||||
QualityKey, getCompressionQuality(track),
|
||||
MimeTypeKey, MIME_AVI,
|
||||
DataClassKey, byte[].class))) {
|
||||
throw new UnsupportedOperationException("Track " + tr + " codec does not support format " + fmt + ". codec=" + tr.codec);
|
||||
}
|
||||
} else {
|
||||
tr.codec.setInputFormat(null);
|
||||
if (null == tr.codec.setOutputFormat(
|
||||
fmt.prepend(FixedFrameRateKey, true,
|
||||
QualityKey, getCompressionQuality(track),
|
||||
MimeTypeKey, MIME_AVI,
|
||||
DataClassKey, byte[].class))) {
|
||||
throw new UnsupportedOperationException("Track " + tr + " codec " + tr.codec + " does not support format. " + fmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isVFRSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty(int track) {
|
||||
return tracks.get(track).samples.isEmpty();
|
||||
}
|
||||
}
|
||||
1734
libsrc/avi/src/org/monte/media/avi/AbstractAVIStream.java
Normal file
1734
libsrc/avi/src/org/monte/media/avi/AbstractAVIStream.java
Normal file
File diff suppressed because it is too large
Load Diff
343
libsrc/avi/src/org/monte/media/avi/DIBCodec.java
Normal file
343
libsrc/avi/src/org/monte/media/avi/DIBCodec.java
Normal file
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
* @(#)DIBCodec.java
|
||||
*
|
||||
* Copyright © 2011-2012 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media.avi;
|
||||
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import org.monte.media.AbstractVideoCodec;
|
||||
import org.monte.media.Buffer;
|
||||
import org.monte.media.Format;
|
||||
import org.monte.media.io.SeekableByteArrayOutputStream;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import static org.monte.media.VideoFormatKeys.*;
|
||||
import static org.monte.media.BufferFlag.*;
|
||||
|
||||
/**
|
||||
* {@code DIBCodec} encodes a BufferedImage as a Microsoft Device Independent
|
||||
* Bitmap (DIB) into a byte array.
|
||||
* <p>
|
||||
* The DIB codec only works with the AVI file format. Other file formats, such
|
||||
* as QuickTime, use a different encoding for uncompressed video.
|
||||
* <p>
|
||||
* This codec currently only supports encoding from a {@code BufferedImage} into
|
||||
* the file format. Decoding support may be added in the future.
|
||||
* <p>
|
||||
* This codec does not encode the color palette of an image. This must be done
|
||||
* separately.
|
||||
* <p>
|
||||
* The pixels of a frame are written row by row from bottom to top and from
|
||||
* the left to the right. 24-bit pixels are encoded as BGR.
|
||||
* <p>
|
||||
* Supported input formats:
|
||||
* <ul>
|
||||
* {@code Format} with {@code BufferedImage.class}, any width, any height,
|
||||
* depth=4.
|
||||
* </ul>
|
||||
* Supported output formats:
|
||||
* <ul>
|
||||
* {@code Format} with {@code byte[].class}, same width and height as input
|
||||
* format, depth=4.
|
||||
* </ul>
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: DIBCodec.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class DIBCodec extends AbstractVideoCodec {
|
||||
|
||||
public DIBCodec() {
|
||||
super(new Format[]{
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA,
|
||||
EncodingKey, ENCODING_BUFFERED_IMAGE, FixedFrameRateKey, true), //
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI,
|
||||
EncodingKey, ENCODING_AVI_DIB, DataClassKey, byte[].class,
|
||||
FixedFrameRateKey, true, DepthKey, 4), //
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI,
|
||||
EncodingKey, ENCODING_AVI_DIB, DataClassKey, byte[].class,
|
||||
FixedFrameRateKey, true, DepthKey, 8), //
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI,
|
||||
EncodingKey, ENCODING_AVI_DIB, DataClassKey, byte[].class,
|
||||
FixedFrameRateKey, true, DepthKey, 24), //
|
||||
},
|
||||
new Format[]{
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA,
|
||||
EncodingKey, ENCODING_BUFFERED_IMAGE, FixedFrameRateKey, true), //
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI,
|
||||
EncodingKey, ENCODING_AVI_DIB, DataClassKey, byte[].class,
|
||||
FixedFrameRateKey, true, DepthKey, 4), //
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI,
|
||||
EncodingKey, ENCODING_AVI_DIB, DataClassKey, byte[].class,
|
||||
FixedFrameRateKey, true, DepthKey, 8), //
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI,
|
||||
EncodingKey, ENCODING_AVI_DIB, DataClassKey, byte[].class,
|
||||
FixedFrameRateKey, true, DepthKey, 24), //
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int process(Buffer in, Buffer out) {
|
||||
if (outputFormat.get(EncodingKey) == ENCODING_BUFFERED_IMAGE) {
|
||||
return decode(in, out);
|
||||
} else {
|
||||
return encode(in, out);
|
||||
}
|
||||
}
|
||||
|
||||
public int decode(Buffer in, Buffer out) {
|
||||
out.setMetaTo(in);
|
||||
out.format = outputFormat;
|
||||
if (in.isFlag(DISCARD)) {
|
||||
return CODEC_OK;
|
||||
}
|
||||
|
||||
out.sampleCount = 1;
|
||||
BufferedImage img = null;
|
||||
|
||||
int imgType;
|
||||
switch (outputFormat.get(DepthKey)) {
|
||||
case 4:
|
||||
imgType = BufferedImage.TYPE_BYTE_INDEXED;
|
||||
break;
|
||||
case 8:
|
||||
imgType = BufferedImage.TYPE_BYTE_INDEXED;
|
||||
break;
|
||||
case 24:
|
||||
imgType = BufferedImage.TYPE_INT_RGB;
|
||||
break;
|
||||
default:
|
||||
imgType = BufferedImage.TYPE_INT_RGB;
|
||||
break;
|
||||
}
|
||||
|
||||
if (out.data instanceof BufferedImage) {
|
||||
img = (BufferedImage) out.data;
|
||||
// Fixme: Handle sub-image
|
||||
if (img.getWidth() != outputFormat.get(WidthKey)
|
||||
|| img.getHeight() != outputFormat.get(HeightKey)
|
||||
|| img.getType() != imgType) {
|
||||
img = null;
|
||||
}
|
||||
}
|
||||
if (img == null) {
|
||||
img = new BufferedImage(outputFormat.get(WidthKey), outputFormat.get(HeightKey), imgType);
|
||||
}
|
||||
out.data = img;
|
||||
|
||||
switch (outputFormat.get(DepthKey)) {
|
||||
case 4:
|
||||
readKey4((byte[]) in.data, in.offset, in.length, img);
|
||||
break;
|
||||
case 8:
|
||||
readKey8((byte[]) in.data, in.offset, in.length, img);
|
||||
break;
|
||||
case 24:
|
||||
default:
|
||||
readKey24((int[]) in.data, in.offset, in.length, img);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return CODEC_OK;
|
||||
}
|
||||
|
||||
public int encode(Buffer in, Buffer out) {
|
||||
out.setMetaTo(in);
|
||||
out.format = outputFormat;
|
||||
if (in.isFlag(DISCARD)) {
|
||||
return CODEC_OK;
|
||||
}
|
||||
|
||||
SeekableByteArrayOutputStream tmp;
|
||||
if (out.data instanceof byte[]) {
|
||||
tmp = new SeekableByteArrayOutputStream((byte[]) out.data);
|
||||
} else {
|
||||
tmp = new SeekableByteArrayOutputStream();
|
||||
}
|
||||
|
||||
// Handle sub-image
|
||||
// FIXME - Scanline stride must be a multiple of four.
|
||||
Rectangle r;
|
||||
int scanlineStride;
|
||||
if (in.data instanceof BufferedImage) {
|
||||
BufferedImage image = (BufferedImage) in.data;
|
||||
WritableRaster raster = image.getRaster();
|
||||
scanlineStride = raster.getSampleModel().getWidth();
|
||||
r = raster.getBounds();
|
||||
r.x -= raster.getSampleModelTranslateX();
|
||||
r.y -= raster.getSampleModelTranslateY();
|
||||
out.header = image.getColorModel();
|
||||
} else {
|
||||
r = new Rectangle(0, 0, outputFormat.get(WidthKey), outputFormat.get(HeightKey));
|
||||
scanlineStride = outputFormat.get(WidthKey);
|
||||
out.header = null;
|
||||
}
|
||||
|
||||
try {
|
||||
switch (outputFormat.get(DepthKey)) {
|
||||
case 4: {
|
||||
byte[] pixels = getIndexed8(in);
|
||||
if (pixels == null) {
|
||||
out.setFlag(DISCARD);
|
||||
return CODEC_OK;
|
||||
}
|
||||
writeKey4(tmp, pixels, r.width, r.height, r.x + r.y * scanlineStride, scanlineStride);
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
byte[] pixels = getIndexed8(in);
|
||||
if (pixels == null) {
|
||||
out.setFlag(DISCARD);
|
||||
return CODEC_OK;
|
||||
}
|
||||
writeKey8(tmp, pixels, r.width, r.height, r.x + r.y * scanlineStride, scanlineStride);
|
||||
break;
|
||||
}
|
||||
case 24: {
|
||||
int[] pixels = getRGB24(in);
|
||||
if (pixels == null) {
|
||||
out.setFlag(DISCARD);
|
||||
return CODEC_OK;
|
||||
}
|
||||
writeKey24(tmp, pixels, r.width, r.height, r.x + r.y * scanlineStride, scanlineStride);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
out.setFlag(DISCARD);
|
||||
return CODEC_OK;
|
||||
}
|
||||
|
||||
out.setFlag(KEYFRAME);
|
||||
out.data = tmp.getBuffer();
|
||||
out.sampleCount = 1;
|
||||
out.offset = 0;
|
||||
out.length = (int) tmp.getStreamPosition();
|
||||
return CODEC_OK;
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
out.setFlag(DISCARD);
|
||||
return CODEC_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
public void readKey4(byte[] in, int offset, int length, BufferedImage img) {
|
||||
DataBufferByte buf = (DataBufferByte) img.getRaster().getDataBuffer();
|
||||
WritableRaster raster = img.getRaster();
|
||||
int scanlineStride = raster.getSampleModel().getWidth();
|
||||
Rectangle r = raster.getBounds();
|
||||
r.x -= raster.getSampleModelTranslateX();
|
||||
r.y -= raster.getSampleModelTranslateY();
|
||||
|
||||
throw new UnsupportedOperationException("readKey4 not yet implemented");
|
||||
}
|
||||
|
||||
public void readKey8(byte[] in, int offset, int length, BufferedImage img) {
|
||||
DataBufferByte buf = (DataBufferByte) img.getRaster().getDataBuffer();
|
||||
WritableRaster raster = img.getRaster();
|
||||
int scanlineStride = raster.getSampleModel().getWidth();
|
||||
Rectangle r = raster.getBounds();
|
||||
r.x -= raster.getSampleModelTranslateX();
|
||||
r.y -= raster.getSampleModelTranslateY();
|
||||
|
||||
int h=img.getHeight();
|
||||
int w=img.getWidth();
|
||||
int i=offset;
|
||||
int j=r.x+r.y*scanlineStride+(h-1)*scanlineStride;
|
||||
byte[] out=buf.getData();
|
||||
for (int y=0;y<h;y++) {
|
||||
System.arraycopy(in,i,out,j,w);
|
||||
i+=w;
|
||||
j-=scanlineStride;
|
||||
}
|
||||
}
|
||||
|
||||
public void readKey24(int[] in, int offset, int length, BufferedImage img) {
|
||||
DataBufferInt buf = (DataBufferInt) img.getRaster().getDataBuffer();
|
||||
WritableRaster raster = img.getRaster();
|
||||
int scanlineStride = raster.getSampleModel().getWidth();
|
||||
Rectangle r = raster.getBounds();
|
||||
r.x -= raster.getSampleModelTranslateX();
|
||||
r.y -= raster.getSampleModelTranslateY();
|
||||
|
||||
int h=img.getHeight();
|
||||
int w=img.getWidth();
|
||||
int i=offset;
|
||||
int j=r.x+r.y*scanlineStride+(h-1)*scanlineStride;
|
||||
int[] out=buf.getData();
|
||||
for (int y=0;y<h;y++) {
|
||||
System.arraycopy(in,i,out,j,w);
|
||||
i+=w;
|
||||
j-=scanlineStride;
|
||||
}
|
||||
}
|
||||
|
||||
/** Encodes a 4-bit key frame.
|
||||
*
|
||||
* @param out The output stream.
|
||||
* @param pixels The image data.
|
||||
* @param offset The offset to the first pixel in the data array.
|
||||
* @param width The width of the image in data elements.
|
||||
* @param scanlineStride The number to append to offset to get to the next scanline.
|
||||
*/
|
||||
public void writeKey4(OutputStream out, byte[] pixels, int width, int height, int offset, int scanlineStride)
|
||||
throws IOException {
|
||||
|
||||
byte[] bytes = new byte[width];
|
||||
for (int y = (height - 1) * scanlineStride; y >= 0; y -= scanlineStride) { // Upside down
|
||||
for (int x = offset, xx = 0, n = offset + width; x < n; x += 2, ++xx) {
|
||||
bytes[xx] = (byte) (((pixels[y + x] & 0xf) << 4) | (pixels[y + x + 1] & 0xf));
|
||||
}
|
||||
out.write(bytes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Encodes an 8-bit key frame.
|
||||
*
|
||||
* @param out The output stream.
|
||||
* @param pixels The image data.
|
||||
* @param offset The offset to the first pixel in the data array.
|
||||
* @param width The width of the image in data elements.
|
||||
* @param scanlineStride The number to append to offset to get to the next scanline.
|
||||
*/
|
||||
public void writeKey8(OutputStream out, byte[] pixels, int width, int height, int offset, int scanlineStride)
|
||||
throws IOException {
|
||||
|
||||
for (int y = (height - 1) * scanlineStride; y >= 0; y -= scanlineStride) { // Upside down
|
||||
out.write(pixels, y + offset, width);
|
||||
}
|
||||
}
|
||||
|
||||
/** Encodes a 24-bit key frame.
|
||||
*
|
||||
* @param out The output stream.
|
||||
* @param pixels The image data.
|
||||
* @param offset The offset to the first pixel in the data array.
|
||||
* @param width The width of the image in data elements.
|
||||
* @param scanlineStride The number to append to offset to get to the next scanline.
|
||||
*/
|
||||
public void writeKey24(OutputStream out, int[] pixels, int width, int height, int offset, int scanlineStride)
|
||||
throws IOException {
|
||||
int w3 = width * 3;
|
||||
byte[] bytes = new byte[w3]; // holds a scanline of raw image data with 3 channels of 8 bit data
|
||||
for (int xy = (height - 1) * scanlineStride + offset; xy >= offset; xy -= scanlineStride) { // Upside down
|
||||
for (int x = 0, xp = 0; x < w3; x += 3, ++xp) {
|
||||
int p = pixels[xy + xp];
|
||||
bytes[x] = (byte) (p); // Blue
|
||||
bytes[x + 1] = (byte) (p >> 8); // Green
|
||||
bytes[x + 2] = (byte) (p >> 16); // Red
|
||||
}
|
||||
out.write(bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
213
libsrc/avi/src/org/monte/media/color/Colors.java
Normal file
213
libsrc/avi/src/org/monte/media/color/Colors.java
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* @(#)Colors.java 1.0 2011-03-13
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media.color;
|
||||
|
||||
import java.awt.image.IndexColorModel;
|
||||
import static java.lang.Math.*;
|
||||
|
||||
/**
|
||||
* {@code Colors}.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version 1.0 2011-03-13 Created.
|
||||
*/
|
||||
public class Colors {
|
||||
|
||||
/** Prevent instance creation. */
|
||||
private Colors() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The macintosh palette is arranged as follows: there are 256 colours to
|
||||
* allocate, an even distribution of colors through the color cube might be
|
||||
* desirable but 256 is not the cube of an integer. 6x6x6 is 216 and so the
|
||||
* first 216 colors are an equal 6x6x6 sampling of the color cube.
|
||||
* This leaves 40 colours to allocate, this has been done by choosing a ramp of
|
||||
* 10 shades each for red, green, blue and grey.
|
||||
*
|
||||
* <p>
|
||||
* References:<br>
|
||||
* <a href="http://paulbourke.net/texture_colour/colourramp/">http://paulbourke.net/texture_colour/colourramp/</a>
|
||||
*
|
||||
* @return The Macintosh color palette.
|
||||
*/
|
||||
public static IndexColorModel createMacColors() {
|
||||
byte[] r = new byte[256];
|
||||
byte[] g = new byte[256];
|
||||
byte[] b = new byte[256];
|
||||
|
||||
// Generate color cube with 216 colors
|
||||
int index = 0;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
for (int j = 0; j < 6; j++) {
|
||||
for (int k = 0; k < 6; k++) {
|
||||
r[index] = (byte) (255 - 51 * i);
|
||||
g[index] = (byte) (255 - 51 * j);
|
||||
b[index] = (byte) (255 - 51 * k);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
index--; // overwrite last color (black) with color ramp
|
||||
|
||||
// Generate red ramp
|
||||
byte[] ramp = {(byte) 238, (byte) 221, (byte) 187, (byte) 170, (byte) 136, (byte) 119, 85, 68, 34, 17};
|
||||
for (int i = 0; i < 10; i++) {
|
||||
r[index] = ramp[i];
|
||||
g[index] = (byte) (0);
|
||||
b[index] = (byte) (0);
|
||||
index++;
|
||||
}
|
||||
// Generate green ramp
|
||||
for (int j = 0; j < 10; j++) {
|
||||
r[index] = (byte) (0);
|
||||
g[index] = ramp[j];
|
||||
b[index] = (byte) (0);
|
||||
index++;
|
||||
}
|
||||
// Generate blue ramp
|
||||
for (int k = 0; k < 10; k++) {
|
||||
r[index] = (byte) (0);
|
||||
g[index] = (byte) (0);
|
||||
b[index] = ramp[k];
|
||||
index++;
|
||||
}
|
||||
// Generate gray ramp
|
||||
for (int ijk = 0; ijk < 10; ijk++) {
|
||||
r[index] = ramp[ijk];
|
||||
g[index] = ramp[ijk];
|
||||
b[index] = ramp[ijk];
|
||||
index++;
|
||||
}
|
||||
// last color is black (nothing to do)
|
||||
|
||||
/*
|
||||
for (int i=0;i<256;i++) {
|
||||
if (i%6==0) System.out.println(); else System.out.print(" ");
|
||||
System.out.print(Integer.toHexString(r[i]&0xff)+","+Integer.toHexString(g[i]&0xff)+","+Integer.toHexString(b[i]&0xff));
|
||||
}*/
|
||||
|
||||
IndexColorModel icm = new IndexColorModel(8, 256, r, g, b);
|
||||
return icm;
|
||||
}
|
||||
|
||||
private static void RGBtoYCC(float[] rgb, float[] ycc) {
|
||||
float R = rgb[0];
|
||||
float G = rgb[1];
|
||||
float B = rgb[2];
|
||||
float Y = 0.3f * R + 0.6f * G + 0.1f * B;
|
||||
float V = R - Y;
|
||||
float U = B - Y;
|
||||
float Cb = (U / 2f) + 0.5f;
|
||||
float Cr = (V / 1.6f) + 0.5f;
|
||||
ycc[0] = Y;
|
||||
ycc[1] = Cb;
|
||||
ycc[2] = Cr;
|
||||
}
|
||||
|
||||
private static void YCCtoRGB(float[] ycc, float[] rgb) {
|
||||
float Y = ycc[0];
|
||||
float Cb = ycc[1];
|
||||
float Cr = ycc[2];
|
||||
float U = (Cb - 0.5f) * 2f;
|
||||
float V = (Cr - 0.5f) * 1.6f;
|
||||
float R = V + Y;
|
||||
float B = U + Y;
|
||||
float G = (Y - 0.3f * R - 0.1f * B) / 0.6f;
|
||||
rgb[0] = R;
|
||||
rgb[1] = G;
|
||||
rgb[2] = B;
|
||||
}
|
||||
|
||||
/** RGB 8-bit per channel to YCC 16-bit per channel. */
|
||||
private static void RGB8toYCC16(int[] rgb, int[] ycc) {
|
||||
int R = rgb[0];
|
||||
int G = rgb[1];
|
||||
int B = rgb[2];
|
||||
int Y = 77 * R + 153 * G + 26 * B;
|
||||
int V = R * 256 - Y;
|
||||
int U = B * 256 - Y;
|
||||
int Cb = (U / 2) + 128 * 256;
|
||||
int Cr = (V * 5 / 8) + 128 * 256;
|
||||
ycc[0] = Y;
|
||||
ycc[1] = Cb;
|
||||
ycc[2] = Cr;
|
||||
}
|
||||
|
||||
/** RGB 8-bit per channel to YCC 16-bit per channel. */
|
||||
private static void RGB8toYCC16(int rgb, int[] ycc) {
|
||||
int R = (rgb & 0xff0000) >>> 16;
|
||||
int G = (rgb & 0xff00) >>> 8;
|
||||
int B = rgb & 0xff;
|
||||
int Y = 77 * R + 153 * G + 26 * B;
|
||||
int V = R * 256 - Y;
|
||||
int U = B * 256 - Y;
|
||||
int Cb = (U / 2) + 128 * 256;
|
||||
int Cr = (V * 5 / 8) + 128 * 256;
|
||||
ycc[0] = Y;
|
||||
ycc[1] = Cb;
|
||||
ycc[2] = Cr;
|
||||
}
|
||||
|
||||
/** YCC 16-bit per channel to RGB 8-bit per channel. */
|
||||
private static void YCC16toRGB8(int[] ycc, int[] rgb) {
|
||||
int Y = ycc[0];
|
||||
int Cb = ycc[1];
|
||||
int Cr = ycc[2];
|
||||
int U = (Cb - 128 * 256) * 2;
|
||||
int V = (Cr - 128 * 256) * 8 / 5;
|
||||
int R = min(255, max(0, (V + Y) / 256));
|
||||
int B = min(255, max(0, (U + Y) / 256));
|
||||
int G = min(255, max(0, (Y - 77 * R - 26 * B) / 153));
|
||||
rgb[0] = R;
|
||||
rgb[1] = G;
|
||||
rgb[2] = B;
|
||||
}
|
||||
|
||||
/** YCC 8-bit per channel to RGB 8-bit per channel.
|
||||
*/
|
||||
private static void YCC8toRGB8(int[] ycc, int[] rgb) {
|
||||
int Y = ycc[0];
|
||||
int Cb = ycc[1];
|
||||
int Cr = ycc[2];
|
||||
// Source: JPEG File Interchange Format Version 1.02, September 1, 1992
|
||||
//RGB can be computed directly from YCbCr (256 levels) as follows:
|
||||
//R = Y + 1.402 (Cr-128)
|
||||
//G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128)
|
||||
//B = Y + 1.772 (Cb-128)
|
||||
int R = (1000 * Y + 1402 * (Cr - 128)) / 1000;
|
||||
int G = (100000 * Y - 34414 * (Cb - 128) - 71414 * (Cr - 128)) / 100000;
|
||||
int B = (1000 * Y + 1772 * (Cb - 128)) / 1000;
|
||||
rgb[0] = min(255, max(0, R));
|
||||
rgb[1] = min(255, max(0, G));
|
||||
rgb[2] = min(255, max(0, B));
|
||||
}
|
||||
|
||||
/** YCC 8-bit per channel to RGB 8-bit per channel.
|
||||
*/
|
||||
private static void RGB8toYCC8(int[] rgb, int[] ycc) {
|
||||
int R = rgb[0];
|
||||
int G = rgb[1];
|
||||
int B = rgb[2];
|
||||
// Source: JPEG File Interchange Format Version 1.02, September 1, 1992
|
||||
//YCbCr (256 levels) can be computed directly from 8-bit RGB as follows:
|
||||
//Y = 0.299R +0.587G +0.114B
|
||||
//Cb = - 0.1687 R - 0.3313 G + 0.5 B + 128
|
||||
//Cr = 0.5 R - 0.4187 G - 0.0813 B + 128
|
||||
int Y = (299 * R + 587 * G + 114 * B) / 1000;
|
||||
int Cb = (-1687 * R - 3313 * G + 5000 * B) / 10000 + 128;
|
||||
int Cr = (5000 * R - 4187 * G - 813 * B) / 10000 + 128;
|
||||
ycc[0] = min(255, max(0, Y));
|
||||
ycc[1] = min(255, max(0, Cb));
|
||||
ycc[2] = min(255, max(0, Cr));
|
||||
}
|
||||
}
|
||||
216
libsrc/avi/src/org/monte/media/io/ByteArrayImageInputStream.java
Normal file
216
libsrc/avi/src/org/monte/media/io/ByteArrayImageInputStream.java
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* @(#)ByteArrayImageInputStream.java
|
||||
*
|
||||
* Copyright (c) 2008-2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/**
|
||||
* A {@code ByteArrayImageInputStream} contains
|
||||
* an internal buffer that contains bytes that
|
||||
* may be read from the stream. An internal
|
||||
* counter keeps track of the next byte to
|
||||
* be supplied by the {@code read} method.
|
||||
* <p>
|
||||
* Closing a {@code ByteArrayImageInputStream} has no effect. The methods in
|
||||
* this class can be called after the stream has been closed without
|
||||
* generating an {@code IOException}.
|
||||
*
|
||||
* @author Werner Randelshofer, Hausmatt 10, CH-6405 Goldau
|
||||
* @version $Id: ByteArrayImageInputStream.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class ByteArrayImageInputStream extends ImageInputStreamImpl2 {
|
||||
/**
|
||||
* An array of bytes that was provided
|
||||
* by the creator of the stream. Elements <code>buf[0]</code>
|
||||
* through <code>buf[count-1]</code> are the
|
||||
* only bytes that can ever be read from the
|
||||
* stream; element <code>buf[streamPos]</code> is
|
||||
* the next byte to be read.
|
||||
*/
|
||||
protected byte buf[];
|
||||
|
||||
/**
|
||||
* The index one greater than the last valid character in the input
|
||||
* stream buffer.
|
||||
* This value should always be nonnegative
|
||||
* and not larger than the length of <code>buf</code>.
|
||||
* It is one greater than the position of
|
||||
* the last byte within <code>buf</code> that
|
||||
* can ever be read from the input stream buffer.
|
||||
*/
|
||||
protected int count;
|
||||
|
||||
/** The offset to the start of the array. */
|
||||
private final int arrayOffset;
|
||||
|
||||
public ByteArrayImageInputStream(byte[] buf) {
|
||||
this(buf, ByteOrder.BIG_ENDIAN);
|
||||
}
|
||||
|
||||
public ByteArrayImageInputStream(byte[] buf, ByteOrder byteOrder) {
|
||||
this(buf, 0, buf.length, byteOrder);
|
||||
}
|
||||
|
||||
public ByteArrayImageInputStream(byte[] buf, int offset, int length, ByteOrder byteOrder) {
|
||||
this.buf = buf;
|
||||
this.streamPos = offset;
|
||||
this.count = Math.min(offset + length, buf.length);
|
||||
this.arrayOffset = offset;
|
||||
this.byteOrder = byteOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next byte of data from this input stream. The value
|
||||
* byte is returned as an <code>int</code> in the range
|
||||
* <code>0</code> to <code>255</code>. If no byte is available
|
||||
* because the end of the stream has been reached, the value
|
||||
* <code>-1</code> is returned.
|
||||
* <p>
|
||||
* This <code>read</code> method
|
||||
* cannot block.
|
||||
*
|
||||
* @return the next byte of data, or <code>-1</code> if the end of the
|
||||
* stream has been reached.
|
||||
*/
|
||||
@Override
|
||||
public synchronized int read() {
|
||||
flushBits();
|
||||
return (streamPos < count) ? (buf[(int)(streamPos++)] & 0xff) : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads up to <code>len</code> bytes of data into an array of bytes
|
||||
* from this input stream.
|
||||
* If <code>streamPos</code> equals <code>count</code>,
|
||||
* then <code>-1</code> is returned to indicate
|
||||
* end of file. Otherwise, the number <code>k</code>
|
||||
* of bytes read is equal to the smaller of
|
||||
* <code>len</code> and <code>count-streamPos</code>.
|
||||
* If <code>k</code> is positive, then bytes
|
||||
* <code>buf[streamPos]</code> through <code>buf[streamPos+k-1]</code>
|
||||
* are copied into <code>b[off]</code> through
|
||||
* <code>b[off+k-1]</code> in the manner performed
|
||||
* by <code>System.arraycopy</code>. The
|
||||
* value <code>k</code> is added into <code>streamPos</code>
|
||||
* and <code>k</code> is returned.
|
||||
* <p>
|
||||
* This <code>read</code> method cannot block.
|
||||
*
|
||||
* @param b the buffer into which the data is read.
|
||||
* @param off the start offset in the destination array <code>b</code>
|
||||
* @param len the maximum number of bytes read.
|
||||
* @return the total number of bytes read into the buffer, or
|
||||
* <code>-1</code> if there is no more data because the end of
|
||||
* the stream has been reached.
|
||||
* @exception NullPointerException If <code>b</code> is <code>null</code>.
|
||||
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
|
||||
* <code>len</code> is negative, or <code>len</code> is greater than
|
||||
* <code>b.length - off</code>
|
||||
*/
|
||||
@Override
|
||||
public synchronized int read(byte b[], int off, int len) {
|
||||
flushBits();
|
||||
if (b == null) {
|
||||
throw new NullPointerException();
|
||||
} else if (off < 0 || len < 0 || len > b.length - off) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
if (streamPos >= count) {
|
||||
return -1;
|
||||
}
|
||||
if (streamPos + len > count) {
|
||||
len = (int)(count - streamPos);
|
||||
}
|
||||
if (len <= 0) {
|
||||
return 0;
|
||||
}
|
||||
System.arraycopy(buf, (int)streamPos, b, off, len);
|
||||
streamPos += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips <code>n</code> bytes of input from this input stream. Fewer
|
||||
* bytes might be skipped if the end of the input stream is reached.
|
||||
* The actual number <code>k</code>
|
||||
* of bytes to be skipped is equal to the smaller
|
||||
* of <code>n</code> and <code>count-streamPos</code>.
|
||||
* The value <code>k</code> is added into <code>streamPos</code>
|
||||
* and <code>k</code> is returned.
|
||||
*
|
||||
* @param n the number of bytes to be skipped.
|
||||
* @return the actual number of bytes skipped.
|
||||
*/
|
||||
public synchronized long skip(long n) {
|
||||
if (streamPos + n > count) {
|
||||
n = count - streamPos;
|
||||
}
|
||||
if (n < 0) {
|
||||
return 0;
|
||||
}
|
||||
streamPos += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of remaining bytes that can be read (or skipped over)
|
||||
* from this input stream.
|
||||
* <p>
|
||||
* The value returned is <code>count - streamPos</code>,
|
||||
* which is the number of bytes remaining to be read from the input buffer.
|
||||
*
|
||||
* @return the number of remaining bytes that can be read (or skipped
|
||||
* over) from this input stream without blocking.
|
||||
*/
|
||||
public synchronized int available() {
|
||||
return (int)(count - streamPos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Closing a <tt>ByteArrayInputStream</tt> has no effect. The methods in
|
||||
* this class can be called after the stream has been closed without
|
||||
* generating an <tt>IOException</tt>.
|
||||
* <p>
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
// does nothing!!
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getStreamPosition() throws IOException {
|
||||
checkClosed();
|
||||
return streamPos-arrayOffset;
|
||||
}
|
||||
@Override
|
||||
public void seek(long pos) throws IOException {
|
||||
checkClosed();
|
||||
flushBits();
|
||||
|
||||
// This test also covers pos < 0
|
||||
if (pos < flushedPos) {
|
||||
throw new IndexOutOfBoundsException("pos < flushedPos!");
|
||||
}
|
||||
|
||||
this.streamPos = pos+arrayOffset;
|
||||
}
|
||||
|
||||
private void flushBits() {
|
||||
bitOffset=0;
|
||||
}
|
||||
@Override
|
||||
public long length() {
|
||||
return count-arrayOffset;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
* @(#)ByteArrayImageOutputStream.java 1.0.1 2011-01-23
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer
|
||||
* Staldenmattweg 2, Goldau, CH-6405, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The copyright of this software is owned by Werner Randelshofer.
|
||||
* You may not use, copy or modify this software, except in
|
||||
* accordance with the license agreement you entered into with
|
||||
* Werner Randelshofer. For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media.io;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import javax.imageio.stream.ImageOutputStreamImpl;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.nio.ByteOrder;
|
||||
import static java.lang.Math.*;
|
||||
|
||||
/**
|
||||
* This class implements an image output stream in which the data is
|
||||
* written into a byte array. The buffer automatically grows as data
|
||||
* is written to it.
|
||||
* The data can be retrieved using {@code toByteArray()}, {@code toImageOutputStream()}
|
||||
* and {@code toOutputStream()}.
|
||||
* <p>
|
||||
* Closing a {@code ByteArrayImageOutputStream} has no effect. The methods in
|
||||
* this class can be called after the stream has been closed without
|
||||
* generating an {@code IOException}.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version 1.0.1 2011-01-23 Implements length method.
|
||||
* <br>1.0 2011-01-18 Created.
|
||||
*/
|
||||
public class ByteArrayImageOutputStream extends ImageOutputStreamImpl {
|
||||
|
||||
|
||||
/**
|
||||
* An array of bytes that was provided
|
||||
* by the creator of the stream. Elements <code>buf[0]</code>
|
||||
* through <code>buf[count-1]</code> are the
|
||||
* only bytes that can ever be read from the
|
||||
* stream; element <code>buf[streamPos]</code> is
|
||||
* the next byte to be read.
|
||||
*/
|
||||
protected byte buf[];
|
||||
/**
|
||||
* The index one greater than the last valid character in the input
|
||||
* stream buffer.
|
||||
* This value should always be nonnegative
|
||||
* and not larger than the length of <code>buf</code>.
|
||||
* It is one greater than the position of
|
||||
* the last byte within <code>buf</code> that
|
||||
* can ever be read from the input stream buffer.
|
||||
*/
|
||||
protected int count;
|
||||
/** The offset to the start of the array. */
|
||||
private final int arrayOffset;
|
||||
|
||||
public ByteArrayImageOutputStream() {
|
||||
this(16);
|
||||
}
|
||||
|
||||
public ByteArrayImageOutputStream(int initialCapacity) {
|
||||
this(new byte[initialCapacity]);
|
||||
}
|
||||
|
||||
public ByteArrayImageOutputStream(byte[] buf) {
|
||||
this(buf, ByteOrder.BIG_ENDIAN);
|
||||
}
|
||||
|
||||
public ByteArrayImageOutputStream(byte[] buf, ByteOrder byteOrder) {
|
||||
this(buf, 0, buf.length, byteOrder);
|
||||
}
|
||||
|
||||
public ByteArrayImageOutputStream(byte[] buf, int offset, int length, ByteOrder byteOrder) {
|
||||
this.buf = buf;
|
||||
this.streamPos = offset;
|
||||
this.count = Math.min(offset + length, buf.length);
|
||||
this.arrayOffset = offset;
|
||||
this.byteOrder = byteOrder;
|
||||
}
|
||||
|
||||
public ByteArrayImageOutputStream(ByteOrder byteOrder) {
|
||||
this(new byte[16],byteOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next byte of data from this input stream. The value
|
||||
* byte is returned as an <code>int</code> in the range
|
||||
* <code>0</code> to <code>255</code>. If no byte is available
|
||||
* because the end of the stream has been reached, the value
|
||||
* <code>-1</code> is returned.
|
||||
* <p>
|
||||
* This <code>read</code> method
|
||||
* cannot block.
|
||||
*
|
||||
* @return the next byte of data, or <code>-1</code> if the end of the
|
||||
* stream has been reached.
|
||||
*/
|
||||
@Override
|
||||
public synchronized int read() throws IOException {
|
||||
flushBits();
|
||||
return (streamPos < count) ? (buf[(int) (streamPos++)] & 0xff) : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads up to <code>len</code> bytes of data into an array of bytes
|
||||
* from this input stream.
|
||||
* If <code>streamPos</code> equals <code>count</code>,
|
||||
* then <code>-1</code> is returned to indicate
|
||||
* end of file. Otherwise, the number <code>k</code>
|
||||
* of bytes read is equal to the smaller of
|
||||
* <code>len</code> and <code>count-streamPos</code>.
|
||||
* If <code>k</code> is positive, then bytes
|
||||
* <code>buf[streamPos]</code> through <code>buf[streamPos+k-1]</code>
|
||||
* are copied into <code>b[off]</code> through
|
||||
* <code>b[off+k-1]</code> in the manner performed
|
||||
* by <code>System.arraycopy</code>. The
|
||||
* value <code>k</code> is added into <code>streamPos</code>
|
||||
* and <code>k</code> is returned.
|
||||
* <p>
|
||||
* This <code>read</code> method cannot block.
|
||||
*
|
||||
* @param b the buffer into which the data is read.
|
||||
* @param off the start offset in the destination array <code>b</code>
|
||||
* @param len the maximum number of bytes read.
|
||||
* @return the total number of bytes read into the buffer, or
|
||||
* <code>-1</code> if there is no more data because the end of
|
||||
* the stream has been reached.
|
||||
* @exception NullPointerException If <code>b</code> is <code>null</code>.
|
||||
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
|
||||
* <code>len</code> is negative, or <code>len</code> is greater than
|
||||
* <code>b.length - off</code>
|
||||
*/
|
||||
@Override
|
||||
public synchronized int read(byte b[], int off, int len) throws IOException {
|
||||
flushBits();
|
||||
if (b == null) {
|
||||
throw new NullPointerException();
|
||||
} else if (off < 0 || len < 0 || len > b.length - off) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
if (streamPos >= count) {
|
||||
return -1;
|
||||
}
|
||||
if (streamPos + len > count) {
|
||||
len = (int) (count - streamPos);
|
||||
}
|
||||
if (len <= 0) {
|
||||
return 0;
|
||||
}
|
||||
System.arraycopy(buf, (int) streamPos, b, off, len);
|
||||
streamPos += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips <code>n</code> bytes of input from this input stream. Fewer
|
||||
* bytes might be skipped if the end of the input stream is reached.
|
||||
* The actual number <code>k</code>
|
||||
* of bytes to be skipped is equal to the smaller
|
||||
* of <code>n</code> and <code>count-streamPos</code>.
|
||||
* The value <code>k</code> is added into <code>streamPos</code>
|
||||
* and <code>k</code> is returned.
|
||||
*
|
||||
* @param n the number of bytes to be skipped.
|
||||
* @return the actual number of bytes skipped.
|
||||
*/
|
||||
public synchronized long skip(long n) {
|
||||
if (streamPos + n > count) {
|
||||
n = count - streamPos;
|
||||
}
|
||||
if (n < 0) {
|
||||
return 0;
|
||||
}
|
||||
streamPos += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of remaining bytes that can be read (or skipped over)
|
||||
* from this input stream.
|
||||
* <p>
|
||||
* The value returned is <code>count - streamPos</code>,
|
||||
* which is the number of bytes remaining to be read from the input buffer.
|
||||
*
|
||||
* @return the number of remaining bytes that can be read (or skipped
|
||||
* over) from this input stream without blocking.
|
||||
*/
|
||||
public synchronized int available() {
|
||||
return (int) (count - streamPos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closing a <tt>ByteArrayInputStream</tt> has no effect. The methods in
|
||||
* this class can be called after the stream has been closed without
|
||||
* generating an <tt>IOException</tt>.
|
||||
* <p>
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
// does nothing!!
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getStreamPosition() throws IOException {
|
||||
checkClosed();
|
||||
return streamPos - arrayOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seek(long pos) throws IOException {
|
||||
checkClosed();
|
||||
flushBits();
|
||||
|
||||
// This test also covers pos < 0
|
||||
if (pos < flushedPos) {
|
||||
throw new IndexOutOfBoundsException("pos < flushedPos!");
|
||||
}
|
||||
|
||||
this.streamPos = pos + arrayOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the specified byte to this output stream.
|
||||
*
|
||||
* @param b the byte to be written.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void write(int b) throws IOException {
|
||||
flushBits();
|
||||
long newcount = max(streamPos + 1, count);
|
||||
if (newcount> Integer.MAX_VALUE) {
|
||||
throw new IndexOutOfBoundsException(newcount+" > max array size");
|
||||
}
|
||||
if (newcount > buf.length) {
|
||||
buf = Arrays.copyOf(buf, max(buf.length << 1, (int) newcount));
|
||||
}
|
||||
buf[(int) streamPos++] = (byte) b;
|
||||
count = (int)newcount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the specified byte array to this output stream.
|
||||
*
|
||||
* @param b the data.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void write(byte b[]) throws IOException {
|
||||
write(b, 0, b.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes <code>len</code> bytes from the specified byte array
|
||||
* starting at offset <code>off</code> to this output stream.
|
||||
*
|
||||
* @param b the data.
|
||||
* @param off the start offset in the data.
|
||||
* @param len the number of bytes to write.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void write(byte b[], int off, int len) throws IOException {
|
||||
flushBits();
|
||||
if ((off < 0) || (off > b.length) || (len < 0)
|
||||
|| ((off + len) > b.length) || ((off + len) < 0)) {
|
||||
throw new IndexOutOfBoundsException("off="+off+", len="+len+", b.length="+b.length);
|
||||
} else if (len == 0) {
|
||||
return;
|
||||
}
|
||||
int newcount = max((int) streamPos + len, count);
|
||||
if (newcount > buf.length) {
|
||||
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
|
||||
}
|
||||
System.arraycopy(b, off, buf, (int) streamPos, len);
|
||||
streamPos += len;
|
||||
count = newcount;
|
||||
}
|
||||
|
||||
/** Writes the contents of the byte array into the specified output
|
||||
* stream.
|
||||
* @param out
|
||||
*/
|
||||
public void toOutputStream(OutputStream out) throws IOException {
|
||||
out.write(buf, arrayOffset, count);
|
||||
}
|
||||
|
||||
/** Writes the contents of the byte array into the specified image output
|
||||
* stream.
|
||||
* @param out
|
||||
*/
|
||||
public void toImageOutputStream(ImageOutputStream out) throws IOException {
|
||||
out.write(buf, arrayOffset, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a newly allocated byte array. Its size is the current
|
||||
* size of this output stream and the valid contents of the buffer
|
||||
* have been copied into it.
|
||||
*
|
||||
* @return the current contents of this output stream, as a byte array.
|
||||
* @see java.io.ByteArrayOutputStream#size()
|
||||
*/
|
||||
public synchronized byte[] toByteArray() {
|
||||
byte[] copy = new byte[count - arrayOffset];
|
||||
System.arraycopy(buf, arrayOffset, copy, 0, count);
|
||||
return copy;
|
||||
}
|
||||
|
||||
/** Returns the internally used byte buffer. */
|
||||
public byte[] getBuffer() {
|
||||
return buf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long length() {
|
||||
return count-arrayOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the <code>count</code> field of this byte array output
|
||||
* stream to zero, so that all currently accumulated output in the
|
||||
* output stream is discarded. The output stream can be used again,
|
||||
* reusing the already allocated buffer space.
|
||||
*
|
||||
* @see java.io.ByteArrayInputStream#count
|
||||
*/
|
||||
public synchronized void clear() {
|
||||
count = arrayOffset;
|
||||
streamPos=arrayOffset;
|
||||
}
|
||||
}
|
||||
189
libsrc/avi/src/org/monte/media/io/ImageInputStreamAdapter.java
Normal file
189
libsrc/avi/src/org/monte/media/io/ImageInputStreamAdapter.java
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* @(#)ImageInputStreamAdapter.java 1.0 2009-12-17
|
||||
*
|
||||
* Copyright (c) 2009 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
|
||||
package org.monte.media.io;
|
||||
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
/**
|
||||
* ImageInputStreamAdapter.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version 1.0 2009-12-17 Created.
|
||||
*/
|
||||
public class ImageInputStreamAdapter extends FilterInputStream {
|
||||
private ImageInputStream iis;
|
||||
public ImageInputStreamAdapter(ImageInputStream iis) {
|
||||
super(null);
|
||||
this.iis=iis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next byte of data from this input stream. The value
|
||||
* byte is returned as an <code>int</code> in the range
|
||||
* <code>0</code> to <code>255</code>. If no byte is available
|
||||
* because the end of the stream has been reached, the value
|
||||
* <code>-1</code> is returned. This method blocks until input data
|
||||
* is available, the end of the stream is detected, or an exception
|
||||
* is thrown.
|
||||
* <p>
|
||||
* This method
|
||||
* simply performs <code>in.read()</code> and returns the result.
|
||||
*
|
||||
* @return the next byte of data, or <code>-1</code> if the end of the
|
||||
* stream is reached.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
* @see java.io.FilterInputStream#in
|
||||
*/
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return iis.read();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads up to <code>len</code> bytes of data from this input stream
|
||||
* into an array of bytes. If <code>len</code> is not zero, the method
|
||||
* blocks until some input is available; otherwise, no
|
||||
* bytes are read and <code>0</code> is returned.
|
||||
* <p>
|
||||
* This method simply performs <code>in.read(b, off, len)</code>
|
||||
* and returns the result.
|
||||
*
|
||||
* @param b the buffer into which the data is read.
|
||||
* @param off the start offset in the destination array <code>b</code>
|
||||
* @param len the maximum number of bytes read.
|
||||
* @return the total number of bytes read into the buffer, or
|
||||
* <code>-1</code> if there is no more data because the end of
|
||||
* the stream has been reached.
|
||||
* @exception NullPointerException If <code>b</code> is <code>null</code>.
|
||||
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
|
||||
* <code>len</code> is negative, or <code>len</code> is greater than
|
||||
* <code>b.length - off</code>
|
||||
* @exception IOException if an I/O error occurs.
|
||||
* @see java.io.FilterInputStream#in
|
||||
*/
|
||||
@Override
|
||||
public int read(byte b[], int off, int len) throws IOException {
|
||||
return iis.read(b, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>
|
||||
* This method simply performs <code>in.skip(n)</code>.
|
||||
*/
|
||||
@Override
|
||||
public long skip(long n) throws IOException {
|
||||
return iis.skipBytes(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an estimate of the number of bytes that can be read (or
|
||||
* skipped over) from this input stream without blocking by the next
|
||||
* caller of a method for this input stream. The next caller might be
|
||||
* the same thread or another thread. A single read or skip of this
|
||||
* many bytes will not block, but may read or skip fewer bytes.
|
||||
* <p>
|
||||
* This method returns the result of {@link #in in}.available().
|
||||
*
|
||||
* @return an estimate of the number of bytes that can be read (or skipped
|
||||
* over) from this input stream without blocking.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return (iis.isCached()) ? //
|
||||
(int)Math.min(Integer.MAX_VALUE, iis.length() - iis.getStreamPosition()) :
|
||||
0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this input stream and releases any system resources
|
||||
* associated with the stream.
|
||||
* This
|
||||
* method simply performs <code>in.close()</code>.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs.
|
||||
* @see java.io.FilterInputStream#in
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
iis.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the current position in this input stream. A subsequent
|
||||
* call to the <code>reset</code> method repositions this stream at
|
||||
* the last marked position so that subsequent reads re-read the same bytes.
|
||||
* <p>
|
||||
* The <code>readlimit</code> argument tells this input stream to
|
||||
* allow that many bytes to be read before the mark position gets
|
||||
* invalidated.
|
||||
* <p>
|
||||
* This method simply performs <code>in.mark(readlimit)</code>.
|
||||
*
|
||||
* @param readlimit the maximum limit of bytes that can be read before
|
||||
* the mark position becomes invalid.
|
||||
* @see java.io.FilterInputStream#in
|
||||
* @see java.io.FilterInputStream#reset()
|
||||
*/
|
||||
@Override
|
||||
public synchronized void mark(int readlimit) {
|
||||
iis.mark();
|
||||
}
|
||||
|
||||
/**
|
||||
* Repositions this stream to the position at the time the
|
||||
* <code>mark</code> method was last called on this input stream.
|
||||
* <p>
|
||||
* This method
|
||||
* simply performs <code>in.reset()</code>.
|
||||
* <p>
|
||||
* Stream marks are intended to be used in
|
||||
* situations where you need to read ahead a little to see what's in
|
||||
* the stream. Often this is most easily done by invoking some
|
||||
* general parser. If the stream is of the type handled by the
|
||||
* parse, it just chugs along happily. If the stream is not of
|
||||
* that type, the parser should toss an exception when it fails.
|
||||
* If this happens within readlimit bytes, it allows the outer
|
||||
* code to reset the stream and try another parser.
|
||||
*
|
||||
* @exception IOException if the stream has not been marked or if the
|
||||
* mark has been invalidated.
|
||||
* @see java.io.FilterInputStream#in
|
||||
* @see java.io.FilterInputStream#mark(int)
|
||||
*/
|
||||
@Override
|
||||
public synchronized void reset() throws IOException {
|
||||
iis.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if this input stream supports the <code>mark</code>
|
||||
* and <code>reset</code> methods.
|
||||
* This method
|
||||
* simply performs <code>in.markSupported()</code>.
|
||||
*
|
||||
* @return <code>true</code> if this stream type supports the
|
||||
* <code>mark</code> and <code>reset</code> method;
|
||||
* <code>false</code> otherwise.
|
||||
* @see java.io.FilterInputStream#in
|
||||
* @see java.io.InputStream#mark(int)
|
||||
* @see java.io.InputStream#reset()
|
||||
*/
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
65
libsrc/avi/src/org/monte/media/io/ImageInputStreamImpl2.java
Normal file
65
libsrc/avi/src/org/monte/media/io/ImageInputStreamImpl2.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* @(#)ImageInputStreamImpl2.java
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteOrder;
|
||||
import javax.imageio.stream.ImageInputStreamImpl;
|
||||
|
||||
/**
|
||||
* {@code ImageInputStreamImpl2} fixes bugs in ImageInputStreamImpl.
|
||||
* <p>
|
||||
* ImageInputStreamImpl uses read(byte[]) instead of readFully(byte[]) inside of
|
||||
* readShort. This results in corrupt data input if the underlying stream can
|
||||
* not fulfill the read operation in a single step.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: ImageInputStreamImpl2.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public abstract class ImageInputStreamImpl2 extends ImageInputStreamImpl {
|
||||
// Length of the buffer used for readFully(type[], int, int)
|
||||
private static final int BYTE_BUF_LENGTH = 8192;
|
||||
/**
|
||||
* Byte buffer used for readFully(type[], int, int). Note that this
|
||||
* array is also used for bulk reads in readShort(), readInt(), etc, so
|
||||
* it should be large enough to hold a primitive value (i.e. >= 8 bytes).
|
||||
* Also note that this array is package protected, so that it can be
|
||||
* used by ImageOutputStreamImpl in a similar manner.
|
||||
*/
|
||||
byte[] byteBuf = new byte[BYTE_BUF_LENGTH];
|
||||
|
||||
@Override
|
||||
public short readShort() throws IOException {
|
||||
readFully(byteBuf, 0, 2);
|
||||
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
return (short)
|
||||
(((byteBuf[0] & 0xff) << 8) | ((byteBuf[1] & 0xff) << 0));
|
||||
} else {
|
||||
return (short)
|
||||
(((byteBuf[1] & 0xff) << 8) | ((byteBuf[0] & 0xff) << 0));
|
||||
}
|
||||
}
|
||||
public int readInt() throws IOException {
|
||||
readFully(byteBuf, 0, 4);
|
||||
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
return
|
||||
(((byteBuf[0] & 0xff) << 24) | ((byteBuf[1] & 0xff) << 16) |
|
||||
((byteBuf[2] & 0xff) << 8) | ((byteBuf[3] & 0xff) << 0));
|
||||
} else {
|
||||
return
|
||||
(((byteBuf[3] & 0xff) << 24) | ((byteBuf[2] & 0xff) << 16) |
|
||||
((byteBuf[1] & 0xff) << 8) | ((byteBuf[0] & 0xff) << 0));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* @(#)SeekableByteArrayOutputStream.java
|
||||
*
|
||||
* Copyright © 2010-2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
|
||||
package org.monte.media.io;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import static java.lang.Math.*;
|
||||
/**
|
||||
* {@code SeekableByteArrayOutputStream}.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: SeekableByteArrayOutputStream.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class SeekableByteArrayOutputStream extends ByteArrayOutputStream {
|
||||
|
||||
/**
|
||||
* The current stream position.
|
||||
*/
|
||||
private int pos;
|
||||
|
||||
/**
|
||||
* Creates a new byte array output stream. The buffer capacity is
|
||||
* initially 32 bytes, though its size increases if necessary.
|
||||
*/
|
||||
public SeekableByteArrayOutputStream() {
|
||||
this(32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new byte array output stream, with a buffer capacity of
|
||||
* the specified size, in bytes.
|
||||
*
|
||||
* @param size the initial size.
|
||||
* @exception IllegalArgumentException if size is negative.
|
||||
*/
|
||||
public SeekableByteArrayOutputStream(int size) {
|
||||
if (size < 0) {
|
||||
throw new IllegalArgumentException("Negative initial size: "
|
||||
+ size);
|
||||
}
|
||||
buf = new byte[size];
|
||||
}
|
||||
/**
|
||||
* Creates a new byte array output stream, which reuses the supplied buffer.
|
||||
*/
|
||||
public SeekableByteArrayOutputStream(byte[] buf) {
|
||||
this.buf = buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the specified byte to this byte array output stream.
|
||||
*
|
||||
* @param b the byte to be written.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void write(int b) {
|
||||
int newcount = max(pos + 1, count);
|
||||
if (newcount > buf.length) {
|
||||
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
|
||||
}
|
||||
buf[pos++] = (byte)b;
|
||||
count = newcount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes <code>len</code> bytes from the specified byte array
|
||||
* starting at offset <code>off</code> to this byte array output stream.
|
||||
*
|
||||
* @param b the data.
|
||||
* @param off the start offset in the data.
|
||||
* @param len the number of bytes to write.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void write(byte b[], int off, int len) {
|
||||
if ((off < 0) || (off > b.length) || (len < 0) ||
|
||||
((off + len) > b.length) || ((off + len) < 0)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
} else if (len == 0) {
|
||||
return;
|
||||
}
|
||||
int newcount = max(pos+len,count);
|
||||
if (newcount > buf.length) {
|
||||
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
|
||||
}
|
||||
System.arraycopy(b, off, buf, pos, len);
|
||||
pos+=len;
|
||||
count = newcount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the <code>count</code> field of this byte array output
|
||||
* stream to zero, so that all currently accumulated output in the
|
||||
* output stream is discarded. The output stream can be used again,
|
||||
* reusing the already allocated buffer space.
|
||||
*
|
||||
* @see java.io.ByteArrayInputStream#count
|
||||
*/
|
||||
@Override
|
||||
public synchronized void reset() {
|
||||
count = 0;
|
||||
pos=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current stream position to the desired location. The
|
||||
* next read will occur at this location. The bit offset is set
|
||||
* to 0.
|
||||
*
|
||||
* <p> An <code>IndexOutOfBoundsException</code> will be thrown if
|
||||
* <code>pos</code> is smaller than the flushed position (as
|
||||
* returned by <code>getflushedPosition</code>).
|
||||
*
|
||||
* <p> It is legal to seek past the end of the file; an
|
||||
* <code>EOFException</code> will be thrown only if a read is
|
||||
* performed.
|
||||
*
|
||||
* @param pos a <code>long</code> containing the desired file
|
||||
* pointer position.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if <code>pos</code> is smaller
|
||||
* than the flushed position.
|
||||
* @exception IOException if any other I/O error occurs.
|
||||
*/
|
||||
public void seek(long pos) throws IOException {
|
||||
this.pos = (int)pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current byte position of the stream. The next write
|
||||
* will take place starting at this offset.
|
||||
*
|
||||
* @return a long containing the position of the stream.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
public long getStreamPosition() throws IOException {
|
||||
return pos;
|
||||
}
|
||||
|
||||
/** Writes the contents of the byte array into the specified output
|
||||
* stream.
|
||||
* @param out
|
||||
*/
|
||||
public void toOutputStream(OutputStream out) throws IOException {
|
||||
out.write(buf, 0, count);
|
||||
}
|
||||
|
||||
/** Returns the underlying byte buffer. */
|
||||
public byte[] getBuffer() {
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
151
libsrc/avi/src/org/monte/media/io/SubImageOutputStream.java
Normal file
151
libsrc/avi/src/org/monte/media/io/SubImageOutputStream.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* @(#)SubImageOutputStream.java 1.0 2011-07-20
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteOrder;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import javax.imageio.stream.ImageOutputStreamImpl;
|
||||
|
||||
/**
|
||||
* {@code SubImageOutputStream}.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version 1.0 2011-07-20 Created.
|
||||
*/
|
||||
public class SubImageOutputStream extends ImageOutputStreamImpl {
|
||||
|
||||
private ImageOutputStream out;
|
||||
private long offset;
|
||||
private long length;
|
||||
|
||||
/** Whether flush and close request shall be forwarded to underlying stream.*/
|
||||
private boolean forwardFlushAndClose;
|
||||
|
||||
public SubImageOutputStream(ImageOutputStream out, ByteOrder bo,boolean forwardFlushAndClose) throws IOException {
|
||||
this(out, out.getStreamPosition(),bo,forwardFlushAndClose);
|
||||
}
|
||||
|
||||
public SubImageOutputStream(ImageOutputStream out, long offset, ByteOrder bo,boolean forwardFlushAndClose) throws IOException {
|
||||
this.out = out;
|
||||
this.offset = offset;
|
||||
this.forwardFlushAndClose=forwardFlushAndClose;
|
||||
setByteOrder(bo);
|
||||
out.seek(offset);
|
||||
}
|
||||
|
||||
private long available() throws IOException {
|
||||
checkClosed();
|
||||
long pos = out.getStreamPosition();
|
||||
if (pos < offset) {
|
||||
out.seek(offset);
|
||||
pos = offset;
|
||||
}
|
||||
return offset + out.length() - pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if (available() <= 0) {
|
||||
return -1;
|
||||
} else {
|
||||
return out.read();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
long av = available();
|
||||
if (av <= 0) {
|
||||
return -1;
|
||||
} else {
|
||||
int result = out.read(b, off, (int) Math.min(len, av));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getStreamPosition() throws IOException {
|
||||
return out.getStreamPosition() - offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seek(long pos) throws IOException {
|
||||
out.seek(pos + offset);
|
||||
length=Math.max(pos-offset+1,length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
if (forwardFlushAndClose) {
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (forwardFlushAndClose) {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFlushedPosition() {
|
||||
return out.getFlushedPosition() - offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation returns false. Subclasses should
|
||||
* override this if they cache data.
|
||||
*/
|
||||
@Override
|
||||
public boolean isCached() {
|
||||
return out.isCached();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation returns false. Subclasses should
|
||||
* override this if they cache data in main memory.
|
||||
*/
|
||||
@Override
|
||||
public boolean isCachedMemory() {
|
||||
return out.isCachedMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCachedFile() {
|
||||
return out.isCachedFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long length() {
|
||||
return length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
out.write(b);
|
||||
length = Math.max(out.getStreamPosition()-offset,length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
out.write(b,off,len);
|
||||
length = Math.max(out.getStreamPosition()-offset,length);
|
||||
}
|
||||
|
||||
public void dispose() throws IOException {
|
||||
if (forwardFlushAndClose) {
|
||||
checkClosed();
|
||||
}
|
||||
out=null;
|
||||
}
|
||||
}
|
||||
155
libsrc/avi/src/org/monte/media/jpeg/JPEGCodec.java
Normal file
155
libsrc/avi/src/org/monte/media/jpeg/JPEGCodec.java
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* @(#)JPGCodec.java
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media.jpeg;
|
||||
|
||||
import org.monte.media.io.ByteArrayImageInputStream;
|
||||
import javax.imageio.ImageReader;
|
||||
import org.monte.media.Format;
|
||||
import org.monte.media.AbstractVideoCodec;
|
||||
import org.monte.media.Buffer;
|
||||
import org.monte.media.io.ByteArrayImageOutputStream;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.IIOImage;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageWriteParam;
|
||||
import javax.imageio.ImageWriter;
|
||||
import static org.monte.media.VideoFormatKeys.*;
|
||||
import static org.monte.media.BufferFlag.*;
|
||||
|
||||
/**
|
||||
* {@code JPEGCodec} encodes a BufferedImage as a byte[] array.
|
||||
* <p>
|
||||
* Supported input formats:
|
||||
* <ul>
|
||||
* {@code VideoFormat} with {@code BufferedImage.class}, any width, any height,
|
||||
* any depth.
|
||||
* </ul>
|
||||
* Supported output formats:
|
||||
* <ul>
|
||||
* {@code VideoFormat} with {@code byte[].class}, same width and height as input
|
||||
* format, depth=24.
|
||||
* </ul>
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: JPEGCodec.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class JPEGCodec extends AbstractVideoCodec {
|
||||
|
||||
public JPEGCodec() {
|
||||
super(new Format[]{
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA,
|
||||
EncodingKey, ENCODING_BUFFERED_IMAGE), //
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_QUICKTIME,
|
||||
EncodingKey, ENCODING_QUICKTIME_JPEG,//
|
||||
CompressorNameKey, COMPRESSOR_NAME_QUICKTIME_JPEG, //
|
||||
DataClassKey, byte[].class, DepthKey, 24), //
|
||||
//
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI,
|
||||
EncodingKey, ENCODING_AVI_MJPG, DataClassKey, byte[].class, DepthKey, 24), //
|
||||
},
|
||||
new Format[]{
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA,
|
||||
EncodingKey, ENCODING_BUFFERED_IMAGE), //
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_QUICKTIME,//
|
||||
EncodingKey, ENCODING_QUICKTIME_JPEG,//
|
||||
CompressorNameKey, COMPRESSOR_NAME_QUICKTIME_JPEG, //
|
||||
DataClassKey, byte[].class, DepthKey, 24), //
|
||||
//
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI,
|
||||
EncodingKey, ENCODING_AVI_MJPG, DataClassKey, byte[].class, DepthKey, 24), //
|
||||
}//
|
||||
);
|
||||
name = "JPEG Codec";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int process(Buffer in, Buffer out) {
|
||||
if (outputFormat.get(EncodingKey).equals(ENCODING_BUFFERED_IMAGE)) {
|
||||
return decode(in, out);
|
||||
} else {
|
||||
return encode(in, out);
|
||||
}
|
||||
}
|
||||
|
||||
public int encode(Buffer in, Buffer out) {
|
||||
out.setMetaTo(in);
|
||||
out.format = outputFormat;
|
||||
if (in.isFlag(DISCARD)) {
|
||||
return CODEC_OK;
|
||||
}
|
||||
BufferedImage image = getBufferedImage(in);
|
||||
if (image == null) {
|
||||
out.setFlag(DISCARD);
|
||||
return CODEC_FAILED;
|
||||
}
|
||||
ByteArrayImageOutputStream tmp;
|
||||
if (out.data instanceof byte[]) {
|
||||
tmp = new ByteArrayImageOutputStream((byte[]) out.data);
|
||||
} else {
|
||||
tmp = new ByteArrayImageOutputStream();
|
||||
}
|
||||
|
||||
try {
|
||||
ImageWriter iw = ImageIO.getImageWritersByMIMEType("image/jpeg").next();
|
||||
ImageWriteParam iwParam = iw.getDefaultWriteParam();
|
||||
iwParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
||||
float quality = outputFormat.get(QualityKey, 1f);
|
||||
iwParam.setCompressionQuality(quality);
|
||||
iw.setOutput(tmp);
|
||||
IIOImage img = new IIOImage(image, null, null);
|
||||
iw.write(null, img, iwParam);
|
||||
iw.dispose();
|
||||
|
||||
out.sampleCount = 1;
|
||||
out.setFlag(KEYFRAME);
|
||||
out.data = tmp.getBuffer();
|
||||
out.offset = 0;
|
||||
out.length = (int) tmp.getStreamPosition();
|
||||
return CODEC_OK;
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
out.setFlag(DISCARD);
|
||||
return CODEC_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
public int decode(Buffer in, Buffer out) {
|
||||
out.setMetaTo(in);
|
||||
out.format = outputFormat;
|
||||
if (in.isFlag(DISCARD)) {
|
||||
return CODEC_OK;
|
||||
}
|
||||
byte[] data = (byte[]) in.data;
|
||||
if (data == null) {
|
||||
out.setFlag(DISCARD);
|
||||
return CODEC_FAILED;
|
||||
}
|
||||
ByteArrayImageInputStream tmp = new ByteArrayImageInputStream(data);
|
||||
|
||||
try {
|
||||
// ImageReader ir = (ImageReader) ImageIO.getImageReadersByMIMEType("image/jpeg").next();
|
||||
ImageReader ir = new MJPGImageReader(new MJPGImageReaderSpi());
|
||||
ir.setInput(tmp);
|
||||
out.data = ir.read(0);
|
||||
ir.dispose();
|
||||
|
||||
out.sampleCount = 1;
|
||||
out.offset = 0;
|
||||
out.length = (int) tmp.getStreamPosition();
|
||||
return CODEC_OK;
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
out.setFlag(DISCARD);
|
||||
return CODEC_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
119
libsrc/avi/src/org/monte/media/jpeg/MJPGImageReader.java
Normal file
119
libsrc/avi/src/org/monte/media/jpeg/MJPGImageReader.java
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* @(#)MJPGImageReader.java
|
||||
*
|
||||
* Copyright (c) 2010-2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media.jpeg;
|
||||
|
||||
import org.monte.media.avi.AVIBMPDIB;
|
||||
import com.sun.imageio.plugins.jpeg.JPEGImageReader;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.stream.MemoryCacheImageInputStream;
|
||||
|
||||
/**
|
||||
* Reads an image in the Motion JPEG (MJPG) format.
|
||||
* <p>.
|
||||
* This class can read Motion JPEG files with omitted Huffmann table.
|
||||
* <p>
|
||||
* For more information see:
|
||||
* Microsoft Windows Bitmap Format.
|
||||
* Multimedia Technical Note: JPEG DIB Format.
|
||||
* (c) 1993 Microsoft Corporation. All rights reserved.
|
||||
* <a href="http://www.fileformat.info/format/bmp/spec/b7c72ebab8064da48ae5ed0c053c67a4/BMPDIB.TXT">BMPDIB.txt</a>
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: MJPGImageReader.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class MJPGImageReader extends ImageReader {
|
||||
|
||||
private static DirectColorModel RGB = new DirectColorModel(24, 0xff0000, 0xff00, 0xff, 0x0);
|
||||
/** When we read the header, we read the whole image. */
|
||||
private BufferedImage image;
|
||||
|
||||
public MJPGImageReader(ImageReaderSpi originatingProvider) {
|
||||
super(originatingProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumImages(boolean allowSearch) throws IOException {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth(int imageIndex) throws IOException {
|
||||
readHeader();
|
||||
return image.getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight(int imageIndex) throws IOException {
|
||||
readHeader();
|
||||
return image.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException {
|
||||
readHeader();
|
||||
LinkedList<ImageTypeSpecifier> l = new LinkedList<ImageTypeSpecifier>();
|
||||
l.add(new ImageTypeSpecifier(RGB, RGB.createCompatibleSampleModel(image.getWidth(), image.getHeight())));
|
||||
return l.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IIOMetadata getStreamMetadata() throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IIOMetadata getImageMetadata(int imageIndex) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException {
|
||||
if (imageIndex > 0) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
readHeader();
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/** Reads the image header.
|
||||
* Does nothing if the header has already been loaded.
|
||||
*/
|
||||
private void readHeader() throws IOException {
|
||||
if (image == null) {
|
||||
ImageReader r = new JPEGImageReader(getOriginatingProvider());
|
||||
Object in = getInput();
|
||||
/*if (in instanceof Buffer) {
|
||||
Buffer buffer = (Buffer) in;
|
||||
in=buffer.getData();
|
||||
}*/
|
||||
if (in instanceof byte[]) {
|
||||
r.setInput(new MemoryCacheImageInputStream(AVIBMPDIB.prependDHTSeg((byte[]) in)));
|
||||
} else if (in instanceof ImageInputStream) {
|
||||
r.setInput(AVIBMPDIB.prependDHTSeg((ImageInputStream) in));
|
||||
} else {
|
||||
r.setInput(AVIBMPDIB.prependDHTSeg((InputStream) in));
|
||||
}
|
||||
image = r.read(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
88
libsrc/avi/src/org/monte/media/jpeg/MJPGImageReaderSpi.java
Normal file
88
libsrc/avi/src/org/monte/media/jpeg/MJPGImageReaderSpi.java
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* @(#)MJPGImageReaderSpi.java
|
||||
*
|
||||
* Copyright (c) 2010-2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media.jpeg;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Locale;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
|
||||
/**
|
||||
* ImageIO service provider interface for images in the Motion JPEG (MJPG)
|
||||
* format.
|
||||
* <p>
|
||||
* The reader described by this class can read Motion JPEG files with omitted
|
||||
* Huffmann table.
|
||||
* <p>
|
||||
* For more information see:
|
||||
* Microsoft Windows Bitmap Format.
|
||||
* Multimedia Technical Note: JPEG DIB Format.
|
||||
* (c) 1993 Microsoft Corporation. All rights reserved.
|
||||
* <a href="http://www.fileformat.info/format/bmp/spec/b7c72ebab8064da48ae5ed0c053c67a4/BMPDIB.TXT">BMPDIB.txt</a>
|
||||
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: MJPGImageReaderSpi.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class MJPGImageReaderSpi extends ImageReaderSpi {
|
||||
|
||||
public MJPGImageReaderSpi() {
|
||||
super("Werner Randelshofer",//vendor name
|
||||
"1.0",//version
|
||||
new String[]{"MJPG"},//names
|
||||
new String[]{"mjpg"},//suffixes,
|
||||
new String[]{"image/mjpg"},// MIMETypes,
|
||||
"org.monte.media.jmf.renderer.video.MJPGImageReader",// readerClassName,
|
||||
new Class[]{ImageInputStream.class,InputStream.class,byte[].class/*,javax.media.Buffer.class*/},// inputTypes,
|
||||
null,// writerSpiNames,
|
||||
false,// supportsStandardStreamMetadataFormat,
|
||||
null,// nativeStreamMetadataFormatName,
|
||||
null,// nativeStreamMetadataFormatClassName,
|
||||
null,// extraStreamMetadataFormatNames,
|
||||
null,// extraStreamMetadataFormatClassNames,
|
||||
false,// supportsStandardImageMetadataFormat,
|
||||
null,// nativeImageMetadataFormatName,
|
||||
null,// nativeImageMetadataFormatClassName,
|
||||
null,// extraImageMetadataFormatNames,
|
||||
null// extraImageMetadataFormatClassNames
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDecodeInput(Object source) throws IOException {
|
||||
if (source instanceof ImageInputStream) {
|
||||
ImageInputStream in = (ImageInputStream) source;
|
||||
in.mark();
|
||||
|
||||
// Check if file starts with a JFIF SOI magic (0xffd8=-40)
|
||||
if (in.readShort() != -40) {
|
||||
in.reset();
|
||||
return false;
|
||||
}
|
||||
in.reset();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageReader createReaderInstance(Object extension) throws IOException {
|
||||
return new MJPGImageReader(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription(Locale locale) {
|
||||
return "MJPG Image Reader";
|
||||
}
|
||||
}
|
||||
250
libsrc/avi/src/org/monte/media/math/IntMath.java
Normal file
250
libsrc/avi/src/org/monte/media/math/IntMath.java
Normal file
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* @(#)IntMath.java
|
||||
*
|
||||
* Copyright (c) 2002-2012 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
|
||||
package org.monte.media.math;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Utility class for integer arithmetic.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: IntMath.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class IntMath {
|
||||
|
||||
/** Creates a new instance of IntMath */
|
||||
public IntMath() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an int whose value is the greatest common divisor of
|
||||
* <tt>abs(a)</tt> and <tt>abs(b)</tt>. Returns 0 if
|
||||
* <tt>a==0 && b==0</tt>.
|
||||
*
|
||||
* @param a value with with the GCD is to be computed.
|
||||
* @param b value with with the GCD is to be computed.
|
||||
* @return <tt>GCD(a, b)</tt>
|
||||
*/
|
||||
public static int gcd(int a, int b) {
|
||||
// Quelle:
|
||||
// Herrmann, D. (1992). Algorithmen Arbeitsbuch.
|
||||
// Bonn, München Paris: Addison Wesley.
|
||||
// ggt6, Seite 63
|
||||
|
||||
a = Math.abs(a);
|
||||
b = Math.abs(b);
|
||||
|
||||
while (a > 0 && b > 0) {
|
||||
a = a % b;
|
||||
if (a > 0) b = b % a;
|
||||
}
|
||||
return a + b;
|
||||
}
|
||||
/**
|
||||
* Returns a long whose value is the greatest common divisor of
|
||||
* <tt>abs(a)</tt> and <tt>abs(b)</tt>. Returns 0 if
|
||||
* <tt>a==0 && b==0</tt>.
|
||||
*
|
||||
* @param a value with with the GCD is to be computed.
|
||||
* @param b value with with the GCD is to be computed.
|
||||
* @return <tt>GCD(a, b)</tt>
|
||||
*/
|
||||
public static long gcd(long a, long b) {
|
||||
// Quelle:
|
||||
// Herrmann, D. (1992). Algorithmen Arbeitsbuch.
|
||||
// Bonn, München Paris: Addison Wesley.
|
||||
// ggt6, Seite 63
|
||||
|
||||
a = Math.abs(a);
|
||||
b = Math.abs(b);
|
||||
|
||||
while (a > 0 && b > 0) {
|
||||
a = a % b;
|
||||
if (a > 0) b = b % a;
|
||||
}
|
||||
return a + b;
|
||||
}
|
||||
/**
|
||||
* Returns a long whose value is the greatest common divisor of
|
||||
* <tt>abs(a)</tt> and <tt>abs(b)</tt>. Returns 0 if
|
||||
* <tt>a==0 && b==0</tt>.
|
||||
*
|
||||
* @param a value with with the GCD is to be computed.
|
||||
* @param b value with with the GCD is to be computed.
|
||||
* @return <tt>GCD(a, b)</tt>
|
||||
*/
|
||||
public static BigInteger gcd(BigInteger a, BigInteger b) {
|
||||
// Quelle:
|
||||
// Herrmann, D. (1992). Algorithmen Arbeitsbuch.
|
||||
// Bonn, München Paris: Addison Wesley.
|
||||
// ggt6, Seite 63
|
||||
|
||||
a = a.abs();
|
||||
b = b.abs();
|
||||
|
||||
while (a.compareTo(BigInteger.ZERO) > 0 && b.compareTo(BigInteger.ZERO) > 0) {
|
||||
a = a.mod(b);
|
||||
if (a.compareTo(BigInteger.ZERO) > 0) b = b.mod(a);
|
||||
}
|
||||
return a.add(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an int whose value is the smallest common multiple of
|
||||
* <tt>abs(a)</tt> and <tt>abs(b)</tt>. Returns 0 if
|
||||
* <tt>a==0 || b==0</tt>.
|
||||
*
|
||||
* @param a value with with the SCM is to be computed.
|
||||
* @param b value with with the SCM is to be computed.
|
||||
* @return <tt>SCM(a, b)</tt>
|
||||
*/
|
||||
public static int scm(int a, int b) {
|
||||
// Quelle:
|
||||
// Herrmann, D. (1992). Algorithmen Arbeitsbuch.
|
||||
// Bonn, München Paris: Addison Wesley.
|
||||
// gill, Seite 141
|
||||
|
||||
if (a == 0 || b == 0) return 0;
|
||||
|
||||
a = Math.abs(a);
|
||||
b = Math.abs(b);
|
||||
|
||||
int u = a;
|
||||
int v = b;
|
||||
|
||||
while (a != b) {
|
||||
if (a < b) {
|
||||
b -= a;
|
||||
v += u;
|
||||
} else {
|
||||
a -= b;
|
||||
u += v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//return a; // gcd
|
||||
return (u + v) / 2; // scm
|
||||
}
|
||||
/**
|
||||
* Returns an int whose value is the smallest common multiple of
|
||||
* <tt>abs(a)</tt> and <tt>abs(b)</tt>. Returns 0 if
|
||||
* <tt>a==0 || b==0</tt>.
|
||||
*
|
||||
* @param a value with with the SCM is to be computed.
|
||||
* @param b value with with the SCM is to be computed.
|
||||
* @return <tt>SCM(a, b)</tt>
|
||||
*/
|
||||
public static long scm(long a, long b) {
|
||||
// Quelle:
|
||||
// Herrmann, D. (1992). Algorithmen Arbeitsbuch.
|
||||
// Bonn, München Paris: Addison Wesley.
|
||||
// gill, Seite 141
|
||||
|
||||
if (a == 0 || b == 0) return 0;
|
||||
|
||||
a = Math.abs(a);
|
||||
b = Math.abs(b);
|
||||
if (b==1)return a;
|
||||
if (a==1)return b;
|
||||
|
||||
long u = a;
|
||||
long v = b;
|
||||
|
||||
// FIXME - Handle overflow
|
||||
while (a != b) {
|
||||
if (a < b) {
|
||||
b -= a;
|
||||
v += u;
|
||||
} else {
|
||||
a -= b;
|
||||
u += v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//return a; // gcd
|
||||
return (u + v) / 2; // scm
|
||||
}
|
||||
/**
|
||||
* Returns an int whose value is the smallest common multiple of
|
||||
* <tt>abs(a)</tt> and <tt>abs(b)</tt>. Returns 0 if
|
||||
* <tt>a==0 || b==0</tt>.
|
||||
*
|
||||
* @param a value with with the SCM is to be computed.
|
||||
* @param b value with with the SCM is to be computed.
|
||||
* @return <tt>SCM(a, b)</tt>
|
||||
*/
|
||||
public static BigInteger scm(BigInteger a, BigInteger b) {
|
||||
// Quelle:
|
||||
// Herrmann, D. (1992). Algorithmen Arbeitsbuch.
|
||||
// Bonn, München Paris: Addison Wesley.
|
||||
// gill, Seite 141
|
||||
|
||||
if (a.compareTo(BigInteger.ZERO) == 0 || b.compareTo(BigInteger.ZERO) == 0) {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
|
||||
a = a.abs();
|
||||
b = b.abs();
|
||||
if (b.compareTo(BigInteger.ONE)==0)return a;
|
||||
if (a.compareTo(BigInteger.ONE)==0)return b;
|
||||
|
||||
BigInteger u = a;
|
||||
BigInteger v = b;
|
||||
|
||||
// FIXME - Handle overflow
|
||||
while (a.compareTo(b) != 0) {
|
||||
if (a .compareTo( b)<0) {
|
||||
b = b.subtract(a);
|
||||
v = v.add(u);
|
||||
} else {
|
||||
a = a.subtract(b);
|
||||
u = u.add(v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//return a; // gcd
|
||||
return (u.add(v)).divide(BigInteger.valueOf(2)); // scm
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverses all 32 bits of the provided integer value.
|
||||
*/
|
||||
public static int reverseBits(int a) {
|
||||
return reverseBits(a, 32);
|
||||
}
|
||||
/**
|
||||
* Reverses specified number of bits of the provided integer value.
|
||||
* @param a The number.
|
||||
* @param numBits The number of bits (must be between 1 and 32).
|
||||
*/
|
||||
public static int reverseBits(int a, int numBits) {
|
||||
int b = 0;
|
||||
for (int i=0; i < numBits; i++) {
|
||||
b <<= 1;
|
||||
b |= (a & 1);
|
||||
a >>>= 1;
|
||||
}
|
||||
return b;
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
for (int i=0; i < 8; i++) {
|
||||
int a = 1<<i;
|
||||
int b = reverseBits(a, 3);
|
||||
System.out.println(a+" - "+b);
|
||||
}
|
||||
}
|
||||
}
|
||||
492
libsrc/avi/src/org/monte/media/math/Rational.java
Normal file
492
libsrc/avi/src/org/monte/media/math/Rational.java
Normal file
@@ -0,0 +1,492 @@
|
||||
/*
|
||||
* @(#)Rational.java
|
||||
*
|
||||
* Copyright (c) 2009-2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media.math;
|
||||
|
||||
import static java.lang.Math.*;
|
||||
import java.math.BigInteger;
|
||||
import static org.monte.media.math.IntMath.*;
|
||||
|
||||
/**
|
||||
* Represents a TIFF RATIONAL number. <p> Two LONGs 32-bit (4-byte) unsigned
|
||||
* integer: the first represents the numerator of a fraction; the second, the
|
||||
* denominator. </p> <p> Invariants: </p> <ul> <li>denominator>=0, the
|
||||
* denominator is always a positive integer</li> <li>0/1 is the unique
|
||||
* representation of 0.</li> <li>1/0,-1/0 are the unique representations of
|
||||
* infinity.</li> </ul>
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: Rational.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class Rational extends Number {
|
||||
|
||||
public static final Rational ONE = new Rational(1, 1,false);
|
||||
public static final Rational ZERO = new Rational(0, 1,false);
|
||||
public static final long serialVersionUID = 1L;
|
||||
private final long num;
|
||||
private final long den;
|
||||
|
||||
public Rational(long numerator) {
|
||||
this(numerator, 1);
|
||||
}
|
||||
|
||||
public Rational(long numerator, long denominator) {
|
||||
this(numerator, denominator, true);
|
||||
}
|
||||
|
||||
private Rational(long numerator, long denominator, boolean reduceFraction) {
|
||||
if (numerator == 0) {
|
||||
// Invariant: 0/1 is unique representation of 0
|
||||
denominator = 1;
|
||||
}
|
||||
|
||||
if (denominator == 0) {
|
||||
// Invariant: 1/0, -1/0 are unique representations of infinity
|
||||
numerator = (numerator > 0) ? 1 : -1;
|
||||
} else if (denominator < 0) {
|
||||
// Invariant: denominator is always positive
|
||||
denominator = -denominator;
|
||||
numerator = -numerator;
|
||||
}
|
||||
|
||||
if (reduceFraction) {
|
||||
long g = gcd(numerator, denominator);
|
||||
num = numerator / g;
|
||||
den = denominator / g;
|
||||
} else {
|
||||
num = numerator;
|
||||
den = denominator;
|
||||
}
|
||||
}
|
||||
|
||||
private Rational(BigInteger numerator, BigInteger denominator, boolean reduceFraction) {
|
||||
if (numerator.equals(BigInteger.ZERO)) {
|
||||
// Invariant: 0/1 is unique representation of 0
|
||||
denominator = BigInteger.ONE;
|
||||
}
|
||||
|
||||
if (denominator.equals(BigInteger.ZERO)) {
|
||||
// Invariant: 1/0, -1/0 are unique representations of infinity
|
||||
numerator = (numerator.compareTo(BigInteger.ZERO) > 0) ? BigInteger.ONE : BigInteger.ONE.negate();
|
||||
} else if (denominator.compareTo(BigInteger.ZERO) < 0) {
|
||||
// Invariant: denominator is always positive
|
||||
denominator = denominator.negate();
|
||||
numerator = numerator.negate();
|
||||
}
|
||||
|
||||
BigInteger numB, denB;
|
||||
if (reduceFraction) {
|
||||
BigInteger g = gcd(numerator, denominator);
|
||||
numB = numerator.divide(g);
|
||||
denB = denominator.divide(g);
|
||||
} else {
|
||||
numB = numerator;
|
||||
denB = denominator;
|
||||
}
|
||||
int bitLength = Math.max(numB.bitLength(), denB.bitLength());
|
||||
if (bitLength > 63) {
|
||||
numB = numB.shiftRight(bitLength - 63);
|
||||
denB = denB.shiftRight(bitLength - 63);
|
||||
if (numB.equals(BigInteger.ZERO)) {
|
||||
// Invariant: 0/1 is unique representation of 0
|
||||
denB = BigInteger.ONE;
|
||||
}
|
||||
|
||||
if (denB.equals(BigInteger.ZERO)) {
|
||||
// Invariant: 1/0, -1/0 are unique representations of infinity
|
||||
numB = (numB.compareTo(BigInteger.ZERO) > 0) ? BigInteger.ONE : BigInteger.ONE.negate();
|
||||
|
||||
}
|
||||
}
|
||||
num = numB.longValue();
|
||||
den = denB.longValue();
|
||||
}
|
||||
|
||||
public Rational(Rational r) {
|
||||
this(r.num, r.den);
|
||||
}
|
||||
|
||||
public long getNumerator() {
|
||||
return num;
|
||||
}
|
||||
|
||||
public long getDenominator() {
|
||||
return den;
|
||||
}
|
||||
|
||||
public Rational add(Rational that) {
|
||||
return add(that, true);
|
||||
}
|
||||
|
||||
private Rational add(Rational that, boolean reduceFraction) {
|
||||
if (this.den == that.den) {
|
||||
// => same denominator: add numerators
|
||||
return new Rational(this.num + that.num, this.den, reduceFraction);
|
||||
}
|
||||
|
||||
// FIXME - handle overflow
|
||||
long s = scm(this.den, that.den);
|
||||
Rational result = new Rational(
|
||||
this.num * (s / this.den) + that.num * (s / that.den),
|
||||
s, reduceFraction);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Warning. Rational is supposed to be immutable. *
|
||||
*
|
||||
* private Rational addAssign(Rational that) { if (this.den == that.den) {
|
||||
* // => same denominator: add numerators this.num += that.num; return this;
|
||||
* }
|
||||
*
|
||||
* // FIXME - handle overflow long s = scm(this.den, that.den); this.num =
|
||||
* this.num * (s / this.den) + that.num * (s / that.den); this.den = s;
|
||||
*
|
||||
*
|
||||
* return reduceAssign(); }
|
||||
*/
|
||||
public Rational subtract(Rational that) {
|
||||
return add(that.negate());
|
||||
}
|
||||
|
||||
public Rational negate() {
|
||||
return valueOf(-num, den);
|
||||
}
|
||||
|
||||
public Rational inverse() {
|
||||
return valueOf(den, num, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the closest rational with the specified denominator which is
|
||||
* smaller or equal than this number.
|
||||
*/
|
||||
public Rational floor(long d) {
|
||||
if (d == den) {
|
||||
return valueOf(num, den);
|
||||
}
|
||||
long s = scm(this.den, d);
|
||||
|
||||
if (s == d) {
|
||||
return valueOf(num * s / den, d);
|
||||
} else if (s == den) {
|
||||
return valueOf(num * d / den, d);
|
||||
} else {
|
||||
return valueOf(num * d / den, d);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the closest rational with the specified denominator which is
|
||||
* greater or equal than this number.
|
||||
*/
|
||||
public Rational ceil(long d) {
|
||||
if (d == den) {
|
||||
return valueOf(num, den);
|
||||
}
|
||||
long s = scm(this.den, d);
|
||||
|
||||
if (s == d) {
|
||||
return valueOf((num * s + den - 1) / den, d);
|
||||
} else if (s == den) {
|
||||
return valueOf((num * d + den - 1) / den, d);
|
||||
} else {
|
||||
return valueOf((num * d + den - 1) / den, d);
|
||||
}
|
||||
}
|
||||
|
||||
public Rational multiply(Rational that) {
|
||||
if (abs(this.num) < Integer.MAX_VALUE
|
||||
&& abs(this.den) < Integer.MAX_VALUE
|
||||
&& abs(that.num) < Integer.MAX_VALUE
|
||||
&& abs(that.den) < Integer.MAX_VALUE) {
|
||||
return valueOf(this.num * that.num,
|
||||
this.den * that.den);
|
||||
} else {
|
||||
return new Rational(
|
||||
BigInteger.valueOf(this.num).multiply(BigInteger.valueOf(that.num)),
|
||||
BigInteger.valueOf(this.den).multiply(BigInteger.valueOf(that.den)),
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
public Rational multiply(long integer) {
|
||||
if (integer==0) {
|
||||
return ZERO;
|
||||
} else if (this.den % integer == 0) {
|
||||
return valueOf(
|
||||
this.num,
|
||||
this.den / integer);
|
||||
} else if (abs(this.num) < Integer.MAX_VALUE
|
||||
&& abs(integer) < Integer.MAX_VALUE) {
|
||||
return valueOf(
|
||||
this.num * integer,
|
||||
this.den);
|
||||
} else {
|
||||
return new Rational(
|
||||
BigInteger.valueOf(this.num).multiply(BigInteger.valueOf(integer)),
|
||||
BigInteger.valueOf(this.den), true);
|
||||
}
|
||||
}
|
||||
|
||||
public Rational divide(Rational that) {
|
||||
if (abs(this.num) < Integer.MAX_VALUE
|
||||
&& abs(this.den) < Integer.MAX_VALUE
|
||||
&& abs(that.num) < Integer.MAX_VALUE
|
||||
&& abs(that.den) < Integer.MAX_VALUE) {
|
||||
return valueOf(this.num * that.den,
|
||||
this.den * that.num);
|
||||
} else {
|
||||
return valueOf(
|
||||
BigInteger.valueOf(this.num).multiply(BigInteger.valueOf(that.den)),
|
||||
BigInteger.valueOf(this.den).multiply(BigInteger.valueOf(that.num)),
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
//long gcd = IntMath.gcd(num, den);
|
||||
if (num == 0) {
|
||||
return "0";
|
||||
} else if (den == 1) {
|
||||
return Long.toString(num);
|
||||
} else {
|
||||
return num + "/" + den;
|
||||
/*
|
||||
} else {
|
||||
return Float.toString((float) num / den);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
public String toDescriptiveString() {
|
||||
long gcd = IntMath.gcd(num, den);
|
||||
if (gcd == 0 || num == 0) {
|
||||
return num + "/" + den + " = " + 0;
|
||||
} else if (gcd == den) {
|
||||
return num + "/" + den + " = " + Long.toString(num / den);
|
||||
} else {
|
||||
return num + "/" + den + " ≈ " + ((float) num / den);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int intValue() {
|
||||
return (int) (num / den);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long longValue() {
|
||||
return num / den;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float floatValue() {
|
||||
return (float) num / (float) den;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double doubleValue() {
|
||||
return (double) num / (double) den;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final Rational that = (Rational) obj;
|
||||
|
||||
return compareTo(that) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* return { -1, 0, +1 } if a < b, a = b, or a > b.
|
||||
*/
|
||||
public int compareTo(Rational that) {
|
||||
// The following code avoids BigInteger allocation if the denominators
|
||||
// are equal
|
||||
if (this.den == that.den) {
|
||||
if (this.num < that.num) {
|
||||
return -1;
|
||||
} else if (this.num > that.num) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Work with longs if overflow can not occur
|
||||
if (abs(this.num) < Integer.MAX_VALUE
|
||||
&& abs(this.den) < Integer.MAX_VALUE
|
||||
&& abs(that.num) < Integer.MAX_VALUE
|
||||
&& abs(that.den) < Integer.MAX_VALUE) {
|
||||
long lhs = this.num * that.den;
|
||||
long rhs = this.den * that.num;
|
||||
if (lhs < rhs) {
|
||||
return -1;
|
||||
} else if (lhs > rhs) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Use big integers to avoid overflows
|
||||
BigInteger lhs;
|
||||
BigInteger rhs;
|
||||
lhs = BigInteger.valueOf(this.num).multiply(BigInteger.valueOf(that.den));
|
||||
rhs = BigInteger.valueOf(this.den).multiply(BigInteger.valueOf(that.num));
|
||||
|
||||
return lhs.compareTo(rhs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (int) ((num ^ (num >>> 32))
|
||||
^ (den ^ (den >>> 32)));
|
||||
|
||||
}
|
||||
|
||||
public static Rational max(Rational a, Rational b) {
|
||||
return (a.compareTo(b) >= 0) ? a : b;
|
||||
}
|
||||
|
||||
public static Rational min(Rational a, Rational b) {
|
||||
return (a.compareTo(b) <= 0) ? a : b;
|
||||
}
|
||||
|
||||
public boolean isZero() {
|
||||
return num == 0;
|
||||
}
|
||||
|
||||
public boolean isLessOrEqualZero() {
|
||||
return num <= 0;
|
||||
}
|
||||
|
||||
public static Rational valueOf(double d) {
|
||||
if (d == 0) {
|
||||
return valueOf(0, 1);
|
||||
}
|
||||
if (abs(d) > Integer.MAX_VALUE) {
|
||||
throw new IllegalArgumentException("Value " + d + " is too big.");
|
||||
}
|
||||
if (Double.isInfinite(d)) {
|
||||
return valueOf((long) signum(d), 0);
|
||||
}
|
||||
if (Double.isNaN(d)) {
|
||||
return valueOf(0, 1); // no way to express a NaN :-(
|
||||
}
|
||||
return toRational(d, Integer.MAX_VALUE, 100);
|
||||
}
|
||||
|
||||
public static Rational valueOf(long num, long den) {
|
||||
return valueOf(num, den, true);
|
||||
}
|
||||
|
||||
private static Rational valueOf(long num, long den, boolean reduceFraction) {
|
||||
if (num == den) {
|
||||
return ONE;
|
||||
}
|
||||
if (num == 0) {
|
||||
return ZERO;
|
||||
}
|
||||
return new Rational(num, den, reduceFraction);
|
||||
}
|
||||
|
||||
public static Rational valueOf(BigInteger num, BigInteger den) {
|
||||
return valueOf(num, den, true);
|
||||
}
|
||||
|
||||
private static Rational valueOf(BigInteger num, BigInteger den, boolean reduceFraction) {
|
||||
if (num.equals(den)) {
|
||||
return ONE;
|
||||
}
|
||||
if (num.equals(BigInteger.ZERO)) {
|
||||
return ZERO;
|
||||
}
|
||||
return new Rational(num, den, reduceFraction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iteratively computes rational from double. <p>Reference:<br> <a
|
||||
* href="http://www2.fz-juelich.de/video/cpp/html/exercises/exercise/Rational_cpp.html">
|
||||
* http://www2.fz-juelich.de/video/cpp/html/exercises/exercise/Rational_cpp.html</a>
|
||||
* </p>
|
||||
*/
|
||||
private static Rational toRational(double x, double limit, int iterations) {
|
||||
double intpart = Math.floor(x);
|
||||
double fractpart = x - intpart;
|
||||
double d = 1.0 / fractpart;
|
||||
long left = (long) intpart;
|
||||
if (d > limit || iterations == 0) {
|
||||
return valueOf(left, 1, false);
|
||||
} else {
|
||||
return valueOf(left, 1, false).add(toRational(d, limit * 0.1, iterations - 1).inverse(), false);
|
||||
}
|
||||
}
|
||||
|
||||
public Rational round(long d) {
|
||||
if (d == den) {
|
||||
return valueOf(num, den);
|
||||
}
|
||||
|
||||
Rational fl = floor(d);
|
||||
Rational diffFl = subtract(fl);
|
||||
|
||||
if (diffFl.isZero()) {
|
||||
return fl;
|
||||
}
|
||||
|
||||
Rational cl = ceil(d);
|
||||
Rational diffCl = subtract(cl);
|
||||
if (diffCl.isZero()) {
|
||||
return cl;
|
||||
}
|
||||
|
||||
if (diffFl.isNegative()) {
|
||||
diffFl = diffFl.negate();
|
||||
}
|
||||
if (diffCl.isNegative()) {
|
||||
diffCl = diffCl.negate();
|
||||
}
|
||||
return diffFl.compareTo(diffCl) <= 0 ? fl : cl;
|
||||
}
|
||||
|
||||
private boolean isNegative() {
|
||||
return num < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string.
|
||||
*
|
||||
* A rational can be represented in the following ways: <li>As a long
|
||||
* number</li> <li>As a double number</li> <li>As an integer/integer
|
||||
* rational number</li>
|
||||
*
|
||||
* @throws NumberFormatException if str can not be parsed.
|
||||
*/
|
||||
public static Rational valueOf(String str) {
|
||||
int p = str.indexOf('/');
|
||||
if (p != -1) {
|
||||
return valueOf(Long.valueOf(str.substring(0, p)), Long.valueOf(str.substring(p + 1)));
|
||||
}
|
||||
try {
|
||||
return valueOf(Long.valueOf(str));
|
||||
} catch (NumberFormatException e) {
|
||||
return valueOf(Double.valueOf(str));
|
||||
}
|
||||
}
|
||||
}
|
||||
118
libsrc/avi/src/org/monte/media/png/PNGCodec.java
Normal file
118
libsrc/avi/src/org/monte/media/png/PNGCodec.java
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* @(#)PNGCodec.java
|
||||
*
|
||||
* Copyright (c) 2011-2012 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media.png;
|
||||
|
||||
import org.monte.media.Format;
|
||||
import org.monte.media.AbstractVideoCodec;
|
||||
import org.monte.media.Buffer;
|
||||
import org.monte.media.io.ByteArrayImageOutputStream;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.IIOImage;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageWriteParam;
|
||||
import javax.imageio.ImageWriter;
|
||||
import static org.monte.media.VideoFormatKeys.*;
|
||||
import static org.monte.media.BufferFlag.*;
|
||||
|
||||
/**
|
||||
* {@code PNGCodec} encodes a BufferedImage as a byte[] array..
|
||||
* <p>
|
||||
* Supported input formats:
|
||||
* <ul>
|
||||
* {@code VideoFormat} with {@code BufferedImage.class}, any width, any height,
|
||||
* any depth.
|
||||
* </ul>
|
||||
* Supported output formats:
|
||||
* <ul>
|
||||
* {@code VideoFormat} with {@code byte[].class}, same width and height as input
|
||||
* format, depth=24.
|
||||
* </ul>
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: PNGCodec.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class PNGCodec extends AbstractVideoCodec {
|
||||
|
||||
public PNGCodec() {
|
||||
super(new Format[]{
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_JAVA,
|
||||
EncodingKey, ENCODING_BUFFERED_IMAGE), //
|
||||
},
|
||||
new Format[]{
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_QUICKTIME,
|
||||
DepthKey, 24,
|
||||
EncodingKey, ENCODING_QUICKTIME_PNG, DataClassKey, byte[].class), //
|
||||
//
|
||||
new Format(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI,
|
||||
DepthKey, 24,
|
||||
EncodingKey, ENCODING_AVI_PNG, DataClassKey, byte[].class), //
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Format setOutputFormat(Format f) {
|
||||
String mimeType = f.get(MimeTypeKey, MIME_QUICKTIME);
|
||||
if (mimeType != null && !mimeType.equals(MIME_AVI)) {
|
||||
return super.setOutputFormat(
|
||||
f.prepend(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_QUICKTIME,
|
||||
EncodingKey, ENCODING_QUICKTIME_PNG, DataClassKey,
|
||||
byte[].class, DepthKey, 24));
|
||||
} else {
|
||||
return super.setOutputFormat(
|
||||
f.prepend(MediaTypeKey, MediaType.VIDEO, MimeTypeKey, MIME_AVI,
|
||||
EncodingKey, ENCODING_AVI_PNG, DataClassKey,
|
||||
byte[].class, DepthKey, 24));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int process(Buffer in, Buffer out) {
|
||||
out.setMetaTo(in);
|
||||
out.format = outputFormat;
|
||||
if (in.isFlag(DISCARD)) {
|
||||
return CODEC_OK;
|
||||
}
|
||||
|
||||
BufferedImage image = getBufferedImage(in);
|
||||
if (image == null) {
|
||||
out.setFlag(DISCARD);
|
||||
return CODEC_FAILED;
|
||||
}
|
||||
|
||||
ByteArrayImageOutputStream tmp;
|
||||
if (out.data instanceof byte[]) {
|
||||
tmp = new ByteArrayImageOutputStream((byte[]) out.data);
|
||||
} else {
|
||||
tmp = new ByteArrayImageOutputStream();
|
||||
}
|
||||
|
||||
try {
|
||||
ImageWriter iw = ImageIO.getImageWritersByMIMEType("image/png").next();
|
||||
ImageWriteParam iwParam = iw.getDefaultWriteParam();
|
||||
iw.setOutput(tmp);
|
||||
IIOImage img = new IIOImage(image, null, null);
|
||||
iw.write(null, img, iwParam);
|
||||
iw.dispose();
|
||||
|
||||
out.setFlag(KEYFRAME);
|
||||
out.header = null;
|
||||
out.data = tmp.getBuffer();
|
||||
out.offset = 0;
|
||||
out.length = (int) tmp.getStreamPosition();
|
||||
return CODEC_OK;
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
out.setFlag(DISCARD);
|
||||
return CODEC_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
188
libsrc/avi/src/org/monte/media/riff/RIFFChunk.java
Normal file
188
libsrc/avi/src/org/monte/media/riff/RIFFChunk.java
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* @(#)RIFFChunk.java
|
||||
*
|
||||
* Copyright (c) 2005-2012 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media.riff;
|
||||
|
||||
import java.util.*;
|
||||
/**
|
||||
* RIFF Chunks form the building blocks of a RIFF file.
|
||||
*
|
||||
* @author Werner Randelshofer, Hausmatt 10, CH-6405 Goldau, Switzerland
|
||||
* @version $Id: RIFFChunk.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
public class RIFFChunk {
|
||||
private int id;
|
||||
private int type;
|
||||
private long size;
|
||||
private long scan;
|
||||
private byte[] data;
|
||||
private Hashtable<RIFFChunk,RIFFChunk> propertyChunks;
|
||||
private ArrayList<RIFFChunk> collectionChunks;
|
||||
/**
|
||||
* This is used to display parser messages, when the parser encounters and
|
||||
* error while parsing the chunk.
|
||||
*/
|
||||
private String parserMessage;
|
||||
|
||||
public RIFFChunk(int type, int id) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
size = -1;
|
||||
scan = -1;
|
||||
}
|
||||
public RIFFChunk(int type, int id, long size, long scan) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
this.size = size;
|
||||
this.scan = scan;
|
||||
}
|
||||
public RIFFChunk(int type, int id, long size, long scan, RIFFChunk propGroup) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
this.size = size;
|
||||
this.scan = scan;
|
||||
if (propGroup != null) {
|
||||
if (propGroup.propertyChunks != null) {
|
||||
propertyChunks = new Hashtable<RIFFChunk,RIFFChunk>(propGroup.propertyChunks);
|
||||
}
|
||||
if (propGroup.collectionChunks != null) {
|
||||
collectionChunks = new ArrayList<RIFFChunk>(propGroup.collectionChunks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ID of chunk.
|
||||
*/
|
||||
public int getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Type of chunk.
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Size of chunk.
|
||||
*/
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Scan position of chunk within the file.
|
||||
*/
|
||||
public long getScan() {
|
||||
return scan;
|
||||
}
|
||||
|
||||
public void putPropertyChunk(RIFFChunk chunk) {
|
||||
if (propertyChunks == null) {
|
||||
propertyChunks = new Hashtable<RIFFChunk,RIFFChunk> ();
|
||||
}
|
||||
propertyChunks.put(chunk,chunk);
|
||||
}
|
||||
|
||||
public RIFFChunk getPropertyChunk(int id) {
|
||||
if (propertyChunks == null) {
|
||||
return null;
|
||||
}
|
||||
RIFFChunk chunk = new RIFFChunk(type, id);
|
||||
return propertyChunks.get(chunk);
|
||||
}
|
||||
|
||||
public Enumeration propertyChunks() {
|
||||
if (propertyChunks == null) {
|
||||
propertyChunks = new Hashtable<RIFFChunk,RIFFChunk> ();
|
||||
}
|
||||
return propertyChunks.keys();
|
||||
}
|
||||
|
||||
public void addCollectionChunk(RIFFChunk chunk) {
|
||||
if (collectionChunks == null) {
|
||||
collectionChunks = new ArrayList<RIFFChunk>();
|
||||
}
|
||||
collectionChunks.add(chunk);
|
||||
}
|
||||
|
||||
public RIFFChunk[] getCollectionChunks(int id) {
|
||||
if (collectionChunks == null) {
|
||||
return new RIFFChunk[0];
|
||||
}
|
||||
Iterator<RIFFChunk> enm = collectionChunks.iterator();
|
||||
int i = 0;
|
||||
while ( enm.hasNext() ) {
|
||||
RIFFChunk chunk = enm.next();
|
||||
if (chunk.id==id) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
RIFFChunk[] array = new RIFFChunk[i];
|
||||
i = 0;
|
||||
enm = collectionChunks.iterator();
|
||||
while ( enm.hasNext() ) {
|
||||
RIFFChunk chunk = enm.next();
|
||||
if (chunk.id==id) {
|
||||
array[i++] = chunk;
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
public Iterator collectionChunks() {
|
||||
if (collectionChunks == null) {
|
||||
collectionChunks = new ArrayList<RIFFChunk>();
|
||||
}
|
||||
return collectionChunks.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data.
|
||||
* Note: The array will not be cloned.
|
||||
*/
|
||||
public void setData(byte[] data) {
|
||||
this.data = data;
|
||||
}
|
||||
/**
|
||||
* Gets the data.
|
||||
* Note: The array will not be cloned.
|
||||
*/
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object another) {
|
||||
if (another instanceof RIFFChunk) {
|
||||
RIFFChunk that = (RIFFChunk) another;
|
||||
return (that.id==this.id) && (that.type==this.type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setParserMessage(String newValue) {
|
||||
this.parserMessage = newValue;
|
||||
}
|
||||
public String getParserMessage() {
|
||||
return this.parserMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString()+"{"+RIFFParser.idToString(getType())+","+RIFFParser.idToString(getID())+"}";
|
||||
}
|
||||
}
|
||||
841
libsrc/avi/src/org/monte/media/riff/RIFFParser.java
Normal file
841
libsrc/avi/src/org/monte/media/riff/RIFFParser.java
Normal file
@@ -0,0 +1,841 @@
|
||||
/*
|
||||
* @(#)RIFFParser.java 1.5 2012-08-03
|
||||
*
|
||||
* Copyright (c) 2005-2012 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media.riff;
|
||||
|
||||
import org.monte.media.AbortException;
|
||||
import org.monte.media.ParseException;
|
||||
import org.monte.media.io.ImageInputStreamAdapter;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.WeakHashMap;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
/**
|
||||
* Interprets Resource Interchange File Format (RIFF) streams.
|
||||
*
|
||||
* <p><b>Abstract</b>
|
||||
* <p>
|
||||
* <b>RIFF File Format</b>
|
||||
* A RIFF file consists of a RIFF header followed by zero or more lists and chunks.
|
||||
* <p>
|
||||
* The RIFF header has the following form:
|
||||
* <pre>
|
||||
* 'RIFF' fileSize fileType (data)
|
||||
* </pre>
|
||||
* where 'RIFF' is the literal FOURCC code 'RIFF', fileSize is a 4-byte value
|
||||
* giving the size of the data in the file, and fileType is a FOURCC that
|
||||
* identifies the specific file type. The value of fileSize includes the size
|
||||
* of the fileType FOURCC plus the size of the data that follows, but does not
|
||||
* include the size of the 'RIFF' FOURCC or the size of fileSize. The file data
|
||||
* consists of chunks and lists, in any order.
|
||||
* <p>
|
||||
* <b>FOURCCs</b><br>
|
||||
* A FOURCC (four-character code) is a 32-bit unsigned integer created by
|
||||
* concatenating four ASCII characters. For example, the FOURCC 'abcd' is
|
||||
* represented on a Little-Endian system as 0x64636261. FOURCCs can contain
|
||||
* space characters, so ' abc' is a valid FOURCC. The RIFF file format uses
|
||||
* FOURCC codes to identify stream types, data chunks, index entries, and other
|
||||
* information.
|
||||
* <p>
|
||||
* A chunk has the following form:
|
||||
* <pre>
|
||||
* ckID ckSize ckData
|
||||
* </pre>
|
||||
* where ckID is a FOURCC that identifies the data contained in the chunk,
|
||||
* ckData is a 4-byte value giving the size of the data in ckData, and ckData is
|
||||
* zero or more bytes of data. The data is always padded to nearest WORD boundary.
|
||||
* ckSize gives the size of the valid data in the chunk; it does not include
|
||||
* the padding, the size of ckID, or the size of ckSize.
|
||||
* <p>
|
||||
* A list has the following form:
|
||||
* <pre>
|
||||
* 'LIST' listSize listType listData
|
||||
* </pre>
|
||||
* where 'LIST' is the literal FOURCC code 'LIST', listSize is a 4-byte value
|
||||
* giving the size of the list, listType is a FOURCC code, and listData consists
|
||||
* of chunks or lists, in any order. The value of listSize includes the size of
|
||||
* listType plus the size of listData; it does not include the 'LIST' FOURCC or
|
||||
* the size of listSize.
|
||||
* <p>
|
||||
* For more information see:
|
||||
* http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/htm/avirifffilereference.asp
|
||||
* http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/htm/aboutriff.asp
|
||||
* <p>
|
||||
* <p><b>Grammar for RIFF streams used by this parser</b>
|
||||
* <pre>
|
||||
* RIFFFile ::= 'RIFF' FormGroup
|
||||
* <br>
|
||||
* GroupChunk ::= FormGroup | ListGroup
|
||||
* FormGroup ::= size GroupType [ ChunkID LocalChunk [pad] | 'LIST ' ListGroup [pad] }
|
||||
* ListGroup ::= size GroupType [ ChunkID LocalChunk [pad] | 'LIST ' ListGroup [pad] }
|
||||
* <br>
|
||||
* LocalChunk ::= DataChunk | CollectionChunk | PropertyChunk
|
||||
* DataChunk ::= size [ struct ]
|
||||
* CollectionChunk ::= size [ struct ]
|
||||
* PropertyChunk ::= size [ struct ]
|
||||
* <br>
|
||||
* size ::= ULONG
|
||||
* GroupType ::= FourCC
|
||||
* ChunkID ::= FourCC
|
||||
* pad ::= (BYTE)0
|
||||
* struct ::= any C language struct built with primitive data types.
|
||||
* </pre>
|
||||
*
|
||||
* <p><b>Examples</b>
|
||||
*
|
||||
* <p><b>Traversing the raw structure of a RIFF file</b>
|
||||
* <p>To traverse the file structure you must first set up a RIFFVisitor object
|
||||
* that does something useful at each call to the visit method. Then create an
|
||||
* instance of a RIFFParser and invoke the #interpret method.
|
||||
*
|
||||
* <pre>
|
||||
* class RIFFRawTraversal
|
||||
* . {
|
||||
* . static class Visitor
|
||||
* . implements RIFFVisitor
|
||||
* . {
|
||||
* . ...implement the visitor interface here...
|
||||
* . }
|
||||
* .
|
||||
* . public static void main(String[] args)
|
||||
* . {
|
||||
* . try {
|
||||
* . Visitor visitor = new Visitor();
|
||||
* . FileInputStream stream = new FileInputStream(args[0]);
|
||||
* . RIFFParser p = new RIFFParser();
|
||||
* . p.interpret(stream,visitor);
|
||||
* . stream.close();
|
||||
* . }
|
||||
* . catch (IOException e) { System.out.println(e); }
|
||||
* . catch (InterpreterException e) { System.out.println(e); }
|
||||
* . catch (AbortedException e) { System.out.println(e); }
|
||||
* . }
|
||||
* . }
|
||||
* </pre>
|
||||
*
|
||||
* <p><b>Traversing the RIFF file and interpreting its content.</b>
|
||||
* <p>Since RIFF files are not completely self describing (there is no information
|
||||
* that helps differentiate between data chunks, property chunks and collection
|
||||
* chunks) a reader must set up the interpreter with some contextual information
|
||||
* before starting the interpreter.
|
||||
* <p>
|
||||
* Once at least one chunk has been declared, the interpreter will only call the
|
||||
* visitor for occurences of the declared group chunks and data chunks. The property
|
||||
* chunks and the collection chunks can be obtained from the current group chunk
|
||||
* by calling #getProperty or #getCollection.
|
||||
* <br>Note: All information the visitor can obtain during interpretation is only
|
||||
* valid during the actual #visit... call. Dont try to get information about properties
|
||||
* or collections for chunks that the visitor is not visiting right now.
|
||||
*
|
||||
* <pre>
|
||||
* class InterpretingAnILBMFile
|
||||
* . {
|
||||
* . static class Visitor
|
||||
* . implements RIFFVisitor
|
||||
* . {
|
||||
* . ...
|
||||
* . }
|
||||
* .
|
||||
* . public static void main(String[] args)
|
||||
* . {
|
||||
* . try {
|
||||
* . Visitor visitor = new Visitor();
|
||||
* . FileInputStream stream = new FileInputStream(args[0]);
|
||||
* . RIFFParser p = new RIFFParser();
|
||||
* . p.declareGroupChunk('FORM','ILBM');
|
||||
* . p.declarePropertyChunk('ILBM','BMHD');
|
||||
* . p.declarePropertyChunk('ILBM','CMAP');
|
||||
* . p.declareCollectionChunk('ILBM','CRNG');
|
||||
* . p.declareDataChunk('ILBM','BODY');
|
||||
* . p.interpret(stream,visitor);
|
||||
* . stream.close();
|
||||
* . }
|
||||
* . catch (IOException e) { System.out.println(e); }
|
||||
* . catch (InterpreterException e) { System.out.println(e); }
|
||||
* . catch (AbortedException e) { System.out.println(e); }
|
||||
* . }
|
||||
* . }
|
||||
* </pre>
|
||||
*
|
||||
* @see RIFFVisitor
|
||||
*
|
||||
* @author Werner Randelshofer, Hausmatt 10, CH-6405 Goldau, Switzerland
|
||||
* @version 1.5 2012-08-03 Adds offset property.
|
||||
* <br>1.4 2011-08-26 Adds HashMap for stop chunks.
|
||||
* <br>1.3 2011-01-23 Use HashMap instead of Hashtable.
|
||||
* <br>1.2 2010-07-06 Use integer IDs for efficiency. Added support for
|
||||
* stop chunks.
|
||||
* <br>1.0 2005-01-16 Created.
|
||||
*/
|
||||
public class RIFFParser extends Object {
|
||||
private final static boolean DEBUG =false;
|
||||
/** ID for FormGroupExpression. */
|
||||
public final static int RIFF_ID = stringToID("RIFF");
|
||||
/** ID for ListGroupExpression. */
|
||||
public final static int LIST_ID = stringToID("LIST");
|
||||
/** ID for NULL chunks. */
|
||||
public final static int NULL_ID = stringToID(" ");
|
||||
/** ID for NULL chunks. */
|
||||
public final static int NULL_NUL_ID = stringToID("\0\0\0\0");
|
||||
/** ID for JUNK chunks. */
|
||||
public final static int JUNK_ID = stringToID("JUNK");
|
||||
/** The visitor traverses the parse tree. */
|
||||
private RIFFVisitor visitor;
|
||||
/** List of data chunks the visitor is interested in. */
|
||||
private HashSet<RIFFChunk> dataChunks;
|
||||
/** List of property chunks the visitor is interested in. */
|
||||
private HashSet<RIFFChunk> propertyChunks;
|
||||
/** List of collection chunks the visitor is interested in. */
|
||||
private HashSet<RIFFChunk> collectionChunks;
|
||||
/** List of stop chunks the visitor is interested in. */
|
||||
private HashSet<Integer> stopChunkTypes;
|
||||
/** List of group chunks the visitor is interested in. */
|
||||
private HashSet<RIFFChunk> groupChunks;
|
||||
/** Reference to the input stream. */
|
||||
private RIFFPrimitivesInputStream in;
|
||||
/** Reference to the image input stream. */
|
||||
private ImageInputStream iin;
|
||||
|
||||
/** Whether we stop at all chunks. */
|
||||
private boolean isStopChunks;
|
||||
|
||||
/** Stream offset. */
|
||||
private long streamOffset;
|
||||
|
||||
/* ---- constructors ---- */
|
||||
/**
|
||||
* Constructs a new RIFF parser.
|
||||
*/
|
||||
public RIFFParser() {
|
||||
}
|
||||
|
||||
public long getStreamOffset() {
|
||||
return streamOffset;
|
||||
}
|
||||
|
||||
public void setStreamOffset(long offset) {
|
||||
this.streamOffset = offset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ---- accessor methods ---- */
|
||||
/* ---- action methods ---- */
|
||||
/**
|
||||
* Interprets the RIFFFile expression located at the
|
||||
* current position of the indicated InputStream.
|
||||
* Lets the visitor traverse the RIFF parse tree during
|
||||
* interpretation.
|
||||
*
|
||||
* <p>Pre condition
|
||||
* <li> Data-, property- and collection chunks must have been
|
||||
* declared prior to this call.
|
||||
* <li> When the client never declared chunks, then all local
|
||||
* chunks will be interpreted as data chunks.
|
||||
* <li> The stream must be positioned at the beginning of the
|
||||
* RIFFFileExpression.
|
||||
*
|
||||
* <p>Post condition
|
||||
* <li> When no exception was thrown then the stream is positioned
|
||||
* after the RIFFFile expression.
|
||||
*
|
||||
* <p>Obligation
|
||||
* The visitor may throw an ParseException or an
|
||||
* AbortException during tree traversal.
|
||||
*
|
||||
* @exception ParseException
|
||||
* Is thrown when an interpretation error occured.
|
||||
* The stream is positioned where the error occured.
|
||||
* @exception AbortException
|
||||
* Is thrown when the visitor decided to abort the
|
||||
* interpretation.
|
||||
*/
|
||||
public long parse(InputStream in, RIFFVisitor v)
|
||||
throws ParseException, AbortException, IOException {
|
||||
this.in = new RIFFPrimitivesInputStream(in);
|
||||
visitor = v;
|
||||
parseFile();
|
||||
return getScan(this.in);
|
||||
}
|
||||
|
||||
public long parse(ImageInputStream in, RIFFVisitor v)
|
||||
throws ParseException, AbortException, IOException {
|
||||
return parse(new ImageInputStreamAdapter(in), v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a RIFF file.
|
||||
*
|
||||
* <pre>
|
||||
* RIFF = 'RIFF' FormGroup
|
||||
* </pre>
|
||||
*/
|
||||
private void parseFile()
|
||||
throws ParseException, AbortException, IOException {
|
||||
int id = in.readFourCC();
|
||||
|
||||
if (id == RIFF_ID) {
|
||||
parseFORM(null);
|
||||
} else if (id == JUNK_ID) {
|
||||
parseLocalChunk(null,id);
|
||||
} else {
|
||||
if (iin!=null) {
|
||||
throw new ParseException("Invalid RIFF File ID: \"" + idToString(id) +" 0x"+Integer.toHexString(id)+" near "+iin.getStreamPosition()+" 0x"+Long.toHexString(iin.getStreamPosition()));
|
||||
} else {
|
||||
throw new ParseException("Invalid RIFF File ID: \"" + idToString(id) +" 0x"+Integer.toHexString(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private long getScan(RIFFPrimitivesInputStream in) {
|
||||
return in.getScan()+streamOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a FORM group.
|
||||
* <pre>
|
||||
* FormGroup ::= size GroupType { ChunkID LocalChunk [pad]
|
||||
* | 'FORM' FormGroup [pad] }
|
||||
* | 'LIST' ListGroup [pad] }
|
||||
* </pre>
|
||||
*/
|
||||
private void parseFORM(HashMap props)
|
||||
throws ParseException, AbortException, IOException {
|
||||
long size = in.readULONG();
|
||||
long offset = getScan(in);
|
||||
int type = in.readFourCC();
|
||||
if (DEBUG)System.out.println("RIFFParser.parseForm "+idToString(type));
|
||||
if (!isGroupType(type)) {
|
||||
throw new ParseException("Invalid FORM Type: \"" + idToString(type) + "\"");
|
||||
}
|
||||
|
||||
RIFFChunk propGroup = (props == null) ? null : (RIFFChunk) props.get(type);
|
||||
RIFFChunk chunk = new RIFFChunk(type, RIFF_ID, size, offset, propGroup);
|
||||
|
||||
boolean visitorWantsToEnterGroup = false;
|
||||
if (isGroupChunk(chunk) && (visitorWantsToEnterGroup = visitor.enteringGroup(chunk))) {
|
||||
visitor.enterGroup(chunk);
|
||||
}
|
||||
|
||||
try {
|
||||
long finish = offset + size;
|
||||
while (getScan(in) < finish) {
|
||||
long idscan = getScan(in);
|
||||
int id = in.readFourCC();
|
||||
|
||||
if (id == RIFF_ID) {
|
||||
parseFORM(props);
|
||||
} else if (id == LIST_ID) {
|
||||
parseLIST(props);
|
||||
} else if (isLocalChunkID(id)) {
|
||||
parseLocalChunk(chunk, id);
|
||||
} else {
|
||||
ParseException pex = new ParseException("Invalid Chunk: \"" + id + "\" at offset:" + idscan);
|
||||
chunk.setParserMessage(pex.getMessage());
|
||||
throw pex;
|
||||
}
|
||||
|
||||
in.align();
|
||||
}
|
||||
} catch (EOFException e) {
|
||||
e.printStackTrace();
|
||||
chunk.setParserMessage(
|
||||
"Unexpected EOF after "
|
||||
+ NumberFormat.getInstance().format(getScan(in) - offset)
|
||||
+ " bytes");
|
||||
} finally {
|
||||
if (visitorWantsToEnterGroup) {
|
||||
visitor.leaveGroup(chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a LIST group.
|
||||
* <pre>
|
||||
* ListGroup ::= size GroupType { ChunkID LocalChunk [pad] | 'LIST ' ListGroup [pad] }
|
||||
* </pre>
|
||||
*/
|
||||
private void parseLIST(HashMap props)
|
||||
throws ParseException, AbortException, IOException {
|
||||
long size = in.readULONG();
|
||||
long scan = getScan(in);
|
||||
int type = in.readFourCC();
|
||||
if (DEBUG)System.out.println("RIFFParser.parseLIST "+idToString(type));
|
||||
|
||||
if (!isGroupType(type)) {
|
||||
throw new ParseException("Invalid LIST Type: \"" + type + "\"");
|
||||
}
|
||||
|
||||
RIFFChunk propGroup = (props == null) ? null : (RIFFChunk) props.get(type);
|
||||
RIFFChunk chunk = new RIFFChunk(type, LIST_ID, size, scan, propGroup);
|
||||
|
||||
boolean visitorWantsToEnterGroup = false;
|
||||
if (isGroupChunk(chunk) && (visitorWantsToEnterGroup = visitor.enteringGroup(chunk))) {
|
||||
visitor.enterGroup(chunk);
|
||||
}
|
||||
try {
|
||||
if (visitorWantsToEnterGroup) {
|
||||
long finish = scan + size;
|
||||
while (getScan(in) < finish) {
|
||||
long idscan = getScan(in);
|
||||
int id = in.readFourCC();
|
||||
if (id == LIST_ID) {
|
||||
parseLIST(props);
|
||||
} else if (isLocalChunkID(id)) {
|
||||
parseLocalChunk(chunk, id);
|
||||
} else {
|
||||
parseGarbage(chunk, id, finish-getScan(in), getScan(in));
|
||||
ParseException pex = new ParseException("Invalid Chunk: \"" + id + "\" at offset:" + idscan);
|
||||
chunk.setParserMessage(pex.getMessage());
|
||||
//throw pex;
|
||||
}
|
||||
|
||||
in.align();
|
||||
}
|
||||
} else {
|
||||
in.skipFully(size-4);
|
||||
in.align();
|
||||
}
|
||||
} finally {
|
||||
if (visitorWantsToEnterGroup) {
|
||||
visitor.leaveGroup(chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a local chunk.
|
||||
* <pre>
|
||||
* LocalChunk ::= size { DataChunk | PropertyChunk | CollectionChunk }
|
||||
* DataChunk = PropertyChunk = CollectionChunk ::= { byte }...*size
|
||||
* </pre>
|
||||
*/
|
||||
private void parseLocalChunk(RIFFChunk parent, int id)
|
||||
throws ParseException, AbortException, IOException {
|
||||
long size = in.readULONG();
|
||||
long scan = getScan(in);
|
||||
if (DEBUG)System.out.println("RIFFParser.parseLocalChunk "+idToString(id));
|
||||
RIFFChunk chunk = new RIFFChunk(parent==null?0:parent.getType(), id, size, scan);
|
||||
|
||||
if (isDataChunk(chunk)) {
|
||||
byte[] data = new byte[(int) size];
|
||||
in.read(data, 0, (int) size);
|
||||
chunk.setData(data);
|
||||
visitor.visitChunk(parent, chunk);
|
||||
} else if (isPropertyChunk(chunk)) {
|
||||
byte[] data = new byte[(int) size];
|
||||
in.read(data, 0, (int) size);
|
||||
chunk.setData(data);
|
||||
parent.putPropertyChunk(chunk);
|
||||
} else if (isCollectionChunk(chunk)) {
|
||||
byte[] data = new byte[(int) size];
|
||||
in.read(data, 0, (int) size);
|
||||
chunk.setData(data);
|
||||
parent.addCollectionChunk(chunk);
|
||||
} else {
|
||||
in.skipFully((int) size);
|
||||
if (isStopChunks) {
|
||||
visitor.visitChunk(parent, chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This method is invoked when we encounter a parsing problem.
|
||||
* <pre>
|
||||
* LocalChunk ::= size { DataChunk | PropertyChunk | CollectionChunk }
|
||||
* DataChunk = PropertyChunk = CollectionChunk ::= { byte }...*size
|
||||
* </pre>
|
||||
*/
|
||||
private void parseGarbage(RIFFChunk parent, int id, long size, long scan)
|
||||
throws ParseException, AbortException, IOException {
|
||||
//long size = in.readULONG();
|
||||
//long scan = getScan(in);
|
||||
|
||||
RIFFChunk chunk = new RIFFChunk(parent.getType(), id, size, scan);
|
||||
|
||||
if (isDataChunk(chunk)) {
|
||||
byte[] data = new byte[(int) size];
|
||||
in.read(data, 0, (int) size);
|
||||
chunk.setData(data);
|
||||
visitor.visitChunk(parent, chunk);
|
||||
} else if (isPropertyChunk(chunk)) {
|
||||
byte[] data = new byte[(int) size];
|
||||
in.read(data, 0, (int) size);
|
||||
chunk.setData(data);
|
||||
parent.putPropertyChunk(chunk);
|
||||
} else if (isCollectionChunk(chunk)) {
|
||||
byte[] data = new byte[(int) size];
|
||||
in.read(data, 0, (int) size);
|
||||
chunk.setData(data);
|
||||
parent.addCollectionChunk(chunk);
|
||||
} else {
|
||||
in.skipFully((int) size);
|
||||
if (isStopChunk(chunk)) {
|
||||
visitor.visitChunk(parent, chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the ID of the chunk has been declared as a
|
||||
* data chunk.
|
||||
*
|
||||
* <p>Pre condition
|
||||
* <li> Data chunks must have been declared before the
|
||||
* interpretation has been started.
|
||||
* <li> This method will always return true when neither
|
||||
* data chunks, property chunks nor collection chunks
|
||||
* have been declared,
|
||||
*
|
||||
* @param chunk Chunk to be verified.
|
||||
* @return True when the parameter is a data chunk.
|
||||
*/
|
||||
protected boolean isDataChunk(RIFFChunk chunk) {
|
||||
if (dataChunks == null) {
|
||||
if (collectionChunks == null && propertyChunks == null && (stopChunkTypes==null||!stopChunkTypes.contains(chunk.getType()))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return dataChunks.contains(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the ID of the chunk has been declared as
|
||||
* a group chunk.
|
||||
*
|
||||
* <p>Pre condition
|
||||
* <li> Group chunks must have been declared before the
|
||||
* interpretation has been started.
|
||||
* (Otherwise the response is always true).
|
||||
*
|
||||
* @param chunk Chunk to be verified.
|
||||
* @return True when the visitor is interested in this is a group chunk.
|
||||
*/
|
||||
protected boolean isGroupChunk(RIFFChunk chunk) {
|
||||
if (groupChunks == null) {
|
||||
return true;
|
||||
} else {
|
||||
return groupChunks.contains(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks wether the ID of the chunk has been declared as a
|
||||
* property chunk.
|
||||
*
|
||||
* <p>Pre condition
|
||||
* <li> Property chunks must have been declared before the
|
||||
* interpretation has been started.
|
||||
* <li> This method will always return false when neither
|
||||
* data chunks, property chunks nor collection chunks
|
||||
* have been declared,
|
||||
*/
|
||||
protected boolean isPropertyChunk(RIFFChunk chunk) {
|
||||
if (propertyChunks == null) {
|
||||
return false;
|
||||
} else {
|
||||
return propertyChunks.contains(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks wether the ID of the chunk has been declared as a
|
||||
* collection chunk.
|
||||
*
|
||||
* <p>Pre condition
|
||||
* <li> Collection chunks must have been declared before the
|
||||
* interpretation has been started.
|
||||
* <li> This method will always return true when neither
|
||||
* data chunks, property chunks nor collection chunks
|
||||
* have been declared,
|
||||
*
|
||||
* @param chunk Chunk to be verified.
|
||||
* @return True when the parameter is a collection chunk.
|
||||
*/
|
||||
protected boolean isCollectionChunk(RIFFChunk chunk) {
|
||||
if (collectionChunks == null) {
|
||||
return false;
|
||||
} else {
|
||||
return collectionChunks.contains(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Declares a data chunk.
|
||||
*
|
||||
* <p>Pre condition
|
||||
* <li> The chunk must not have already been declared as of a
|
||||
* different type.
|
||||
* <li> Declarations may not be done during interpretation
|
||||
* of an RIFFFileExpression.
|
||||
*
|
||||
* <p>Post condition
|
||||
* <li> Data chunk declared
|
||||
*
|
||||
* @param type
|
||||
* Type of the chunk. Must be formulated as a TypeID conforming
|
||||
* to the method #isFormType.
|
||||
* @param id
|
||||
* ID of the chunk. Must be formulated as a ChunkID conforming
|
||||
* to the method #isLocalChunkID.
|
||||
*/
|
||||
public void declareDataChunk(int type, int id) {
|
||||
RIFFChunk chunk = new RIFFChunk(type, id);
|
||||
if (dataChunks == null) {
|
||||
dataChunks = new HashSet<RIFFChunk>();
|
||||
}
|
||||
dataChunks.add(chunk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Declares a FORM group chunk.
|
||||
*
|
||||
* <p>Pre condition
|
||||
* <li> The chunk must not have already been declared as of a
|
||||
* different type.
|
||||
* <li> Declarations may not be done during interpretation
|
||||
* of an RIFFFileExpression.
|
||||
*
|
||||
* <p>Post condition
|
||||
* <li> Group chunk declared
|
||||
*
|
||||
* @param type
|
||||
* Type of the chunk. Must be formulated as a TypeID conforming
|
||||
* to the method #isFormType.
|
||||
* @param id
|
||||
* ID of the chunk. Must be formulated as a ChunkID conforming
|
||||
* to the method #isContentsType.
|
||||
*/
|
||||
public void declareGroupChunk(int type, int id) {
|
||||
RIFFChunk chunk = new RIFFChunk(type, id);
|
||||
if (groupChunks == null) {
|
||||
groupChunks = new HashSet<RIFFChunk>();
|
||||
}
|
||||
groupChunks.add(chunk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Declares a property chunk.
|
||||
*
|
||||
* <p>Pre condition
|
||||
* <li> The chunk must not have already been declared as of a
|
||||
* different type.
|
||||
* <li> Declarations may not be done during interpretation
|
||||
* of an RIFFFileExpression.
|
||||
*
|
||||
* <p>Post condition
|
||||
* <li> Group chunk declared
|
||||
*
|
||||
*
|
||||
* @param type
|
||||
* Type of the chunk. Must be formulated as a TypeID conforming
|
||||
* to the method #isFormType.
|
||||
* @param id
|
||||
* ID of the chunk. Must be formulated as a ChunkID conforming
|
||||
* to the method #isLocalChunkID.
|
||||
*/
|
||||
public void declarePropertyChunk(int type, int id) {
|
||||
RIFFChunk chunk = new RIFFChunk(type, id);
|
||||
if (propertyChunks == null) {
|
||||
propertyChunks = new HashSet<RIFFChunk>();
|
||||
}
|
||||
propertyChunks.add(chunk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Declares a collection chunk.
|
||||
*
|
||||
* <p>Pre condition
|
||||
* <li> The chunk must not have already been declared as of a
|
||||
* different type.
|
||||
* <li> Declarations may not be done during interpretation
|
||||
* of an RIFFFileExpression.
|
||||
*
|
||||
* <p>Post condition
|
||||
* <li> Collection chunk declared
|
||||
*
|
||||
* @param type
|
||||
* Type of the chunk. Must be formulated as a TypeID conforming
|
||||
* to the method #isFormType.
|
||||
* @param id
|
||||
* ID of the chunk. Must be formulated as a ChunkID conforming
|
||||
* to the method #isLocalChunkID.
|
||||
*/
|
||||
public void declareCollectionChunk(int type, int id) {
|
||||
RIFFChunk chunk = new RIFFChunk(type, id);
|
||||
if (collectionChunks == null) {
|
||||
collectionChunks = new HashSet<RIFFChunk>();
|
||||
}
|
||||
collectionChunks.add(chunk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Declares a stop chunk.
|
||||
*
|
||||
* <p>Pre condition
|
||||
* <li> The chunk must not have already been declared as of a
|
||||
* different type.
|
||||
* <li> Declarations may not be done during interpretation
|
||||
* of an RIFFFileExpression.
|
||||
*
|
||||
* <p>Post condition
|
||||
* <li> Stop chunk declared
|
||||
*
|
||||
* @param type
|
||||
* Type of the chunk. Must be formulated as a TypeID conforming
|
||||
* to the method #isFormType.
|
||||
*/
|
||||
public void declareStopChunkType(int type) {
|
||||
if (stopChunkTypes == null) {
|
||||
stopChunkTypes = new HashSet<Integer>();
|
||||
}
|
||||
stopChunkTypes.add(type);
|
||||
}
|
||||
|
||||
/** Whether the parse should stop at all chunks.
|
||||
* <p>
|
||||
* The parser does not read the data body of stop chunks.
|
||||
* <p>
|
||||
* By declaring stop chunks, and not declaring any data, group or
|
||||
* property chunks, the file structure of a RIFF file can be quickly
|
||||
* scanned through.
|
||||
*/
|
||||
public void declareStopChunks() {
|
||||
isStopChunks = true;
|
||||
}
|
||||
|
||||
private boolean isStopChunk(RIFFChunk chunk) {
|
||||
return isStopChunks||stopChunkTypes!=null&&stopChunkTypes.contains(chunk.getType());
|
||||
}
|
||||
|
||||
/* ---- Class methods ---- */
|
||||
/**
|
||||
* Checks wether the argument represents a valid RIFF GroupID.
|
||||
*
|
||||
* <p>Validation
|
||||
* <ul>
|
||||
* <li> Group ID must be one of RIFF_ID, LIST_ID.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param id Chunk ID to be checked.
|
||||
* @return True when the chunk ID is a valid Group ID.
|
||||
*/
|
||||
public static boolean isGroupID(int id) {
|
||||
return id == LIST_ID || id == RIFF_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks wether the argument represents a valid RIFF Group Type.
|
||||
*
|
||||
* <p>Validation
|
||||
* <ul>
|
||||
* <li> Must be a valid ID.</li>
|
||||
* <li> Must not be a group ID.</li>
|
||||
* <li> Must not be a NULL_ID.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param id Chunk ID to be checked.
|
||||
* @return True when the chunk ID is a valid Group ID.
|
||||
*/
|
||||
public static boolean isGroupType(int id) {
|
||||
return isID(id) && !isGroupID(id) && id != NULL_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the argument represents a valid RIFF ID.
|
||||
*
|
||||
* <p>Validation
|
||||
* <li> Every byte of an ID must be in the range of 0x20..0x7e
|
||||
* <li> The id may not have leading spaces (unless the id is a NULL_ID).
|
||||
*
|
||||
* @param id Chunk ID to be checked.
|
||||
* @return True when the ID is a valid IFF chunk ID.
|
||||
*/
|
||||
public static boolean isID(int id) {
|
||||
int c0 = id >> 24;
|
||||
int c1 = (id >> 16) & 0xff;
|
||||
int c2 = (id >> 8) & 0xff;
|
||||
int c3 = id & 0xff;
|
||||
|
||||
return id == NULL_NUL_ID
|
||||
|| c0 >= 0x20 && c0 <= 0x7e
|
||||
&& c1 >= 0x20 && c1 <= 0x7e
|
||||
&& c2 >= 0x20 && c2 <= 0x7e
|
||||
&& c3 >= 0x20 && c3 <= 0x7e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the argument is a valid Local Chunk ID.
|
||||
*
|
||||
* <p>Validation
|
||||
* <ud>
|
||||
* <li> Must be valid ID.</li>
|
||||
* <li> Local Chunk IDs may not collide with GroupIDs.</id>
|
||||
* <li> Must not be a NULL_ID.</li>
|
||||
* </ud>
|
||||
*
|
||||
* @param id Chunk ID to be checked.
|
||||
* @return True when the chunk ID is a Local Chunk ID.
|
||||
*/
|
||||
public static boolean isLocalChunkID(int id) {
|
||||
if (isGroupID(id)) {
|
||||
return false;
|
||||
}
|
||||
return id != NULL_ID && isID(id);
|
||||
}
|
||||
private WeakHashMap<String, String> ids;
|
||||
|
||||
/**
|
||||
* Convert an integer IFF identifier to String.
|
||||
*
|
||||
* @param anInt ID to be converted.
|
||||
* @return String representation of the ID.
|
||||
*/
|
||||
public static String idToString(int anInt) {
|
||||
byte[] bytes = new byte[4];
|
||||
|
||||
bytes[0] = (byte) (anInt >>> 24);
|
||||
bytes[1] = (byte) (anInt >>> 16);
|
||||
bytes[2] = (byte) (anInt >>> 8);
|
||||
bytes[3] = (byte) (anInt >>> 0);
|
||||
|
||||
try {
|
||||
return new String(bytes, "ASCII");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new InternalError(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the first four letters of the
|
||||
* String into an IFF Identifier.
|
||||
*
|
||||
* @param aString String to be converted.
|
||||
* @return ID representation of the String.
|
||||
*/
|
||||
public static int stringToID(String aString) {
|
||||
byte[] bytes = aString.getBytes();
|
||||
|
||||
return ((int) bytes[0]) << 24
|
||||
| ((int) bytes[1]) << 16
|
||||
| ((int) bytes[2]) << 8
|
||||
| ((int) bytes[3]) << 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* @(#)RIFFPrimitivesInputStream.java 1.0 2005-01-15
|
||||
*
|
||||
* Copyright (c) 2005 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media.riff;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* A RIFF primitives input stream lets an application read primitive data
|
||||
* types in the Microsoft Resource Interfache File Format (RIFF) format from an
|
||||
* underlying input stream.
|
||||
*
|
||||
* Reference:
|
||||
* AVI RIFF File Reference
|
||||
* http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/htm/avirifffilereference.asp
|
||||
*
|
||||
* @author Werner Randelshofer, Hausmatt 10, CH-6405 Goldau, Switzerland
|
||||
* @version 1.0 2005-01-15 Created.
|
||||
*/
|
||||
public class RIFFPrimitivesInputStream extends FilterInputStream {
|
||||
private long scan, mark;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param in the input stream.
|
||||
*/
|
||||
public RIFFPrimitivesInputStream(InputStream in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read 1 byte from the input stream and interpret
|
||||
* them as an 8 Bit unsigned UBYTE value.
|
||||
*/
|
||||
public int readUBYTE()
|
||||
throws IOException {
|
||||
int b0 = in.read();
|
||||
|
||||
if (b0 == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
scan += 1;
|
||||
return b0 & 0xff;
|
||||
}
|
||||
/**
|
||||
* Read 2 bytes from the input stream and interpret
|
||||
* them as a 16 Bit signed WORD value.
|
||||
*/
|
||||
public short readWORD()
|
||||
throws IOException {
|
||||
int b0 = in.read();
|
||||
int b1 = in.read();
|
||||
|
||||
if (b1 == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
scan += 2;
|
||||
|
||||
return (short) (((b0 & 0xff) << 0) | ((b1 & 0xff) << 8));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read 2 bytes from the input stream and interpret
|
||||
* them as a 16 Bit unsigned UWORD value.
|
||||
*/
|
||||
public int readUWORD()
|
||||
throws IOException {
|
||||
return readWORD() & 0xffff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read 4 bytes from the input stream and interpret
|
||||
* them as a 32 Bit signed LONG value.
|
||||
*/
|
||||
public int readLONG()
|
||||
throws IOException {
|
||||
int b0 = in.read();
|
||||
int b1 = in.read();
|
||||
int b2 = in.read();
|
||||
int b3 = in.read();
|
||||
|
||||
if (b3 == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
scan += 4;
|
||||
|
||||
return ((b0&0xff) << 0) +
|
||||
((b1&0xff) << 8) +
|
||||
((b2&0xff) << 16) +
|
||||
((b3&0xff) << 24);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read 4 bytes from the input stream and interpret
|
||||
* them as a four byte character code.
|
||||
*
|
||||
* Cited from Referenced "AVI RIFF File Reference":
|
||||
* "A FOURCC (four-character code) is a 32-bit unsigned integer created by
|
||||
* concatenating four ASCII characters. For example, the FOURCC 'abcd' is
|
||||
* represented on a Little-Endian system as 0x64636261. FOURCCs can contain
|
||||
* space characters, so ' abc' is a valid FOURCC. The AVI file format uses
|
||||
* FOURCC codes to identify stream types, data chunks, index entries, and
|
||||
* other information."
|
||||
*/
|
||||
public int readFourCC()
|
||||
throws IOException {
|
||||
int b3 = in.read();
|
||||
int b2 = in.read();
|
||||
int b1 = in.read();
|
||||
int b0 = in.read();
|
||||
|
||||
if (b0 == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
scan += 4;
|
||||
|
||||
return ((b0&0xff) << 0) +
|
||||
((b1&0xff) << 8) +
|
||||
((b2&0xff) << 16) +
|
||||
((b3&0xff) << 24);
|
||||
}
|
||||
/**
|
||||
* Read 4 bytes from the input stream and interpret
|
||||
* them as a four byte character code.
|
||||
*
|
||||
* Cited from Referenced "AVI RIFF File Reference":
|
||||
* "A FOURCC (four-character code) is a 32-bit unsigned integer created by
|
||||
* concatenating four ASCII characters. For example, the FOURCC 'abcd' is
|
||||
* represented on a Little-Endian system as 0x64636261. FOURCCs can contain
|
||||
* space characters, so ' abc' is a valid FOURCC. The AVI file format uses
|
||||
* FOURCC codes to identify stream types, data chunks, index entries, and
|
||||
* other information."
|
||||
*/
|
||||
public String readFourCCString()
|
||||
throws IOException {
|
||||
byte[] buf = new byte[4];
|
||||
readFully(buf, 0, 4);
|
||||
//scan += 4; <- scan is updated by method readFully
|
||||
return new String(buf, "ASCII");
|
||||
}
|
||||
|
||||
/**
|
||||
* Read 4 Bytes from the input Stream and interpret
|
||||
* them as an unsigned Integer value of type ULONG.
|
||||
*/
|
||||
public long readULONG()
|
||||
throws IOException {
|
||||
return (long)(readLONG()) & 0x00ffffffff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Align to an even byte position in the input stream.
|
||||
* This will skip one byte in the stream if the current
|
||||
* read position is not even.
|
||||
*/
|
||||
public void align()
|
||||
throws IOException {
|
||||
if (scan % 2 == 1) {
|
||||
in.skip(1);
|
||||
scan++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current read position within the file (as seen
|
||||
* by this input stream filter).
|
||||
*/
|
||||
public long getScan()
|
||||
{ return scan; }
|
||||
|
||||
/**
|
||||
* Reads one byte.
|
||||
*/
|
||||
public int read()
|
||||
throws IOException {
|
||||
int data = in.read();
|
||||
if (data != -1) scan++;
|
||||
return data;
|
||||
}
|
||||
/**
|
||||
* Reads a sequence of bytes.
|
||||
*/
|
||||
public int readFully(byte[] b,int offset, int length)
|
||||
throws IOException {
|
||||
int count = read(b, offset, length);
|
||||
if (count != length) {
|
||||
throw new EOFException("readFully for "+length+" bytes, unexpected EOF after "+count+" bytes.");
|
||||
}
|
||||
//scan += count; <- scan is already counted by read method
|
||||
return count;
|
||||
}
|
||||
/**
|
||||
* Reads a sequence of bytes.
|
||||
*/
|
||||
public int read(byte[] b,int offset, int length)
|
||||
throws IOException {
|
||||
int count = 0;
|
||||
while (count < length) {
|
||||
int result = in.read(b,offset+count,length-count);
|
||||
if (result == -1) break;
|
||||
count += result;
|
||||
}
|
||||
scan += count;
|
||||
return count;
|
||||
}
|
||||
/**
|
||||
* Marks the input stream.
|
||||
* @param readlimit The maximum limit of bytes that can be read before
|
||||
* the mark position becomes invalid.
|
||||
*/
|
||||
public void mark(int readlimit) {
|
||||
in.mark(readlimit);
|
||||
mark = scan;
|
||||
}
|
||||
/**
|
||||
* Repositions the stream at the previously marked position.
|
||||
*
|
||||
* @exception IOException If the stream has not been marked or if the
|
||||
* mark has been invalidated.
|
||||
*/
|
||||
public void reset()
|
||||
throws IOException {
|
||||
in.reset();
|
||||
scan = mark;
|
||||
}
|
||||
/**
|
||||
* Skips over and discards n bytes of data from this input stream. This skip
|
||||
* method tries to skip the provided number of bytes.
|
||||
*/
|
||||
public long skip(long n)
|
||||
throws IOException {
|
||||
long skipped = in.skip(n);
|
||||
scan += skipped;
|
||||
return skipped;
|
||||
}
|
||||
/**
|
||||
* Skips over and discards n bytes of data from this input stream. Throws
|
||||
*
|
||||
* @param n the number of bytes to be skipped.
|
||||
* @exception EOFException if this input stream reaches the end before
|
||||
* skipping all the bytes.
|
||||
*/
|
||||
public void skipFully(long n)
|
||||
throws IOException {
|
||||
if (n==0) return;
|
||||
|
||||
int total = 0;
|
||||
int cur = 0;
|
||||
|
||||
while ((total<n) && ((cur = (int) in.skip(n-total)) > 0)) {
|
||||
total += cur;
|
||||
}
|
||||
if (cur == 0) throw new EOFException();
|
||||
scan += total;
|
||||
}
|
||||
}
|
||||
43
libsrc/avi/src/org/monte/media/riff/RIFFVisitor.java
Normal file
43
libsrc/avi/src/org/monte/media/riff/RIFFVisitor.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* @(#)RIFFVIsitor.java 1.0 2005-01-09
|
||||
*
|
||||
* Copyright (c) 2005 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
package org.monte.media.riff;
|
||||
|
||||
import org.monte.media.AbortException;
|
||||
import org.monte.media.ParseException;
|
||||
|
||||
/**
|
||||
* RIFFVIsitor is notified each time the RIFFParser visits
|
||||
* a data chunk and when a group is entered or leaved.
|
||||
*
|
||||
* @version 1.0 2005-01-09 Created.
|
||||
*/
|
||||
public interface RIFFVisitor {
|
||||
/** This method is invoked when the parser attempts to enter a group.
|
||||
* The visitor can return false, if the parse shall skip the group contents.
|
||||
*
|
||||
* @param group
|
||||
* @return True to enter the group, false to skip over the group.
|
||||
*/
|
||||
public boolean enteringGroup(RIFFChunk group);
|
||||
|
||||
/** This method is invoked when the parser enters a group chunk.*/
|
||||
public void enterGroup(RIFFChunk group)
|
||||
throws ParseException, AbortException;
|
||||
|
||||
/** This method is invoked when the parser leaves a group chunk.*/
|
||||
public void leaveGroup(RIFFChunk group)
|
||||
throws ParseException, AbortException;
|
||||
|
||||
/** This method is invoked when the parser has read a data chunk or
|
||||
* has skipped a stop chunk.*/
|
||||
public void visitChunk(RIFFChunk group, RIFFChunk chunk)
|
||||
throws ParseException, AbortException;
|
||||
}
|
||||
463
libsrc/avi/src/org/monte/media/util/Methods.java
Normal file
463
libsrc/avi/src/org/monte/media/util/Methods.java
Normal file
@@ -0,0 +1,463 @@
|
||||
/*
|
||||
* @(#)Methods.java
|
||||
*
|
||||
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
|
||||
* All rights reserved.
|
||||
*
|
||||
* You may not use, copy or modify this file, except in compliance with the
|
||||
* license agreement you entered into with Werner Randelshofer.
|
||||
* For details see accompanying license terms.
|
||||
*/
|
||||
|
||||
package org.monte.media.util;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
|
||||
/**
|
||||
* Methods contains convenience methods for method invocations using
|
||||
* java.lang.reflect.
|
||||
*
|
||||
* @author Werner Randelshofer
|
||||
* @version $Id: Methods.java 299 2013-01-03 07:40:18Z werner $
|
||||
*/
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class Methods {
|
||||
/**
|
||||
* Prevent instance creation.
|
||||
*/
|
||||
private Methods() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the specified accessible parameterless method if it exists.
|
||||
*
|
||||
* @param obj The object on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
* @return The return value of the method.
|
||||
* @return NoSuchMethodException if the method does not exist or is not
|
||||
* accessible.
|
||||
*/
|
||||
public static Object invoke(Object obj, String methodName)
|
||||
throws NoSuchMethodException {
|
||||
try {
|
||||
Method method = obj.getClass().getMethod(methodName, new Class[0]);
|
||||
Object result = method.invoke(obj, new Object[0]);
|
||||
return result;
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new NoSuchMethodException(methodName+" is not accessible");
|
||||
} catch (InvocationTargetException e) {
|
||||
// The method is not supposed to throw exceptions
|
||||
throw new InternalError(e.getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified accessible method with a string parameter if it exists.
|
||||
*
|
||||
* @param obj The object on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
* @param stringParameter The String parameter
|
||||
* @return The return value of the method or METHOD_NOT_FOUND.
|
||||
* @return NoSuchMethodException if the method does not exist or is not accessible.
|
||||
*/
|
||||
public static Object invoke(Object obj, String methodName, String stringParameter)
|
||||
throws NoSuchMethodException {
|
||||
try {
|
||||
Method method = obj.getClass().getMethod(methodName, new Class[] { String.class });
|
||||
Object result = method.invoke(obj, new Object[] { stringParameter });
|
||||
return result;
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new NoSuchMethodException(methodName+" is not accessible");
|
||||
} catch (InvocationTargetException e) {
|
||||
// The method is not supposed to throw exceptions
|
||||
throw new InternalError(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the specified accessible parameterless method if it exists.
|
||||
*
|
||||
* @param clazz The class on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
* @return The return value of the method or METHOD_NOT_FOUND.
|
||||
* @return NoSuchMethodException if the method does not exist or is not accessible.
|
||||
*/
|
||||
public static Object invokeStatic(Class clazz, String methodName)
|
||||
throws NoSuchMethodException {
|
||||
try {
|
||||
Method method = clazz.getMethod(methodName, new Class[0]);
|
||||
Object result = method.invoke(null, new Object[0]);
|
||||
return result;
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new NoSuchMethodException(methodName+" is not accessible");
|
||||
} catch (InvocationTargetException e) {
|
||||
// The method is not supposed to throw exceptions
|
||||
throw new InternalError(e.getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified accessible parameterless method if it exists.
|
||||
*
|
||||
* @param clazz The class on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
* @return The return value of the method.
|
||||
* @return NoSuchMethodException if the method does not exist or is not accessible.
|
||||
*/
|
||||
public static Object invokeStatic(String clazz, String methodName)
|
||||
throws NoSuchMethodException {
|
||||
try {
|
||||
return invokeStatic(Class.forName(clazz), methodName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new NoSuchMethodException("class "+clazz+" not found");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified parameterless method if it exists.
|
||||
*
|
||||
* @param clazz The class on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
* @param type The parameter type.
|
||||
* @param value The parameter value.
|
||||
* @return The return value of the method.
|
||||
* @return NoSuchMethodException if the method does not exist or is not accessible.
|
||||
*/
|
||||
public static Object invokeStatic(Class clazz, String methodName, Class type, Object value)
|
||||
throws NoSuchMethodException {
|
||||
return invokeStatic(clazz,methodName,new Class[]{type},new Object[]{value});
|
||||
}
|
||||
/**
|
||||
* Invokes the specified parameterless method if it exists.
|
||||
*
|
||||
* @param clazz The class on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
* @param types The parameter types.
|
||||
* @param values The parameter values.
|
||||
* @return The return value of the method.
|
||||
* @return NoSuchMethodException if the method does not exist or is not accessible.
|
||||
*/
|
||||
public static Object invokeStatic(Class clazz, String methodName, Class[] types, Object[] values)
|
||||
throws NoSuchMethodException {
|
||||
try {
|
||||
Method method = clazz.getMethod(methodName, types);
|
||||
Object result = method.invoke(null, values);
|
||||
return result;
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new NoSuchMethodException(methodName+" is not accessible");
|
||||
} catch (InvocationTargetException e) {
|
||||
// The method is not supposed to throw exceptions
|
||||
throw new InternalError(e.getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified parameterless method if it exists.
|
||||
*
|
||||
* @param clazz The class on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
* @param types The parameter types.
|
||||
* @param values The parameter values.
|
||||
* @return The return value of the method.
|
||||
* @return NoSuchMethodException if the method does not exist or is not accessible.
|
||||
*/
|
||||
public static Object invokeStatic(String clazz, String methodName,
|
||||
Class[] types, Object[] values)
|
||||
throws NoSuchMethodException {
|
||||
try {
|
||||
return invokeStatic(Class.forName(clazz), methodName, types, values);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new NoSuchMethodException("class "+clazz+" not found");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified parameterless method if it exists.
|
||||
*
|
||||
* @param clazz The class on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
* @param types The parameter types.
|
||||
* @param values The parameter values.
|
||||
* @param defaultValue The default value.
|
||||
* @return The return value of the method or the default value if the method
|
||||
* does not exist or is not accessible.
|
||||
*/
|
||||
public static Object invokeStatic(String clazz, String methodName,
|
||||
Class[] types, Object[] values, Object defaultValue) {
|
||||
try {
|
||||
return invokeStatic(Class.forName(clazz), methodName, types, values);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return defaultValue;
|
||||
} catch (NoSuchMethodException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the specified getter method if it exists.
|
||||
*
|
||||
* @param obj The object on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
* @param defaultValue This value is returned, if the method does not exist.
|
||||
* @return The value returned by the getter method or the default value.
|
||||
*/
|
||||
public static int invokeGetter(Object obj, String methodName, int defaultValue) {
|
||||
try {
|
||||
Method method = obj.getClass().getMethod(methodName, new Class[0]);
|
||||
Object result = method.invoke(obj, new Object[0]);
|
||||
return ((Integer) result).intValue();
|
||||
} catch (NoSuchMethodException e) {
|
||||
return defaultValue;
|
||||
} catch (IllegalAccessException e) {
|
||||
return defaultValue;
|
||||
} catch (InvocationTargetException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified getter method if it exists.
|
||||
*
|
||||
* @param obj The object on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
* @param defaultValue This value is returned, if the method does not exist.
|
||||
* @return The value returned by the getter method or the default value.
|
||||
*/
|
||||
public static long invokeGetter(Object obj, String methodName, long defaultValue) {
|
||||
try {
|
||||
Method method = obj.getClass().getMethod(methodName, new Class[0]);
|
||||
Object result = method.invoke(obj, new Object[0]);
|
||||
return ((Long) result).longValue();
|
||||
} catch (NoSuchMethodException e) {
|
||||
return defaultValue;
|
||||
} catch (IllegalAccessException e) {
|
||||
return defaultValue;
|
||||
} catch (InvocationTargetException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified getter method if it exists.
|
||||
*
|
||||
* @param obj The object on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
* @param defaultValue This value is returned, if the method does not exist.
|
||||
* @return The value returned by the getter method or the default value.
|
||||
*/
|
||||
public static boolean invokeGetter(Object obj, String methodName, boolean defaultValue) {
|
||||
try {
|
||||
Method method = obj.getClass().getMethod(methodName, new Class[0]);
|
||||
Object result = method.invoke(obj, new Object[0]);
|
||||
return ((Boolean) result).booleanValue();
|
||||
} catch (NoSuchMethodException e) {
|
||||
return defaultValue;
|
||||
} catch (IllegalAccessException e) {
|
||||
return defaultValue;
|
||||
} catch (InvocationTargetException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified getter method if it exists.
|
||||
*
|
||||
* @param obj The object on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
* @param defaultValue This value is returned, if the method does not exist.
|
||||
* @return The value returned by the getter method or the default value.
|
||||
*/
|
||||
public static Object invokeGetter(Object obj, String methodName, Object defaultValue) {
|
||||
try {
|
||||
Method method = obj.getClass().getMethod(methodName, new Class[0]);
|
||||
Object result = method.invoke(obj, new Object[0]);
|
||||
return result;
|
||||
} catch (NoSuchMethodException e) {
|
||||
return defaultValue;
|
||||
} catch (IllegalAccessException e) {
|
||||
return defaultValue;
|
||||
} catch (InvocationTargetException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified getter method if it exists.
|
||||
*
|
||||
* @param clazz The object on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
* @param defaultValue This value is returned, if the method does not exist.
|
||||
* @return The value returned by the getter method or the default value.
|
||||
*/
|
||||
public static boolean invokeStaticGetter(Class clazz, String methodName, boolean defaultValue) {
|
||||
try {
|
||||
Method method = clazz.getMethod(methodName, new Class[0]);
|
||||
Object result = method.invoke(null, new Object[0]);
|
||||
return ((Boolean) result).booleanValue();
|
||||
} catch (NoSuchMethodException e) {
|
||||
return defaultValue;
|
||||
} catch (IllegalAccessException e) {
|
||||
return defaultValue;
|
||||
} catch (InvocationTargetException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified setter method if it exists.
|
||||
*
|
||||
* @param obj The object on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
*/
|
||||
public static Object invoke(Object obj, String methodName, boolean newValue)
|
||||
throws NoSuchMethodException {
|
||||
try {
|
||||
Method method = obj.getClass().getMethod(methodName, new Class[] { Boolean.TYPE} );
|
||||
return method.invoke(obj, new Object[] { newValue});
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new NoSuchMethodException(methodName+" is not accessible");
|
||||
} catch (InvocationTargetException e) {
|
||||
// The method is not supposed to throw exceptions
|
||||
throw new InternalError(e.getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified method if it exists.
|
||||
*
|
||||
* @param obj The object on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
*/
|
||||
public static Object invoke(Object obj, String methodName, int newValue)
|
||||
throws NoSuchMethodException {
|
||||
try {
|
||||
Method method = obj.getClass().getMethod(methodName, new Class[] { Integer.TYPE} );
|
||||
return method.invoke(obj, new Object[] { newValue});
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new NoSuchMethodException(methodName+" is not accessible");
|
||||
} catch (InvocationTargetException e) {
|
||||
// The method is not supposed to throw exceptions
|
||||
throw new InternalError(e.getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified setter method if it exists.
|
||||
*
|
||||
* @param obj The object on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
*/
|
||||
public static Object invoke(Object obj, String methodName, float newValue)
|
||||
throws NoSuchMethodException {
|
||||
try {
|
||||
Method method = obj.getClass().getMethod(methodName, new Class[] { Float.TYPE} );
|
||||
return method.invoke(obj, new Object[] { new Float(newValue)});
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new NoSuchMethodException(methodName+" is not accessible");
|
||||
} catch (InvocationTargetException e) {
|
||||
// The method is not supposed to throw exceptions
|
||||
throw new InternalError(e.getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified setter method if it exists.
|
||||
*
|
||||
* @param obj The object on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
*/
|
||||
public static Object invoke(Object obj, String methodName, Class clazz, Object newValue)
|
||||
throws NoSuchMethodException {
|
||||
try {
|
||||
Method method = obj.getClass().getMethod(methodName, new Class[] { clazz } );
|
||||
return method.invoke(obj, new Object[] { newValue});
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new NoSuchMethodException(methodName+" is not accessible");
|
||||
} catch (InvocationTargetException e) {
|
||||
// The method is not supposed to throw exceptions
|
||||
throw new InternalError(e.getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified setter method if it exists.
|
||||
*
|
||||
* @param obj The object on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
*/
|
||||
public static Object invoke(Object obj, String methodName, Class[] clazz, Object... newValue)
|
||||
throws NoSuchMethodException {
|
||||
try {
|
||||
Method method = obj.getClass().getMethod(methodName, clazz );
|
||||
return method.invoke(obj, newValue);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new NoSuchMethodException(methodName+" is not accessible");
|
||||
} catch (InvocationTargetException e) {
|
||||
// The method is not supposed to throw exceptions
|
||||
InternalError error = new InternalError(e.getMessage());
|
||||
error.initCause((e.getCause() != null) ? e.getCause() : e);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified setter method if it exists.
|
||||
*
|
||||
* @param obj The object on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
*/
|
||||
public static void invokeIfExists(Object obj, String methodName) {
|
||||
try {
|
||||
invoke(obj, methodName);
|
||||
} catch (NoSuchMethodException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified setter method if it exists.
|
||||
*
|
||||
* @param obj The object on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
*/
|
||||
public static void invokeIfExists(Object obj, String methodName, float newValue) {
|
||||
try {
|
||||
invoke(obj, methodName, newValue);
|
||||
} catch (NoSuchMethodException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified method if it exists.
|
||||
*
|
||||
* @param obj The object on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
*/
|
||||
public static void invokeIfExists(Object obj, String methodName, boolean newValue) {
|
||||
try {
|
||||
invoke(obj, methodName, newValue);
|
||||
} catch (NoSuchMethodException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invokes the specified setter method if it exists.
|
||||
*
|
||||
* @param obj The object on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
*/
|
||||
public static void invokeIfExists(Object obj, String methodName, Class clazz, Object newValue) {
|
||||
try {
|
||||
invoke(obj, methodName, clazz, newValue);
|
||||
} catch (NoSuchMethodException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the specified setter method if it exists.
|
||||
*
|
||||
* @param obj The object on which to invoke the method.
|
||||
* @param methodName The name of the method.
|
||||
*/
|
||||
public static void invokeIfExistsWithEnum(Object obj, String methodName, String enumClassName, String enumValueName) {
|
||||
try {
|
||||
Class enumClass = Class.forName(enumClassName);
|
||||
Object enumValue = invokeStatic("java.lang.Enum", "valueOf", new Class[] {Class.class, String.class},
|
||||
new Object[] {enumClass, enumValueName}
|
||||
);
|
||||
invoke(obj, methodName, enumClass, enumValue);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// ignore
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
// ignore
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
73
libsrc/gif/build.xml
Normal file
73
libsrc/gif/build.xml
Normal file
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- You may freely edit this file. See commented blocks below for -->
|
||||
<!-- some examples of how to customize the build. -->
|
||||
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||
<!-- the Compile on Save feature is turned off for the project. -->
|
||||
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||
<!-- in the project's Project Properties dialog box.-->
|
||||
<project name="gif" default="default" basedir=".">
|
||||
<description>Builds, tests, and runs the project gif.</description>
|
||||
<import file="nbproject/build-impl.xml"/>
|
||||
<!--
|
||||
|
||||
There exist several targets which are by default empty and which can be
|
||||
used for execution of your tasks. These targets are usually executed
|
||||
before and after some main targets. They are:
|
||||
|
||||
-pre-init: called before initialization of project properties
|
||||
-post-init: called after initialization of project properties
|
||||
-pre-compile: called before javac compilation
|
||||
-post-compile: called after javac compilation
|
||||
-pre-compile-single: called before javac compilation of single file
|
||||
-post-compile-single: called after javac compilation of single file
|
||||
-pre-compile-test: called before javac compilation of JUnit tests
|
||||
-post-compile-test: called after javac compilation of JUnit tests
|
||||
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||
-pre-jar: called before JAR building
|
||||
-post-jar: called after JAR building
|
||||
-post-clean: called after cleaning build products
|
||||
|
||||
(Targets beginning with '-' are not intended to be called on their own.)
|
||||
|
||||
Example of inserting an obfuscator after compilation could look like this:
|
||||
|
||||
<target name="-post-compile">
|
||||
<obfuscate>
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
</obfuscate>
|
||||
</target>
|
||||
|
||||
For list of available properties check the imported
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
|
||||
Another way to customize the build is by overriding existing main targets.
|
||||
The targets of interest are:
|
||||
|
||||
-init-macrodef-javac: defines macro for javac compilation
|
||||
-init-macrodef-junit: defines macro for junit execution
|
||||
-init-macrodef-debug: defines macro for class debugging
|
||||
-init-macrodef-java: defines macro for class execution
|
||||
-do-jar: JAR building
|
||||
run: execution of project
|
||||
-javadoc-build: Javadoc generation
|
||||
test-report: JUnit report generation
|
||||
|
||||
An example of overriding the target for project execution could look like this:
|
||||
|
||||
<target name="run" depends="gif-impl.jar">
|
||||
<exec dir="bin" executable="launcher.exe">
|
||||
<arg file="${dist.jar}"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
Notice that the overridden target depends on the jar target and not only on
|
||||
the compile target as the regular run target does. Again, for a list of available
|
||||
properties which you can use, check the target you are overriding in the
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
-->
|
||||
</project>
|
||||
1413
libsrc/gif/nbproject/build-impl.xml
Normal file
1413
libsrc/gif/nbproject/build-impl.xml
Normal file
File diff suppressed because it is too large
Load Diff
8
libsrc/gif/nbproject/genfiles.properties
Normal file
8
libsrc/gif/nbproject/genfiles.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
build.xml.data.CRC32=c07cf2d0
|
||||
build.xml.script.CRC32=d45952bc
|
||||
build.xml.stylesheet.CRC32=8064a381@1.68.1.46
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=c07cf2d0
|
||||
nbproject/build-impl.xml.script.CRC32=178a9ed1
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.74.1.48
|
||||
71
libsrc/gif/nbproject/project.properties
Normal file
71
libsrc/gif/nbproject/project.properties
Normal file
@@ -0,0 +1,71 @@
|
||||
annotation.processing.enabled=true
|
||||
annotation.processing.enabled.in.editor=false
|
||||
annotation.processing.processor.options=
|
||||
annotation.processing.processors.list=
|
||||
annotation.processing.run.all.processors=true
|
||||
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
||||
build.classes.dir=${build.dir}/classes
|
||||
build.classes.excludes=**/*.java,**/*.form
|
||||
# This directory is removed when the project is cleaned:
|
||||
build.dir=build
|
||||
build.generated.dir=${build.dir}/generated
|
||||
build.generated.sources.dir=${build.dir}/generated-sources
|
||||
# Only compile against the classpath explicitly listed here:
|
||||
build.sysclasspath=ignore
|
||||
build.test.classes.dir=${build.dir}/test/classes
|
||||
build.test.results.dir=${build.dir}/test/results
|
||||
# Uncomment to specify the preferred debugger connection transport:
|
||||
#debug.transport=dt_socket
|
||||
debug.classpath=\
|
||||
${run.classpath}
|
||||
debug.test.classpath=\
|
||||
${run.test.classpath}
|
||||
# Files in build.classes.dir which should be excluded from distribution jar
|
||||
dist.archive.excludes=
|
||||
# This directory is removed when the project is cleaned:
|
||||
dist.dir=dist
|
||||
dist.jar=../../lib/gif.jar
|
||||
dist.javadoc.dir=${dist.dir}/javadoc
|
||||
excludes=
|
||||
includes=**
|
||||
jar.compress=false
|
||||
javac.classpath=
|
||||
# Space-separated list of extra javac options
|
||||
javac.compilerargs=
|
||||
javac.deprecation=false
|
||||
javac.processorpath=\
|
||||
${javac.classpath}
|
||||
javac.source=1.7
|
||||
javac.target=1.7
|
||||
javac.test.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
javac.test.processorpath=\
|
||||
${javac.test.classpath}
|
||||
javadoc.additionalparam=
|
||||
javadoc.author=false
|
||||
javadoc.encoding=${source.encoding}
|
||||
javadoc.noindex=false
|
||||
javadoc.nonavbar=false
|
||||
javadoc.notree=false
|
||||
javadoc.private=false
|
||||
javadoc.splitindex=true
|
||||
javadoc.use=true
|
||||
javadoc.version=false
|
||||
javadoc.windowtitle=
|
||||
meta.inf.dir=${src.dir}/META-INF
|
||||
mkdist.disabled=true
|
||||
platform.active=default_platform
|
||||
run.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
# Space-separated list of JVM arguments used when running the project.
|
||||
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
|
||||
# To set system properties for unit tests define test-sys-prop.name=value:
|
||||
run.jvmargs=
|
||||
run.test.classpath=\
|
||||
${javac.test.classpath}:\
|
||||
${build.test.classes.dir}
|
||||
source.encoding=UTF-8
|
||||
src.dir=src
|
||||
test.src.dir=test
|
||||
15
libsrc/gif/nbproject/project.xml
Normal file
15
libsrc/gif/nbproject/project.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.java.j2seproject</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<name>gif</name>
|
||||
<source-roots>
|
||||
<root id="src.dir"/>
|
||||
</source-roots>
|
||||
<test-roots>
|
||||
<root id="test.src.dir"/>
|
||||
</test-roots>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
191
libsrc/gif/src/net/kroo/elliot/GifSequenceWriter.java
Normal file
191
libsrc/gif/src/net/kroo/elliot/GifSequenceWriter.java
Normal file
@@ -0,0 +1,191 @@
|
||||
package net.kroo.elliot;
|
||||
|
||||
/*
|
||||
|
||||
Created by Elliot Kroo on 2009-04-25.
|
||||
|
||||
This work is licensed under the Creative Commons Attribution 3.0 Unported
|
||||
License. To view a copy of this license, visit
|
||||
http://creativecommons.org/licenses/by/3.0/ or send a letter to Creative
|
||||
Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
|
||||
*/
|
||||
|
||||
import javax.imageio.*;
|
||||
import javax.imageio.metadata.*;
|
||||
import javax.imageio.stream.*;
|
||||
import java.awt.image.*;
|
||||
import java.io.*;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class GifSequenceWriter {
|
||||
protected ImageWriter gifWriter;
|
||||
protected ImageWriteParam imageWriteParam;
|
||||
protected IIOMetadata imageMetaData;
|
||||
|
||||
/**
|
||||
* Creates a new GifSequenceWriter
|
||||
*
|
||||
* @param outputStream the ImageOutputStream to be written to
|
||||
* @param imageType one of the imageTypes specified in BufferedImage
|
||||
* @param timeBetweenFramesMS the time between frames in miliseconds
|
||||
* @param loopContinuously wether the gif should loop repeatedly
|
||||
* @throws IIOException if no gif ImageWriters are found
|
||||
*
|
||||
* @author Elliot Kroo (elliot[at]kroo[dot]net)
|
||||
*/
|
||||
public GifSequenceWriter(
|
||||
ImageOutputStream outputStream,
|
||||
int imageType,
|
||||
int timeBetweenFramesMS,
|
||||
boolean loopContinuously) throws IIOException, IOException {
|
||||
// my method to create a writer
|
||||
gifWriter = getWriter();
|
||||
imageWriteParam = gifWriter.getDefaultWriteParam();
|
||||
ImageTypeSpecifier imageTypeSpecifier =
|
||||
ImageTypeSpecifier.createFromBufferedImageType(imageType);
|
||||
|
||||
imageMetaData =
|
||||
gifWriter.getDefaultImageMetadata(imageTypeSpecifier,
|
||||
imageWriteParam);
|
||||
|
||||
String metaFormatName = imageMetaData.getNativeMetadataFormatName();
|
||||
|
||||
IIOMetadataNode root = (IIOMetadataNode)
|
||||
imageMetaData.getAsTree(metaFormatName);
|
||||
|
||||
IIOMetadataNode graphicsControlExtensionNode = getNode(
|
||||
root,
|
||||
"GraphicControlExtension");
|
||||
|
||||
graphicsControlExtensionNode.setAttribute("disposalMethod", "restoreToBackgroundColor"); //JPEXS: changed none to restoreToBackgroundColor
|
||||
graphicsControlExtensionNode.setAttribute("userInputFlag", "FALSE");
|
||||
graphicsControlExtensionNode.setAttribute(
|
||||
"transparentColorFlag",
|
||||
"FALSE");
|
||||
graphicsControlExtensionNode.setAttribute(
|
||||
"delayTime",
|
||||
Integer.toString(timeBetweenFramesMS / 10));
|
||||
graphicsControlExtensionNode.setAttribute(
|
||||
"transparentColorIndex",
|
||||
"0");
|
||||
|
||||
IIOMetadataNode commentsNode = getNode(root, "CommentExtensions");
|
||||
commentsNode.setAttribute("CommentExtension", "Created by MAH");
|
||||
|
||||
IIOMetadataNode appEntensionsNode = getNode(
|
||||
root,
|
||||
"ApplicationExtensions");
|
||||
|
||||
IIOMetadataNode child = new IIOMetadataNode("ApplicationExtension");
|
||||
|
||||
child.setAttribute("applicationID", "NETSCAPE");
|
||||
child.setAttribute("authenticationCode", "2.0");
|
||||
|
||||
int loop = loopContinuously ? 0 : 1;
|
||||
|
||||
child.setUserObject(new byte[]{ 0x1, (byte) (loop & 0xFF), (byte)
|
||||
((loop >> 8) & 0xFF)});
|
||||
appEntensionsNode.appendChild(child);
|
||||
|
||||
imageMetaData.setFromTree(metaFormatName, root);
|
||||
|
||||
gifWriter.setOutput(outputStream);
|
||||
|
||||
gifWriter.prepareWriteSequence(null);
|
||||
}
|
||||
|
||||
public void writeToSequence(RenderedImage img) throws IOException {
|
||||
gifWriter.writeToSequence(
|
||||
new IIOImage(
|
||||
img,
|
||||
null,
|
||||
imageMetaData),
|
||||
imageWriteParam);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close this GifSequenceWriter object. This does not close the underlying
|
||||
* stream, just finishes off the GIF.
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
gifWriter.endWriteSequence();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first available GIF ImageWriter using
|
||||
* ImageIO.getImageWritersBySuffix("gif").
|
||||
*
|
||||
* @return a GIF ImageWriter object
|
||||
* @throws IIOException if no GIF image writers are returned
|
||||
*/
|
||||
private static ImageWriter getWriter() throws IIOException {
|
||||
Iterator<ImageWriter> iter = ImageIO.getImageWritersBySuffix("gif");
|
||||
if(!iter.hasNext()) {
|
||||
throw new IIOException("No GIF Image Writers Exist");
|
||||
} else {
|
||||
return iter.next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an existing child node, or creates and returns a new child node (if
|
||||
* the requested node does not exist).
|
||||
*
|
||||
* @param rootNode the <tt>IIOMetadataNode</tt> to search for the child node.
|
||||
* @param nodeName the name of the child node.
|
||||
*
|
||||
* @return the child node, if found or a new node created with the given name.
|
||||
*/
|
||||
private static IIOMetadataNode getNode(
|
||||
IIOMetadataNode rootNode,
|
||||
String nodeName) {
|
||||
int nNodes = rootNode.getLength();
|
||||
for (int i = 0; i < nNodes; i++) {
|
||||
if (rootNode.item(i).getNodeName().compareToIgnoreCase(nodeName)
|
||||
== 0) {
|
||||
return((IIOMetadataNode) rootNode.item(i));
|
||||
}
|
||||
}
|
||||
IIOMetadataNode node = new IIOMetadataNode(nodeName);
|
||||
rootNode.appendChild(node);
|
||||
return(node);
|
||||
}
|
||||
|
||||
/**
|
||||
public GifSequenceWriter(
|
||||
BufferedOutputStream outputStream,
|
||||
int imageType,
|
||||
int timeBetweenFramesMS,
|
||||
boolean loopContinuously) {
|
||||
|
||||
*/
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length > 1) {
|
||||
// grab the output image type from the first image in the sequence
|
||||
BufferedImage firstImage = ImageIO.read(new File(args[0]));
|
||||
|
||||
// create a new BufferedOutputStream with the last argument
|
||||
ImageOutputStream output =
|
||||
new FileImageOutputStream(new File(args[args.length - 1]));
|
||||
|
||||
// create a gif sequence with the type of the first image, 1 second
|
||||
// between frames, which loops continuously
|
||||
GifSequenceWriter writer =
|
||||
new GifSequenceWriter(output, firstImage.getType(), 1, false);
|
||||
|
||||
// write out the first image to our sequence...
|
||||
writer.writeToSequence(firstImage);
|
||||
for(int i=1; i<args.length-1; i++) {
|
||||
BufferedImage nextImage = ImageIO.read(new File(args[i]));
|
||||
writer.writeToSequence(nextImage);
|
||||
}
|
||||
|
||||
writer.close();
|
||||
output.close();
|
||||
} else {
|
||||
System.out.println(
|
||||
"Usage: java GifSequenceWriter [list of gif files] [output file]");
|
||||
}
|
||||
}
|
||||
}
|
||||
73
libsrc/jpacker/build.xml
Normal file
73
libsrc/jpacker/build.xml
Normal file
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- You may freely edit this file. See commented blocks below for -->
|
||||
<!-- some examples of how to customize the build. -->
|
||||
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||
<!-- the Compile on Save feature is turned off for the project. -->
|
||||
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||
<!-- in the project's Project Properties dialog box.-->
|
||||
<project name="jpacker" default="default" basedir=".">
|
||||
<description>Builds, tests, and runs the project jpacker.</description>
|
||||
<import file="nbproject/build-impl.xml"/>
|
||||
<!--
|
||||
|
||||
There exist several targets which are by default empty and which can be
|
||||
used for execution of your tasks. These targets are usually executed
|
||||
before and after some main targets. They are:
|
||||
|
||||
-pre-init: called before initialization of project properties
|
||||
-post-init: called after initialization of project properties
|
||||
-pre-compile: called before javac compilation
|
||||
-post-compile: called after javac compilation
|
||||
-pre-compile-single: called before javac compilation of single file
|
||||
-post-compile-single: called after javac compilation of single file
|
||||
-pre-compile-test: called before javac compilation of JUnit tests
|
||||
-post-compile-test: called after javac compilation of JUnit tests
|
||||
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||
-pre-jar: called before JAR building
|
||||
-post-jar: called after JAR building
|
||||
-post-clean: called after cleaning build products
|
||||
|
||||
(Targets beginning with '-' are not intended to be called on their own.)
|
||||
|
||||
Example of inserting an obfuscator after compilation could look like this:
|
||||
|
||||
<target name="-post-compile">
|
||||
<obfuscate>
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
</obfuscate>
|
||||
</target>
|
||||
|
||||
For list of available properties check the imported
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
|
||||
Another way to customize the build is by overriding existing main targets.
|
||||
The targets of interest are:
|
||||
|
||||
-init-macrodef-javac: defines macro for javac compilation
|
||||
-init-macrodef-junit: defines macro for junit execution
|
||||
-init-macrodef-debug: defines macro for class debugging
|
||||
-init-macrodef-java: defines macro for class execution
|
||||
-do-jar: JAR building
|
||||
run: execution of project
|
||||
-javadoc-build: Javadoc generation
|
||||
test-report: JUnit report generation
|
||||
|
||||
An example of overriding the target for project execution could look like this:
|
||||
|
||||
<target name="run" depends="jpacker-impl.jar">
|
||||
<exec dir="bin" executable="launcher.exe">
|
||||
<arg file="${dist.jar}"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
Notice that the overridden target depends on the jar target and not only on
|
||||
the compile target as the regular run target does. Again, for a list of available
|
||||
properties which you can use, check the target you are overriding in the
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
-->
|
||||
</project>
|
||||
BIN
libsrc/jpacker/jargs.jar
Normal file
BIN
libsrc/jpacker/jargs.jar
Normal file
Binary file not shown.
3
libsrc/jpacker/manifest.mf
Normal file
3
libsrc/jpacker/manifest.mf
Normal file
@@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
X-COMMENT: Main-Class will be added automatically by build
|
||||
|
||||
1413
libsrc/jpacker/nbproject/build-impl.xml
Normal file
1413
libsrc/jpacker/nbproject/build-impl.xml
Normal file
File diff suppressed because it is too large
Load Diff
8
libsrc/jpacker/nbproject/genfiles.properties
Normal file
8
libsrc/jpacker/nbproject/genfiles.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
build.xml.data.CRC32=811ea359
|
||||
build.xml.script.CRC32=f4a6aa27
|
||||
build.xml.stylesheet.CRC32=8064a381@1.74.1.48
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=811ea359
|
||||
nbproject/build-impl.xml.script.CRC32=a8ed580a
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.74.1.48
|
||||
77
libsrc/jpacker/nbproject/project.properties
Normal file
77
libsrc/jpacker/nbproject/project.properties
Normal file
@@ -0,0 +1,77 @@
|
||||
annotation.processing.enabled=true
|
||||
annotation.processing.enabled.in.editor=false
|
||||
annotation.processing.processors.list=
|
||||
annotation.processing.run.all.processors=true
|
||||
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
||||
application.title=jpacker
|
||||
application.vendor=
|
||||
build.classes.dir=${build.dir}/classes
|
||||
build.classes.excludes=**/*.java,**/*.form
|
||||
# This directory is removed when the project is cleaned:
|
||||
build.dir=build
|
||||
build.generated.dir=${build.dir}/generated
|
||||
build.generated.sources.dir=${build.dir}/generated-sources
|
||||
# Only compile against the classpath explicitly listed here:
|
||||
build.sysclasspath=ignore
|
||||
build.test.classes.dir=${build.dir}/test/classes
|
||||
build.test.results.dir=${build.dir}/test/results
|
||||
# Uncomment to specify the preferred debugger connection transport:
|
||||
#debug.transport=dt_socket
|
||||
debug.classpath=\
|
||||
${run.classpath}
|
||||
debug.test.classpath=\
|
||||
${run.test.classpath}
|
||||
# Files in build.classes.dir which should be excluded from distribution jar
|
||||
dist.archive.excludes=
|
||||
# This directory is removed when the project is cleaned:
|
||||
dist.dir=dist
|
||||
dist.jar=../../lib/jpacker.jar
|
||||
dist.javadoc.dir=${dist.dir}/javadoc
|
||||
endorsed.classpath=
|
||||
excludes=
|
||||
file.reference.jargs.jar=jargs.jar
|
||||
includes=**
|
||||
jar.compress=false
|
||||
javac.classpath=\
|
||||
${file.reference.jargs.jar}
|
||||
# Space-separated list of extra javac options
|
||||
javac.compilerargs=
|
||||
javac.deprecation=false
|
||||
javac.processorpath=\
|
||||
${javac.classpath}
|
||||
javac.source=1.7
|
||||
javac.target=1.7
|
||||
javac.test.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
javac.test.processorpath=\
|
||||
${javac.test.classpath}
|
||||
javadoc.additionalparam=
|
||||
javadoc.author=false
|
||||
javadoc.encoding=${source.encoding}
|
||||
javadoc.noindex=false
|
||||
javadoc.nonavbar=false
|
||||
javadoc.notree=false
|
||||
javadoc.private=false
|
||||
javadoc.splitindex=true
|
||||
javadoc.use=true
|
||||
javadoc.version=false
|
||||
javadoc.windowtitle=
|
||||
main.class=com.jpacker.JPacker
|
||||
manifest.file=manifest.mf
|
||||
meta.inf.dir=${src.dir}/META-INF
|
||||
mkdist.disabled=true
|
||||
platform.active=default_platform
|
||||
run.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
# Space-separated list of JVM arguments used when running the project.
|
||||
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
|
||||
# To set system properties for unit tests define test-sys-prop.name=value:
|
||||
run.jvmargs=
|
||||
run.test.classpath=\
|
||||
${javac.test.classpath}:\
|
||||
${build.test.classes.dir}
|
||||
source.encoding=UTF-8
|
||||
src.dir=src
|
||||
test.src.dir=test
|
||||
15
libsrc/jpacker/nbproject/project.xml
Normal file
15
libsrc/jpacker/nbproject/project.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.java.j2seproject</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<name>jpacker</name>
|
||||
<source-roots>
|
||||
<root id="src.dir"/>
|
||||
</source-roots>
|
||||
<test-roots>
|
||||
<root id="test.src.dir"/>
|
||||
</test-roots>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
197
libsrc/jpacker/src/com/jpacker/JPacker.java
Normal file
197
libsrc/jpacker/src/com/jpacker/JPacker.java
Normal file
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker;
|
||||
|
||||
import com.jpacker.exceptions.EmptyFileException;
|
||||
import jargs.gnu.CmdLineParser;
|
||||
import jargs.gnu.CmdLineParser.IllegalOptionValueException;
|
||||
import jargs.gnu.CmdLineParser.Option;
|
||||
import jargs.gnu.CmdLineParser.UnknownOptionException;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public class JPacker {
|
||||
|
||||
/**
|
||||
* @param args
|
||||
* the command line arguments
|
||||
*/
|
||||
public static void main(String[] args) throws FileNotFoundException, IOException {
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
CmdLineParser parser = new CmdLineParser();
|
||||
Option baseOpt = parser.addIntegerOption('b', "base");
|
||||
Option columnsOpt = parser.addIntegerOption('c', "column");
|
||||
Option helpOpt = parser.addBooleanOption('h', "help");
|
||||
Option minifyOpt = parser.addBooleanOption('m', "minify");
|
||||
Option outputFilenameOpt = parser.addStringOption('o', "output");
|
||||
Option quietOpt = parser.addBooleanOption('q', "quiet");
|
||||
Option shrinkVariablesOpt = parser.addBooleanOption('s', "shrink-variables");
|
||||
|
||||
Writer out = null;
|
||||
BufferedReader in = null;
|
||||
|
||||
try {
|
||||
if (args.length == 0) {
|
||||
throw new RuntimeException("No input file");
|
||||
}
|
||||
|
||||
parser.parse(args);
|
||||
|
||||
Boolean help = (Boolean) parser.getOptionValue(helpOpt);
|
||||
if (help != null && help.booleanValue()) {
|
||||
printUsage();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
boolean minify = parser.getOptionValue(minifyOpt) != null;
|
||||
boolean shrinkVariables = parser.getOptionValue(shrinkVariablesOpt) != null;
|
||||
boolean quiet = parser.getOptionValue(quietOpt) != null;
|
||||
Integer base = (Integer) parser.getOptionValue(baseOpt);
|
||||
Integer columns = (Integer) parser.getOptionValue(columnsOpt);
|
||||
|
||||
if (parser.getRemainingArgs().length == 0) {
|
||||
throw new FileNotFoundException("No input file was provided");
|
||||
}
|
||||
|
||||
String inputFilename = parser.getRemainingArgs()[0];
|
||||
String outputFilename = (String) parser.getOptionValue(outputFilenameOpt);
|
||||
|
||||
JPackerExecuter executer;
|
||||
if (base == null) {
|
||||
executer = new JPackerExecuter(JPackerEncoding.NONE);
|
||||
} else {
|
||||
executer = new JPackerExecuter(getEncoding(baseOpt, base));
|
||||
}
|
||||
in = new BufferedReader(new FileReader(new File(inputFilename)));
|
||||
String unpacked = buildStringFromTextFile(in);
|
||||
if (unpacked.isEmpty()) {
|
||||
throw new EmptyFileException("The file is empty");
|
||||
}
|
||||
|
||||
String packed = executer.pack(unpacked, minify, shrinkVariables);
|
||||
|
||||
if (outputFilename == null) {
|
||||
out = new OutputStreamWriter(System.out);
|
||||
} else {
|
||||
out = new OutputStreamWriter(new FileOutputStream(outputFilename));
|
||||
}
|
||||
|
||||
if (columns != null) {
|
||||
packed = wrapLines(packed, columns);
|
||||
}
|
||||
|
||||
out.write(packed.replace("\n", System.getProperty("line.separator")));
|
||||
out.close();
|
||||
if (!quiet) {
|
||||
long endTime = System.currentTimeMillis();
|
||||
System.out.printf("Reduced to %.2f%% of its original size in %.4f seconds.\n",
|
||||
((double) packed.length() / (double) unpacked.length()) * 100,
|
||||
(double) (endTime - startTime) / 1000);
|
||||
}
|
||||
|
||||
} catch (FileNotFoundException e) {
|
||||
System.out.println("File not found: " + e.getLocalizedMessage());
|
||||
System.exit(1);
|
||||
} catch (IllegalOptionValueException e) {
|
||||
System.out.println("Illegal option: " + e.getValue() + " - " + e.getOption());
|
||||
System.exit(1);
|
||||
} catch (UnknownOptionException e) {
|
||||
printUsage();
|
||||
System.exit(1);
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getLocalizedMessage());
|
||||
System.exit(1);
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
System.out.println(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
System.out.println(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void printUsage() {
|
||||
System.out.println("\nUsage: java -jar jpacker-x.y.z.jar [options] [input file]\n\n"
|
||||
+ "Options\n"
|
||||
+ " -b, --base Encoding base. Options are: 10, 36, 52, 62 \n"
|
||||
+ " and 95. Ignored if --minify option is set.\n"
|
||||
+ " -c, --column <column> Insert a line break after the specified column \n"
|
||||
+ " number.\n"
|
||||
+ " -h, --help Displays this information.\n"
|
||||
+ " -m, --minify Minify only, do not obfuscate.\n"
|
||||
+ " --minify and --base values will be ignored.\n"
|
||||
+ " -o <file>, --output <file> Place the output into <file>.\n"
|
||||
+ " Defaults to stdout.\n"
|
||||
+ " -q, --quiet Quiet mode, no message.\n"
|
||||
+ " -s, --shrink-variables Shrink variables. Ignored if --minify option \n"
|
||||
+ " is set.\n");
|
||||
}
|
||||
|
||||
private static String wrapLines(String packedScript, Integer columns) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < packedScript.length(); i++) {
|
||||
int end = ((i + columns) > (packedScript.length()) ? packedScript.length() : i + columns);
|
||||
sb.append(packedScript.substring(i, end)).append(System.getProperty("line.separator"));
|
||||
i = end + 1;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String buildStringFromTextFile(BufferedReader reader) throws FileNotFoundException, IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String s;
|
||||
while ((s = reader.readLine()) != null) {
|
||||
sb.append(s).append(System.getProperty("line.separator"));
|
||||
}
|
||||
reader.close();
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static JPackerEncoding getEncoding(Option option, Integer base) throws IllegalOptionValueException {
|
||||
switch (base) {
|
||||
case 10:
|
||||
return JPackerEncoding.NUMERIC;
|
||||
case 36:
|
||||
return JPackerEncoding.MID;
|
||||
case 52:
|
||||
return JPackerEncoding.BASIC;
|
||||
case 62:
|
||||
return JPackerEncoding.NORMAL;
|
||||
case 95:
|
||||
return JPackerEncoding.HIGH_ASCII;
|
||||
default:
|
||||
throw new IllegalOptionValueException(option, "Encoding base option not valid");
|
||||
}
|
||||
}
|
||||
}
|
||||
75
libsrc/jpacker/src/com/jpacker/JPackerEncoding.java
Normal file
75
libsrc/jpacker/src/com/jpacker/JPackerEncoding.java
Normal file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker;
|
||||
|
||||
import com.jpacker.encoders.BasicEncoder;
|
||||
import com.jpacker.encoders.Encoder;
|
||||
import com.jpacker.encoders.HighAsciiEncoder;
|
||||
import com.jpacker.encoders.MidEncoder;
|
||||
import com.jpacker.encoders.NormalEncoder;
|
||||
import com.jpacker.encoders.NumericEncoder;
|
||||
|
||||
/**
|
||||
* Enum of encoding levels
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*
|
||||
*/
|
||||
public enum JPackerEncoding {
|
||||
|
||||
/**
|
||||
* No encoding
|
||||
*/
|
||||
NONE(0, "", null),
|
||||
/**
|
||||
* Base<sub>10</sub> : [0-9]
|
||||
*/
|
||||
NUMERIC(10, "String", new NumericEncoder()),
|
||||
/**
|
||||
* Base<sub>36</sub> : [0-z]
|
||||
*/
|
||||
MID(36, "function(c){return c.toString(a)}", new MidEncoder()),
|
||||
/**
|
||||
* Base<sub>52</sub> : [a-Z]
|
||||
*/
|
||||
BASIC(52, "function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>25?String.fromCharCode(c+39):String.fromCharCode(c+97));", new BasicEncoder()),
|
||||
/**
|
||||
* Base<sub>62</sub> : [0-Z]
|
||||
*/
|
||||
NORMAL(62, "function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))}", new NormalEncoder()),
|
||||
/**
|
||||
* Base<sub>95</sub> : [¡-ÿ]
|
||||
*/
|
||||
HIGH_ASCII(95, "function(c){return(c<a?\"\":e(c/a))String.fromCharCode(c%a+161)}", new HighAsciiEncoder());
|
||||
private final int encodingBase;
|
||||
private final String encode;
|
||||
private Encoder encoder;
|
||||
|
||||
JPackerEncoding(int encodingBase, String encode, Encoder encoder) {
|
||||
this.encodingBase = encodingBase;
|
||||
this.encode = encode;
|
||||
this.encoder = encoder;
|
||||
}
|
||||
|
||||
public int getEncodingBase() {
|
||||
return encodingBase;
|
||||
}
|
||||
|
||||
public String getEncode() {
|
||||
return encode;
|
||||
}
|
||||
|
||||
public Encoder getEncoder() {
|
||||
return encoder;
|
||||
}
|
||||
}
|
||||
329
libsrc/jpacker/src/com/jpacker/JPackerExecuter.java
Normal file
329
libsrc/jpacker/src/com/jpacker/JPackerExecuter.java
Normal file
@@ -0,0 +1,329 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Formatter;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.jpacker.encoders.BasicEncoder;
|
||||
import com.jpacker.encoders.Encoder;
|
||||
import com.jpacker.strategies.DefaultReplacementStrategy;
|
||||
import com.jpacker.strategies.ReplacementStrategy;
|
||||
|
||||
/**
|
||||
* Packer class.
|
||||
*
|
||||
* Main jPacker class that packs the script.
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public class JPackerExecuter {
|
||||
|
||||
private JPackerEncoding encoding;
|
||||
private static final String UNPACK = "eval(function(p,a,c,k,e,r){e=%5$s;if(!''.replace(/^/,String)){while(c--)r[%6$s]=k[c]"
|
||||
+ "||%6$s;k=[function(e){return r[e]}];e=function(){return'\\\\w+'};c=1};while(c--)if(k[c])p=p."
|
||||
+ "replace(new RegExp('\\\\b'+e(c)+'\\\\b','g'),k[c]);return p}('%1$s',%2$s,%3$s,'%4$s'.split('|'),0,{}))";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param encoding
|
||||
* The encoding level for this instance
|
||||
*/
|
||||
public JPackerExecuter(JPackerEncoding encoding) {
|
||||
setEncoding(encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs the script
|
||||
*
|
||||
* @param script
|
||||
* The script to pack
|
||||
* @param minifyOnly
|
||||
* True if script should only be minified and not encoded and/or
|
||||
* its variables shrunk, false otherwise.
|
||||
* @param shrinkVariables
|
||||
* True if variables should be shrunk, false otherwise. If
|
||||
* minifyOnly is true, this option has no side effect.
|
||||
* @return The packed script
|
||||
*/
|
||||
public String pack(String script, boolean minifyOnly, boolean shrinkVariables) {
|
||||
script += "\n";
|
||||
script = minify(script);
|
||||
if (!minifyOnly) {
|
||||
if (shrinkVariables) {
|
||||
script = shrinkVariables(script);
|
||||
}
|
||||
if (encoding != JPackerEncoding.NONE) {
|
||||
script = encode(script);
|
||||
}
|
||||
}
|
||||
return script;
|
||||
}
|
||||
|
||||
// zero encoding - just removal of whitespace and comments
|
||||
private String minify(String script) {
|
||||
JPackerParser parser = new JPackerParser();
|
||||
ReplacementStrategy defaultStrat = new DefaultReplacementStrategy();
|
||||
// protect data
|
||||
parser = addDataRegEx(parser);
|
||||
script = parser.exec(script, defaultStrat);
|
||||
// remove white-space
|
||||
parser = addWhiteSpaceRegEx(parser);
|
||||
script = parser.exec(script, defaultStrat);
|
||||
// clean
|
||||
parser = addCleanUpRegEx(parser);
|
||||
script = parser.exec(script, defaultStrat);
|
||||
// done
|
||||
return script;
|
||||
}
|
||||
|
||||
private JPackerParser addDataRegEx(JPackerParser parser) {
|
||||
final String COMMENT1 = "(\\/\\/|;;;)[^\\n]*";
|
||||
final String COMMENT2 = "\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\/";
|
||||
final String REGEX = "\\/(\\\\[\\/\\\\]|[^*\\/])(\\\\.|[^\\/\\n\\\\])*\\/[gim]*";
|
||||
|
||||
// Packer.CONTINUE
|
||||
parser.remove("\\\\\\r?\\n");
|
||||
|
||||
parser.ignore("'(\\\\.|[^'\\\\])*'");
|
||||
parser.ignore("\"(\\\\.|[^\"\\\\])*\"");
|
||||
parser.ignore("\\/\\*@|@\\*\\/|\\/\\/@[^\\n]*\\n");
|
||||
parser.replace("(" + COMMENT1 + ")\\n\\s*(" + REGEX + ")?", "\n$3");
|
||||
parser.replace("(" + COMMENT2 + ")\\s*(" + REGEX + ")?", " $3");
|
||||
parser.replace("([\\[\\(\\^=,{}:;&|!*?])\\s*(" + REGEX + ")", "$1$2");
|
||||
return parser;
|
||||
}
|
||||
|
||||
private JPackerParser addCleanUpRegEx(JPackerParser parser) {
|
||||
parser.replace("\\(\\s*;\\s*;\\s*\\)", "(;;)");
|
||||
parser.ignore("throw[};]+[};]"); // safari 1.3 bug
|
||||
parser.replace(";+\\s*([};])", "$1");
|
||||
parser.remove(";;[^\\n\\r]+[\\n\\r]");
|
||||
return parser;
|
||||
}
|
||||
|
||||
private JPackerParser addWhiteSpaceRegEx(JPackerParser parser) {
|
||||
parser.replace("(\\d)\\s+(\\.\\s*[a-z\\$_\\[\\(])", "$1 $2");
|
||||
parser.replace("([+\\-])\\s+([+\\-])", "$1 $2");
|
||||
parser.replace("(\\b|\\$)\\s+(\\b|\\$)", "$1 $2");
|
||||
parser.replace("\\b\\s+\\$\\s+\\b", " $ ");
|
||||
parser.replace("\\$\\s+\\b", "$ ");
|
||||
parser.replace("\\b\\s+\\$", " $");
|
||||
parser.replace("\\b\\s+\\b", " ");
|
||||
parser.remove("\\s+");
|
||||
return parser;
|
||||
}
|
||||
|
||||
private String shrinkVariables(String script) {
|
||||
final Pattern pattern = Pattern.compile("^[^'\"]\\/");
|
||||
// identify blocks, particularly identify function blocks (which define
|
||||
// scope)
|
||||
Pattern blockPattern = Pattern.compile("(function\\s*[\\w$]*\\s*\\(\\s*([^\\)]*)\\s*\\)\\s*)?(\\{([^{}]*)\\})");
|
||||
List<String> blocks = new ArrayList<String>(); // store program blocks
|
||||
// (anything between
|
||||
// braces {})
|
||||
|
||||
final List<String> data = new ArrayList<String>(); // encoded strings
|
||||
// and regular
|
||||
// expressions
|
||||
|
||||
JPackerParser parser = new JPackerParser();
|
||||
parser = addDataRegEx(parser);
|
||||
script = parser.exec(script, new ReplacementStrategy() {
|
||||
|
||||
@Override
|
||||
public String replace(List<JPackerPattern> patterns, Matcher matcher) {
|
||||
String replacement = "#" + data.size();
|
||||
String string = matcher.group();
|
||||
if (pattern.matcher(string).find()) {
|
||||
replacement = string.charAt(0) + replacement;
|
||||
string = string.substring(1);
|
||||
}
|
||||
data.add(string);
|
||||
return replacement;
|
||||
}
|
||||
});
|
||||
|
||||
do {
|
||||
// put the blocks back
|
||||
Matcher blockMatcher = blockPattern.matcher(script);
|
||||
StringBuffer sb = new StringBuffer();
|
||||
while (blockMatcher.find()) {
|
||||
blockMatcher.appendReplacement(sb, encodeBlock(blockMatcher, blocks));
|
||||
}
|
||||
blockMatcher.appendTail(sb);
|
||||
script = sb.toString();
|
||||
} while (blockPattern.matcher(script).find());
|
||||
|
||||
while (Pattern.compile("~(\\d+)~").matcher(script).find()) {
|
||||
script = decodeBlock(script, blocks);
|
||||
}
|
||||
// put strings and regular expressions back
|
||||
Matcher storeMatcher = Pattern.compile("#(\\d+)").matcher(script);
|
||||
StringBuffer sb2 = new StringBuffer();
|
||||
while (storeMatcher.find()) {
|
||||
int num = Integer.parseInt(storeMatcher.group(1));
|
||||
storeMatcher.appendReplacement(sb2, Matcher.quoteReplacement(data.get(num)));
|
||||
}
|
||||
storeMatcher.appendTail(sb2);
|
||||
|
||||
return sb2.toString();
|
||||
}
|
||||
|
||||
private String encode(String script) {
|
||||
JPackerWords words = new JPackerWords(script, encoding);
|
||||
|
||||
Pattern wordsPattern = Pattern.compile("\\w+");
|
||||
Matcher wordsMatcher = wordsPattern.matcher(script);
|
||||
StringBuffer sb = new StringBuffer();
|
||||
while (wordsMatcher.find()) {
|
||||
JPackerWord tempWord = new JPackerWord(wordsMatcher.group());
|
||||
wordsMatcher.appendReplacement(sb, words.find(tempWord).getEncoded());
|
||||
}
|
||||
wordsMatcher.appendTail(sb);
|
||||
|
||||
int ascii = Math.min(Math.max(words.getWords().size(), 2), encoding.getEncodingBase());
|
||||
|
||||
String p = escape(sb.toString());
|
||||
String a = String.valueOf(ascii);
|
||||
String c = String.valueOf(words.getWords().size());
|
||||
String k = words.toString();
|
||||
String e = getEncode(ascii);
|
||||
String r = ascii > 10 ? "e(c)" : "c";
|
||||
|
||||
return new Formatter().format(UNPACK, p, a, c, k, e, r).toString();
|
||||
}
|
||||
|
||||
// encoder for program blocks
|
||||
private String encodeBlock(Matcher matcher, List<String> blocks) {
|
||||
|
||||
String block = matcher.group();
|
||||
String func = matcher.group(1);
|
||||
String args = matcher.group(2);
|
||||
|
||||
if (func != null && !func.isEmpty()) { // the block is a function block
|
||||
// decode the function block (THIS IS THE IMPORTANT BIT)
|
||||
// We are retrieving all sub-blocks and will re-parse them in light
|
||||
// of newly shrunk variables
|
||||
while (Pattern.compile("~(\\d+)~").matcher(block).find()) {
|
||||
block = decodeBlock(block, blocks);
|
||||
}
|
||||
|
||||
// create the list of variable and argument names
|
||||
Pattern varNamePattern = Pattern.compile("var\\s+[\\w$]+");
|
||||
Matcher varNameMatcher = varNamePattern.matcher(block);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (varNameMatcher.find()) {
|
||||
sb.append(varNameMatcher.group()).append(",");
|
||||
}
|
||||
|
||||
String vars = "";
|
||||
if (!sb.toString().isEmpty()) {
|
||||
vars = sb.deleteCharAt(sb.length() - 1).toString().replaceAll("var\\s+", "");
|
||||
}
|
||||
|
||||
String[] ids = concat(args.split("\\s*,\\s*"), vars.split("\\s*,\\s*"));
|
||||
Set<String> idList = new LinkedHashSet<String>();
|
||||
for (String s : ids) {
|
||||
if (!s.isEmpty()) {
|
||||
idList.add(s);
|
||||
}
|
||||
}
|
||||
// process each identifier
|
||||
int count = 0;
|
||||
String shortId;
|
||||
for (String id : idList) {
|
||||
id = id.trim();
|
||||
if (id.length() > 1) { // > 1 char
|
||||
id = Matcher.quoteReplacement(id);
|
||||
// find the next free short name (check everything in the
|
||||
// current scope)
|
||||
Encoder e = new BasicEncoder();
|
||||
do {
|
||||
shortId = e.encode(count++);
|
||||
} while (Pattern.compile("[^\\w$.]" + shortId + "[^\\w$:]").matcher(block).find());
|
||||
// replace the long name with the short name
|
||||
while (Pattern.compile("([^\\w$.])" + id + "([^\\w$:])").matcher(block).find()) {
|
||||
block = block.replaceAll("([^\\w$.])" + id + "([^\\w$:])", "$1" + shortId + "$2");
|
||||
}
|
||||
block = block.replaceAll("([^{,\\w$.])" + id + ":", "$1" + shortId + ":");
|
||||
}
|
||||
}
|
||||
}
|
||||
String replacement = "~" + blocks.size() + "~";
|
||||
blocks.add(block);
|
||||
return replacement;
|
||||
}
|
||||
|
||||
private String decodeBlock(String block, List<String> blocks) {
|
||||
Matcher encoded = Pattern.compile("~(\\d+)~").matcher(block);
|
||||
StringBuffer sbe = new StringBuffer();
|
||||
while (encoded.find()) {
|
||||
int num = Integer.parseInt(encoded.group(1));
|
||||
encoded.appendReplacement(sbe, Matcher.quoteReplacement(blocks.get(num)));
|
||||
}
|
||||
encoded.appendTail(sbe);
|
||||
return sbe.toString();
|
||||
}
|
||||
|
||||
private String[] concat(String[] a, String[] b) {
|
||||
String[] c = new String[a.length + b.length];
|
||||
System.arraycopy(a, 0, c, 0, a.length);
|
||||
System.arraycopy(b, 0, c, a.length, b.length);
|
||||
return c;
|
||||
}
|
||||
|
||||
private String getEncode(int ascii) {
|
||||
if (ascii > 96) {
|
||||
return JPackerEncoding.HIGH_ASCII.getEncode();
|
||||
} else if (ascii > 36) {
|
||||
return JPackerEncoding.NORMAL.getEncode();
|
||||
} else if (ascii > 10) {
|
||||
return JPackerEncoding.MID.getEncode();
|
||||
} else {
|
||||
return JPackerEncoding.NUMERIC.getEncode();
|
||||
}
|
||||
}
|
||||
|
||||
private String escape(String input) {
|
||||
// single quotes wrap the final string so escape them
|
||||
// also escape new lines required by conditional comments
|
||||
return input.replaceAll("([\\\\'])", "\\\\$1").replaceAll("[\\r\\n]+", "\\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Encoding level. Options are: {@link JPackerEncoding#NONE},
|
||||
* {@link JPackerEncoding#NUMERIC}, {@link JPackerEncoding#MID},
|
||||
* {@link JPackerEncoding#NORMAL} and {@link JPackerEncoding#HIGH_ASCII}.
|
||||
*
|
||||
* @return The current encoding level
|
||||
*/
|
||||
public JPackerEncoding getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the encoding level to use.
|
||||
*
|
||||
* @param encoding
|
||||
*/
|
||||
public final void setEncoding(JPackerEncoding encoding) {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
}
|
||||
182
libsrc/jpacker/src/com/jpacker/JPackerParser.java
Normal file
182
libsrc/jpacker/src/com/jpacker/JPackerParser.java
Normal file
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.jpacker.evaluators.DeleteEvaluator;
|
||||
import com.jpacker.evaluators.Evaluator;
|
||||
import com.jpacker.evaluators.IntegerEvaluator;
|
||||
import com.jpacker.evaluators.StringEvaluator;
|
||||
import com.jpacker.strategies.DefaultReplacementStrategy;
|
||||
import com.jpacker.strategies.ReplacementStrategy;
|
||||
|
||||
/**
|
||||
* Parser class that matches RegGrp.js.
|
||||
*
|
||||
* This class parses the script using the expressions added via
|
||||
* {@link #remove(String)}, {@link #ignore(String)},
|
||||
* {@link #replace(String,String)} and {@link #replace(String,Evaluator)}
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public class JPackerParser {
|
||||
|
||||
private static Pattern GROUPS = Pattern.compile("\\(");
|
||||
private static Pattern SUB_REPLACE = Pattern.compile("\\$(\\d+)");
|
||||
private static Pattern INDEXED = Pattern.compile("^\\$\\d+$");
|
||||
private static Pattern ESCAPE = Pattern.compile("\\\\.");
|
||||
private static Pattern ESCAPE_BRACKETS = Pattern.compile("\\(\\?[:=!]|\\[[^\\]]+\\]");
|
||||
private static Pattern DELETED = Pattern.compile("\\x01[^\\x01]*\\x01");
|
||||
private static String IGNORE = "$0";
|
||||
private List<JPackerPattern> jpatterns = new ArrayList<JPackerPattern>();
|
||||
|
||||
/**
|
||||
* Add an expression to be removed
|
||||
*
|
||||
* @param expression
|
||||
* Regular expression {@link String}
|
||||
*/
|
||||
public void remove(String expression) {
|
||||
replace(expression, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an expression to be ignored
|
||||
*
|
||||
* @param expression
|
||||
* Regular expression {@link String}
|
||||
*/
|
||||
public void ignore(String expression) {
|
||||
replace(expression, IGNORE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an expression to be replaced with the replacement string
|
||||
*
|
||||
* @param expression
|
||||
* Regular expression {@link String}
|
||||
* @param replacement
|
||||
* Replacement {@link String}. Use $1, $2, etc. for groups
|
||||
*/
|
||||
public void replace(String expression, String replacement) {
|
||||
if (replacement.isEmpty()) {
|
||||
replace(expression, new DeleteEvaluator());
|
||||
return;
|
||||
}
|
||||
Evaluator evaluator;
|
||||
// does the pattern deal with sub-expressions? and a simple lookup (e.g. $2)
|
||||
if (SUB_REPLACE.matcher(replacement).matches() && INDEXED.matcher(replacement).matches()) {
|
||||
evaluator = new IntegerEvaluator(Integer.parseInt(replacement.substring(1)));
|
||||
} else {
|
||||
evaluator = new StringEvaluator(replacement);
|
||||
}
|
||||
JPackerPattern jpattern = new JPackerPattern(expression, evaluator);
|
||||
// count the number of sub-expressions
|
||||
jpattern.setLength(countSubExpressions(expression));
|
||||
jpatterns.add(jpattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an expression to be replaced using an {@link Evaluator} object
|
||||
*
|
||||
* @param expression
|
||||
* Regular expression String
|
||||
* @param evaluator
|
||||
* The {@link Evaluator} object
|
||||
*/
|
||||
public void replace(String expression, Evaluator evaluator) {
|
||||
JPackerPattern jpattern = new JPackerPattern(expression, evaluator);
|
||||
// count the number of sub-expressions
|
||||
jpattern.setLength(countSubExpressions(expression));
|
||||
jpatterns.add(jpattern);
|
||||
}
|
||||
|
||||
// builds the patterns into a single regular expression
|
||||
private Pattern buildPatterns() {
|
||||
StringBuilder rtrn = new StringBuilder();
|
||||
for (JPackerPattern jpattern : jpatterns) {
|
||||
rtrn.append(jpattern).append("|");
|
||||
}
|
||||
rtrn.deleteCharAt(rtrn.length() - 1);
|
||||
return Pattern.compile(rtrn.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the parser in order to parse the script with the expressions
|
||||
* added via {@link #remove(String)}, {@link #ignore(String)},
|
||||
* {@link #replace(String,String)} and {@link #replace(String,Evaluator)}
|
||||
*
|
||||
* @param input
|
||||
* The script to be parsed
|
||||
* @return The parsed script
|
||||
*/
|
||||
public String exec(String input) {
|
||||
return exec(input, new DefaultReplacementStrategy());
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the parser in order to parse the script with the expressions
|
||||
* added via {@link #remove(String)}, {@link #ignore(String)},
|
||||
* {@link #replace(String,String)} and {@link #replace(String,Evaluator)}.
|
||||
* Using a {@link ReplacementStrategy} object, a custom replacement
|
||||
* algorithm can be used.
|
||||
*
|
||||
* @param input
|
||||
* The script to be parsed
|
||||
* @param strategy
|
||||
* The {@link ReplacementStrategy} object for custom replacement
|
||||
* @return The parsed script
|
||||
*/
|
||||
public String exec(String input, ReplacementStrategy strategy) {
|
||||
Matcher matcher = buildPatterns().matcher(input);
|
||||
StringBuffer sb = new StringBuffer(input.length());
|
||||
while (matcher.find()) {
|
||||
String rep = strategy.replace(jpatterns, matcher);
|
||||
if (rep != null && !rep.isEmpty()) {
|
||||
rep = Matcher.quoteReplacement(rep);
|
||||
}
|
||||
matcher.appendReplacement(sb, rep);
|
||||
}
|
||||
matcher.appendTail(sb);
|
||||
return DELETED.matcher(sb).replaceAll("");
|
||||
}
|
||||
|
||||
// count the number of sub-expressions
|
||||
private int countSubExpressions(String expression) {
|
||||
int cont = 0;
|
||||
Matcher matcher = GROUPS.matcher(internalEscape(expression));
|
||||
while (matcher.find()) {
|
||||
cont++;
|
||||
}
|
||||
// - add 1 because each group is itself a sub-expression
|
||||
return cont + 1;
|
||||
}
|
||||
|
||||
private String internalEscape(String str) {
|
||||
return ESCAPE_BRACKETS.matcher(ESCAPE.matcher(str).replaceAll("")).replaceAll("");
|
||||
}
|
||||
|
||||
/**
|
||||
* The patterns added to this {@link JPackerParser} object as a {@link List}
|
||||
* of {@link JPackerPattern}
|
||||
*
|
||||
* @return The {@link List} of {@link JPackerPattern} objects
|
||||
*/
|
||||
public List<JPackerPattern> getJPatterns() {
|
||||
return jpatterns;
|
||||
}
|
||||
}
|
||||
65
libsrc/jpacker/src/com/jpacker/JPackerPattern.java
Normal file
65
libsrc/jpacker/src/com/jpacker/JPackerPattern.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker;
|
||||
|
||||
import com.jpacker.evaluators.Evaluator;
|
||||
|
||||
/**
|
||||
* Wrapper class for each pattern
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public class JPackerPattern {
|
||||
|
||||
private String expression;
|
||||
private Evaluator evaluator;
|
||||
private int length;
|
||||
|
||||
public JPackerPattern() {
|
||||
}
|
||||
|
||||
public JPackerPattern(String expression, Evaluator evaluator) {
|
||||
this.expression = expression;
|
||||
this.evaluator = evaluator;
|
||||
evaluator.setJPattern(this);
|
||||
}
|
||||
|
||||
public String getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
public void setExpression(String expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(int length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public Evaluator getEvaluator() {
|
||||
return evaluator;
|
||||
}
|
||||
|
||||
public void setEvaluator(Evaluator evaluator) {
|
||||
this.evaluator = evaluator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + expression + ")";
|
||||
}
|
||||
}
|
||||
98
libsrc/jpacker/src/com/jpacker/JPackerWord.java
Normal file
98
libsrc/jpacker/src/com/jpacker/JPackerWord.java
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker;
|
||||
|
||||
/**
|
||||
* Wrapper class for a keyword
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public class JPackerWord {
|
||||
|
||||
private int count = 0;
|
||||
private String encoded = "";
|
||||
private int index = -1;
|
||||
private String word;
|
||||
private String replacement;
|
||||
|
||||
public JPackerWord(String word) {
|
||||
this.word = word;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public String getEncoded() {
|
||||
return encoded;
|
||||
}
|
||||
|
||||
public void setEncoded(String encoded) {
|
||||
this.encoded = encoded;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public String getWord() {
|
||||
return word;
|
||||
}
|
||||
|
||||
public void setWord(String word) {
|
||||
this.word = word;
|
||||
}
|
||||
|
||||
public String getReplacement() {
|
||||
return replacement;
|
||||
}
|
||||
|
||||
public void setReplacement(String replacement) {
|
||||
this.replacement = replacement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final JPackerWord other = (JPackerWord) obj;
|
||||
if ((this.word == null) ? (other.word != null) : !this.word.equals(other.word)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 37 * hash + (this.word != null ? this.word.hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return word;
|
||||
}
|
||||
}
|
||||
149
libsrc/jpacker/src/com/jpacker/JPackerWords.java
Normal file
149
libsrc/jpacker/src/com/jpacker/JPackerWords.java
Normal file
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Wrapper class for a {@link JPackerWord} list built based on script's keywords (later
|
||||
* wrapped into a JPackerWord list)
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public final class JPackerWords {
|
||||
|
||||
private JPackerEncoding encoding;
|
||||
private static final Pattern WORDS = Pattern.compile("\\w+");
|
||||
private List<JPackerWord> words = new ArrayList<JPackerWord>();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param script
|
||||
* The input script to look up for keywords
|
||||
* @param encoding
|
||||
* The encoding level to use
|
||||
*/
|
||||
public JPackerWords(String script, JPackerEncoding encoding) {
|
||||
this.encoding = encoding;
|
||||
Matcher matcher = WORDS.matcher(script);
|
||||
while (matcher.find()) {
|
||||
add(new JPackerWord(matcher.group()));
|
||||
}
|
||||
encode();
|
||||
}
|
||||
|
||||
private void add(JPackerWord word) {
|
||||
if (!words.contains(word)) {
|
||||
words.add(word);
|
||||
}
|
||||
JPackerWord w = find(word);
|
||||
w.setCount(w.getCount() + 1);
|
||||
}
|
||||
|
||||
private void encode() {
|
||||
// sort by frequency
|
||||
Collections.sort(words, new Comparator<JPackerWord>() {
|
||||
|
||||
@Override
|
||||
public int compare(JPackerWord x, JPackerWord y) {
|
||||
return y.getCount() - x.getCount();
|
||||
}
|
||||
});
|
||||
|
||||
// a dictionary of encoding base -> base10
|
||||
Map<String, Integer> encoded = new HashMap<String, Integer>();
|
||||
|
||||
for (int i = 0; i < words.size(); i++) {
|
||||
encoded.put(encoding.getEncoder().encode(i), i);
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
for (JPackerWord word : words) {
|
||||
if (encoded.containsKey(word.getWord())) {
|
||||
word.setIndex(encoded.get(word.getWord()));
|
||||
word.setReplacement("");
|
||||
} else {
|
||||
while (words.contains(new JPackerWord(encoding.getEncoder().encode(index)))) {
|
||||
index++;
|
||||
}
|
||||
word.setIndex(index++);
|
||||
word.setReplacement(word.getWord());
|
||||
}
|
||||
word.setEncoded(encoding.getEncoder().encode(word.getIndex()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// sort by encoding
|
||||
Collections.sort(words, new Comparator<JPackerWord>() {
|
||||
|
||||
@Override
|
||||
public int compare(JPackerWord x, JPackerWord y) {
|
||||
return x.getIndex() - y.getIndex();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a word in the JPackerWord list
|
||||
*
|
||||
* @param word
|
||||
* The JPackerWord object to find in the list
|
||||
* @return The JPackerWord object if found, null otherwise
|
||||
*/
|
||||
public JPackerWord find(JPackerWord word) {
|
||||
Iterator<JPackerWord> it = words.iterator();
|
||||
while (it.hasNext() == true) {
|
||||
JPackerWord pw = it.next();
|
||||
if (pw.equals(word)) {
|
||||
return pw;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of JPackerWord objects
|
||||
*
|
||||
* @return The list of JPackerWord objects
|
||||
*/
|
||||
public List<JPackerWord> getWords() {
|
||||
return words;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method has been overridden to return the list of JPackerWord objects
|
||||
* as a single String object separated by the '|' character
|
||||
*
|
||||
* @return A List of JPackerWord objects as a single String object separated
|
||||
* by the '|' character
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (JPackerWord word : words) {
|
||||
sb.append(word.getReplacement()).append('|');
|
||||
}
|
||||
sb.deleteCharAt(sb.length() - 1);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
27
libsrc/jpacker/src/com/jpacker/encoders/BasicEncoder.java
Normal file
27
libsrc/jpacker/src/com/jpacker/encoders/BasicEncoder.java
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker.encoders;
|
||||
|
||||
/**
|
||||
* Basic (base52) encoder: [a-Z]
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*
|
||||
*/
|
||||
public class BasicEncoder implements Encoder {
|
||||
|
||||
@Override
|
||||
public String encode(int c) {
|
||||
return (c < 52 ? "" : encode(c / 52)) + (((c = c % 52)) > 25 ? String.valueOf((char) (c + 39)) : String.valueOf((char) (c + 97)));
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user