📄 compress.c
字号:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
#include<direct.h>
#include"N_error.h"
#include"tree.h"
#include"compress.h"
#include"binary.h"
#include"file.h"
//////////*size of file////////////////////////////////////////////////////////////////////
float IPUTFILESIZETOAL = 0;
/*如果申请空间根据用户反映循环的申请空间*////////////////////////////////////////////////////////////
void *CallSpace(unsigned int size)
{
void *A = 0;
while( ( A = malloc(size) ) == NULL )
{
if( !ASK("Not enough memory now!Do you want to close some tasks and retry?(Y/N)") )
break;
};
return A;
}
////////////////////////////////////////////////////////////////////
float SizeHelp(node_p root,int high)
{
if( IsLeaf(root))
{
return high*(float)GetWeight(root) ;
}
else
{
float L,R;
high++;
L = SizeHelp( GetLeft(root),high );
R = SizeHelp( GetRight(root),high );
high--;
return ( L + R);
}
}
unsigned int SizeOfOutFile(node_p root)
{ //when calculate the out size the end of codes out put a extranal char and a extranal information char so we add 2 to outfile size;
unsigned int r = 0;
r = (int)SizeHelp(root,0)/8+2;
return r;
}
/////////////////////////////////////////////////////////////////////////////////////////
int TranslateAndSto(FILE *fsource,FILE *fgoal,node_p const codetree,weight_t *KeyArray)
{
int help,ch;
node_p p = codetree;
unsigned char *const cwp = (unsigned char*)&help , *const positionp = (unsigned char*)&help+1;
*cwp = 0;
*positionp = 7;
while( (ch = ReadC(fsource)) != EOF)
{
if( !codetree)
{
N_ERROR("at TranslateAndSto the codetree is empty codetree !");
exit(0);
}
p = codetree;
while( !IsLeaf(p) )
{
if( KeyArray[ch] < GetKey(p) )
{
p = GetLeft(p);
WriteBitToC(cwp,0,*positionp);
if( *positionp )
{
(*positionp)--;
}
else
{
WriteFullCToFile( 1,cwp,fgoal);
*positionp = 7;
}
}
else
{
p = GetRight(p);
WriteBitToC(cwp,1,*positionp);
if( *positionp )
{
(*positionp)--;
}
else
{
WriteFullCToFile( 1,cwp,fgoal);
*positionp = 7;
}
}
}
}
if(*positionp != 7) WriteFullCToFile( 1,cwp,fgoal);//write the last char to file (may be not a full usefull char;)
return *positionp+1;//return how many bits of the end is rubbsh;
}
//////////////////////////////////////////////////////////////////////////////////////////
int GiveFormHead(FILE *fp)
{
if( WriteStrToF("this is a good compress software!",fp))
return 1;;
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
int CompressAFile(FILE *fpInFile,FILE *fpOutFile)
{
// char BitsOfRubbish;
unsigned long int InFileSize,OutFileSize;
weight_t A[256] = {0};
node_p root;
InFileSize = Statist(A,fpInFile);
IPUTFILESIZETOAL += InFileSize;
if(fseek(fpInFile,0,0) != 0)
{
N_ERROR("can not replace the pointor of source file");
return 0;
}
root = ConstructTree(A);
//if root is 0 then thie file is empty!
if( !root)
{
if(!WriteC( 0,fpOutFile,"At function compress Write file error"))
return 0;
if(!WriteC(0,fpOutFile,"At function compress Write file error"))
return 0;
WriteLIntToF(0,fpOutFile);
return (2 + 4);
}
//****when the file has more then a codes do it by use the tree***
else if( !IsLeaf(root) )
{
TreeSto(root,fpOutFile);
OutFileSize = SizeOfOutFile(root);
WriteLIntToF(InFileSize,fpOutFile);
TranslateAndSto(fpInFile,fpOutFile,root,A);
OutFileSize += LeafNumber(root)*9/8+1;
FreeTree(root);
return OutFileSize;
}
///********if the input file only has one code we just store how many numbers of that code the file has***********
else
{
if(!WriteC( GetLabel(root),fpOutFile,"At function compress Write file error"))
return 0;
if(!WriteC(GetLabel(root),fpOutFile,"At function compress Write file error"))
return 0;
WriteLIntToF(InFileSize,fpOutFile);
FreeTree(root);
return (2 + 4);
}
}
long int Compress(const char *InFilePath,const f_name_t InFileNames,const char *OutFilePath,const char *OutFileName)
{
char temp[MAX_PATH] = {0},temp1[MAX_PATH] = {0},*inname = 0;//use to ensure that the space of file name string is enough;
char errormsg[256] = {0};
long int OutSize = 0;
FILE *fps,*fpg;
f_name_node_p namep = InFileNames.head;
errormsg[0] = 0;
strcat(errormsg,"at function Compress Can't create file ");
strcat(errormsg,OutFileName);
///copy the file path to the enough space string and link the out file name to the end ;
OutFilePath = strcpy(temp,OutFilePath);
OutFileName = LinkPath_Name(OutFilePath,OutFileName);
//open the out file;
if( !(fpg = OpenF(OutFileName,"wb",errormsg)))
return 0;
GiveFormHead(fpg);
while(namep)
{
///get the full path and name of input file F_N_GetName(namep) store it to temp and made inneme point to it;
inname = strcpy(temp1,InFilePath);
inname = LinkPath_Name(inname,F_N_GetName(namep));
errormsg[0] = 0;
strcat(errormsg,"at function Compress Can't open file ");
strcat(errormsg,inname);
if( !(fps = OpenF(inname,"rb",errormsg)))
{
if(ASK("do you want to continue?"))
break;//do nothing;
else
{
fclose(fpg);
remove(OutFileName);
return 0;
}
}
if( !WriteStrToF(F_N_GetName(namep),fpg))
{
errormsg[0] = 0;
strcat(errormsg,"at function Compress Can't write the file name to ");
strcat(errormsg,OutFileName);
if(ASK(""))//do nothing;
{
break;
}
else
{
fclose(fpg);
remove(OutFileName);
}
}
CompressAFile(fps,fpg);
fclose(fps);
namep = F_N_GoNext(namep);
}
OutSize = ftell(fpg);
fclose(fpg);
return OutSize;
}
//////////////////////////////////////////////////////////////////////////
void PrintHelp()
{
printf("This is a free compress software \
\nuse help :\ncompress:\n compress outfilename folder1 folder2 ...\
\n outfilename is the out put file name which will write to the \
\n current work folder ! folder1 folder2 ...are folders while you \
\nwant to compress rember the folders must in the current work path!\
\nthank you for using it !");
}
///////////////////////////////////////////////////////////////////////////////
int main(int argc ,char **argv)
{
float rate;
unsigned int OutSize;
int i = 0;
f_name_t names = CreateFileName();
char *OutFileName,temp[MAX_PATH] = {0},CurPath[MAX_PATH] = {0};
if(argc < 3)
{
PrintHelp();
return 1;
}
getcwd(CurPath,MAX_PATH);
i = 2;
while(argv[i])
{
AddFileFromFolder(CurPath,argv[i],&names);
i++;
}
OutFileName = argv[1];
if(OutFileName)
{
OutFileName = strcat(temp,OutFileName);
OutFileName = strcat(OutFileName,".nw");
}
else
{
N_ERROR("must input a out file name!");
exit(0);
}
/* AddFileName(&names,"a.txt");
AddFileName(&names,"a.txt");
AddFileName(&names,"b.txt");
OutFileName = "t";
*/
//get the current work path
if(OutSize = Compress(CurPath,names,CurPath,OutFileName))
{
if(OutSize)rate = OutSize/IPUTFILESIZETOAL;
printf("Compressed successfully!\nInput Files total Size is %0.0f\nOutput file %s %d\ncompress rate is %f",IPUTFILESIZETOAL,OutFileName,OutSize,rate);
}
else
printf("Did not compress \n");
FreeFileList(&names);
// Compress("a.txt","b.nb");
}
////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -