Notifications
Clear all

[Closed] LZO decompress/compress data

an error not in english but in windows language (this is strange) tell me
– Runtime error: dotNet runtime exception: Cannot widen from source type to target type either because the source type is a not a primitive type or the conversion cannot be accomplished.
I resolved creating a dotnet bytes array, i test applying a value>255 and now work.
But “bytes” is a dotnetObjects and “compressed_bytes” is a max’s array.
How can i simplify the creation of a byte array (max use a int64 array ?) because my script read data stream from a file with:
bytes = for i=1 to DATASIZE collect readByte fin #unsigned

clearlistener()
(
SIZEOF = 100
bytes = dotNetObject "System.Byte[]" SIZEOF
for idx=0 to SIZEOF-1 do bytes.SetValue (dotNetObject "System.Byte" (random 0 455)) idx
	
lzo = dotnet.loadAssembly ((getDir #archives) +"/m2tw_scripts/lib/Simplicit.Net.Lzo.dll")
lzocompressor = lzo.createInstance "Simplicit.Net.Lzo.LZOCompressor"
--((dotNetClass "System.Text.Encoding").default.getbytes "m string")
compressed_bytes = lzocompressor.compress bytes

format "original : %
compressed : %
" (for idx=0 to SIZEOF-1 collect bytes.GetValue idx) compressed_bytes
)

this is a example and work, but it can done better ?


clearlistener()
try
(
	filename = getOpenFileName types:"all types (*.*)|*.*" caption:("LZO compression")
	if filename!=undefined then
	(
		fin = fopen filename "rb"
		SIZEOF = getFileSize filename
		
		bytes = dotNetObject "System.Byte[]" SIZEOF
		for idx=0 to SIZEOF-1 do bytes.SetValue (dotNetObject "System.Byte" (readByte fin #unsigned)) idx
		
		fclose fin
	
		lzo = dotnet.loadAssembly ((getDir #archives) +"/m2tw_scripts/lib/Simplicit.Net.Lzo.dll")
		lzocompressor = lzo.createInstance "Simplicit.Net.Lzo.LZOCompressor"
		compressed_bytes = lzocompressor.compress bytes
		--format "original : %
compressed : %
" (for idx=0 to SIZEOF-1 collect bytes.GetValue idx) compressed_bytes
		
		filename = getSaveFileName types:"all types (*.*)|*.*"caption:("LZO compression save")
		if filename!=undefined then
		(
			fout = fopen filename "wb"
			for b in compressed_bytes do writeByte fout b #unsigned
			fclose fout
		)
		
	)
)
catch ("ERROR")

i don’t undertand this error:


			SIZEOF = decompressed.count
			format ">> run lzo compression with sizeof:%
" SIZEOF
			BytesArray = dotnet.ValueToDotNetObject decompressed (dotNetClass "System.byte[]")
			lzo = dotnet.loadAssembly (LibraryDir +"/Simplicit.Net.Lzo.dll")
			lzocompressor = lzo.CreateInstance "Simplicit.Net.Lzo.LZOCompressor"
			compressed = lzocompressor.Decompress BytesArray


>> MAXScript Rollout Handler Exception: -- Runtime error: dotNet runtime exception: Arithmetic operation resulted in an overflow. <<


in max2011 there aren’t issue but in max9 i can’t build a Byte[] array:

in max9 this work:
arr = dotNetObject “System.Int32[]” 100
arr.set 0 (dotNetObject “System.Byte” 255)

but this not work:
arr = dotNetObject “System.Byte[]” 100
arr.set 0 (dotNetObject “System.Byte” 255)

because <dotNetObject “System.Byte” 255> return a int32… how is possible ? someone can help me a re-compiled a new Simpl icit.Net.Lzo.dll that accept a
dotNetObject “System.Int32[]” ?

to do this i re-compiled the dll:

	--BytesArray = dotnet.ValueToDotNetObject compressed (dotNetClass "System.Byte[]")
 	BytesArray = dotNetObject "System.Int32[]" SIZEOF
 	for i=0 to SIZEOF-1 do BytesArray.Set (dotNetObject "System.Int32" i) (dotNetObject "System.Byte" compressed[i+1])
 	
 	
 	lzo = dotnet.loadAssembly ((getDir #archives) +"/m2tw_scripts/lib/Simplicit.Net.Lzo.dll")
 	lzocompressor = lzo.createInstance "Simplicit.Net.Lzo.LZOCompressor"
 	decompressed_bytes = lzocompressor.Compress BytesArray

in C# i write:

...
 		public byte[] Compress(int[] src_int) {
 
 			byte[] src = new byte[src_int.Length];
 			for (int i = 0; i < src_int.Length; i++)
 			{
 				src[i] = (byte)(src_int[i] & 0xFF);
 			}
 ...

the new dll in the attachemtns

I wonder how you ever make this woking… maybe you test it on 32-bit Max?
I constantly get .Net exception:

An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)

and that means that those lzo.dll is built for x86 only. Did you get similar runtime error?

this script was tested in windowsXP32 bit with max9 32bit, but this weekend i will test it on windows7 64bit with max2011 32 and 64 bit.
The dll was compiled with Framework 2.0 (for max9 but work also for max2011)

max9 have a issue using “system.byte[]” becasue it convert always in “system.int32[]” so the lzo.dll don’t work… in max2011 there are the new function “dotnet.ValueToDotNetObject <max array of integer> (dotNetClass “System.Byte[]”)” but for big file (example 500000bytes) the heapsize increase a lot because max must build an array with 500.000 integers so i add a new function to let the dll read the file, but the output is always a big array and the file must be closed when reading.

in the attachment there are the new c# code, you can recompiled if you want or add new functions

when you decompres to convert some bytes array into float or integer you can do it:

convFN = dotnetClass "System.BitConverter"
for i=1 to SIZEOF by 4 collect
(
bytes =#(data[i],data[i+1],data[i+2],data[i+3])
floatvalue = conv.ToSingle (dotnet.ValueToDotNetObject bytes (dotNetClass "System.Byte[]")) 0
--intvalue = conv.ToInt32 (dotnet.ValueToDotNetObject bytes  (dotNetClass "System.Byte[]")) 0
)

Well, that make sense, I’m on XP x64 so I changed the target platform form AnyCPU to x86 in my vs project, and now (after re-comp.) it work in 32-bit Max, but am too write a methods to work directly with files in C#, as the Max convert .net bytes to integers anyway and this kill whole goodness (: but still no way to use the new wrapper with that lzo.dll in 64-bit Max.

I see no hope to run your assembly on x64, but just in case I will test it later on.
Meanwhile I attach my LZOCompressor.cs

I forget to add an example code, in case you want to test my cs version.
(note – for the test, put together (same folder) both dll’s, this script + example.tif)

(
	local curDir = getFilenamePath (getSourceFileName())
	local libLZO = curDir + "lzo.dll"
	local netLZO = curDir + "Simplicit.Net.Lzo.dll"
	local ready = (
		isStructDef DotNet and \
		not is64bitApplication() and \
		doesFileExist libLZO and \
		doesFileExist netLZO
	)
	if ready do
	(
		global netAsmLZO
		if netAsmLZO == undefined or \
		ClassOf netAsmLZO != dotNetObject or \
		(netAsmLZO.GetType()).ToString() != "System.Reflection.Assembly" \
		do (::netAsmLZO = DotNet.loadAssembly netLZO)
		ready = (::netAsmLZO != undefined)
	)
	if ready do
	(
		local LZO = netAsmLZO.CreateInstance "Simplicit.Net.Lzo.LZOCompressor"
		local inFile = curDir + "example.tif" -- example test file to process
		if doesFileExist inFile do
		(
			LZO.CompressFile inFile -- compress the file
			compFile = inFile + ".lzo"
			format "Len(orig): % | Len(comp): %
" (getFileSize inFile) (getFileSize compFile)
			renameFile inFile (inFile + ".bak") -- rename original file
			LZO.DecompressFile compFile -- decompress the file
			format "Is Equal (Orig & Decomp) = %
" (getFileSize inFile == getFileSize (inFile+".bak"))
		)
	)
)

Page 2 / 3