#include once "window9.bi"

'*******************************************************************************************
Function CompressMem(Byref BUF_DEST As Byte Ptr,byval SOURSEDATA As Byte ptr,Byval SIZEDATA As ULong, ByVal level As long=5) As Long Export
	Dim As long LEN_DEST=compressBound(SIZEDATA)
	BUF_DEST=Allocate(LEN_DEST)
	if BUF_DEST then
		compress2(BUF_DEST,cast(any ptr,@LEN_DEST),SOURSEDATA, SIZEDATA,level)
		BUF_DEST=ReAllocate(BUF_DEST,LEN_DEST+4)
		if BUF_DEST then
			fastcopy(BUF_DEST+LEN_DEST,@SIZEDATA,4)
			Function=LEN_DEST+4
		else
			print "Allocated memory error in CompressMem!"
		endif
	else
		print "Allocated memory error in CompressMem!"
	endif
End Function
'*******************************************************************************************
Function DeCompressMem(Byref BUF_COMPRESSED As Byte Ptr,byval SIZECOMPRESSED As Long,ByRef BUFDESTDATA As Byte Ptr) As Long Export
	Dim LEN_SRC As long ptr = Cast(Long ptr ,BUF_COMPRESSED+SIZECOMPRESSED-4) 
	dim as Long iRetBytes = *LEN_SRC
	BUFDESTDATA=ReAllocate(BUFDESTDATA,*LEN_SRC )
	if BUFDESTDATA then
		uncompress(BUFDESTDATA, Cast(any Ptr,@iRetBytes), BUF_COMPRESSED, SIZECOMPRESSED-4)
		Return iRetBytes
	else
		print "Allocated memory error in DeCompressMem!"
	endif
End Function

'*******************************************************************************************
Function CompressFile(ByRef filename As String, ByRef filenameDest As String,ByVal level As Long=5) As Long Export
	Dim As HANDLE handle,handle1
	Dim As Long numcikl,ostatok,sizesourse,endsize,fullend,SizeReadWrite
	Dim As Byte Ptr bufsourse,bufdest
	handle=Read_File(FileName)
	If handle<>cast(HANDLE,-1) Then
		sizesourse=Size_File(handle)
		If sizesourse>10000000 Then
			numcikl=sizesourse\10000000
			ostatok= sizesourse Mod 10000000
			Dim As Long massvalue(numcikl)
			handle1=Create_File(filenameDest)
			If handle1<>cast(HANDLE,-1) Then
				bufdest=Allocate(10000000)
				bufsourse=Allocate(10000000)
				if bufdest andalso bufsourse then
					For a As Long =1 To numcikl
						Read_Data(Handle,bufsourse,10000000)
						endsize=CompressMem(bufdest,bufsourse,10000000,level)
						fullend=fullend+endsize
						massvalue(a)=endsize
						Write_Data(handle1, bufdest,endsize)
					Next
					
					If ostatok>0 Then
						Read_Data(Handle,bufsourse,ostatok)
						endsize=CompressMem(bufdest,bufsourse,ostatok,level)
						fullend=fullend+endsize
						Write_Data(handle1, bufdest ,endsize)
					Else
						endsize=0
					EndIf
					For a As Long =1 To numcikl
						Write_Integer(handle1,massvalue(a))
					Next
					Write_Integer(handle1,endsize)
					Write_Integer(handle1,numcikl)
				else
					print "Allocated memory error in CompressFile!"
				endif
				Close_File(handle1)
				Function=fullend+numcikl*4+8
			endif
		Else
			bufsourse=Allocate(sizesourse)
			if bufsourse then
				Read_Data(Handle,bufsourse,sizesourse)
				bufdest=Allocate(sizesourse)
				if bufdest then
					endsize=CompressMem(bufdest,bufsourse,sizesourse,level)
					handle1=Create_File(filenameDest)
					If handle1<>cast(HANDLE,-1) Then
						Write_Data(handle1, bufdest ,endsize)
						Write_Integer(handle1,0)
						Close_File(handle1)
						Function=endsize+4
					EndIf
				else
					print "Allocated memory error in CompressFile!"
				endif
			else
				print "Allocated memory error in CompressFile!"
			endif
		EndIf
		Close_file(handle)
	EndIf
	if bufsourse then DeAllocate(bufsourse)
	if bufdest then DeAllocate(bufdest)
End Function
'*******************************************************************************************
Function DeCompressFile(ByRef filename As String, ByRef filenameDest As String) As Long export
	Dim As HANDLE handle,handle1
	Dim As Long numcikl,ostatok,sizesourse,endsize,fullend,SizeReadWrite
	Dim As Byte Ptr bufsourse,bufdest
	handle=Read_File(FileName)
	If handle<>cast(HANDLE,-1) Then
		Set_File_Pointer(handle,-8,FILE_END)
		ostatok=Read_Integer(handle)
		numcikl=Read_Integer(handle)
		If numcikl<>0 Then
			handle1=Create_File(filenameDest)
			If handle1<>cast(HANDLE,-1) Then
				Dim As ULong massvalue(numcikl+1)
				Set_File_Pointer(handle,-(numcikl*4+8),FILE_END)
				For a As long=1 To numcikl
					massvalue(a)=Read_Integer(handle)
				Next
				If ostatok<>0 Then
					massvalue(numcikl+1)=ostatok
					massvalue(0)=numcikl+1
				Else
					massvalue(0)=numcikl
				EndIf
				Set_File_Pointer(handle,0,FILE_Begin)
				bufsourse=Allocate(15000000)
				bufdest=Allocate(10000000)
				if bufsourse andalso bufdest then
					For a As Long=1 To massvalue(0)
						Read_Data(Handle,bufsourse,massvalue(a))
						endsize=DeCompressMem(bufsourse,massvalue(a),bufdest)
						Write_Data(handle1, bufdest,endsize)
						fullend+=endsize
					Next
				else
					print "Allocated memory error in DeCompressFile!"
				endif
				Close_File(handle1)
			EndIf
		Else
			handle1=Create_File(filenameDest)
			If handle1<>cast(HANDLE,-1) Then
				sizesourse=Size_File(handle)-4 
				Set_File_Pointer(handle,0,FILE_BEGIN)
				bufsourse=Allocate(sizesourse)
				if bufsourse then
					Read_data(Handle,bufsourse,sizesourse)
					bufdest=Allocate(sizesourse)
					if bufdest then
						endsize=DeCompressMem(bufsourse,sizesourse,bufdest)
						Write_Data(handle1, bufdest,endsize)
					else
						print "Allocated memory error in DeCompressFile!"
					endif
				else
					print "Allocated memory error in DeCompressFile!"
				endif
				Close_File(handle1)
				fullend=endsize
			EndIf
		EndIf
		Close_File(handle)
	EndIf
	if bufdest then DeAllocate(bufdest)
	if bufsourse then DeAllocate(bufsourse)
	Return fullend
End Function
'*******************************************************************************************