main.c

来自「傅立叶变换和小波变换是图像压缩的重要工具。该代大戏是利用小波变换进行图像压缩。」· C语言 代码 · 共 830 行 · 第 1/2 页

C
830
字号
		DrawDriver_Lock(true);
		DrawDriver_UnLock();
	}

	if ( encoding )
	{
		compFP = fopen(toName,"wb");
		if ( !compFP )
			errexit("compFP fopen failed!");

		FWrite(compFP,&width,sizeof(int));
		FWrite(compFP,&height,sizeof(int));
		FWrite(compFP,&frames,sizeof(int));
		FWrite(compFP,&fps,sizeof(int));

		if ( streamFP )
			fseek(streamFP,offset,SEEK_SET);

		for(f=0;f<frames;f++)
		{
		float rmse;

			if ( bmpsIn )
			{
			char name[1024];
			bool ex;
				ex = ExistsBmp(bmpNameBase,f+bmpBaseN,name);
				assert(ex);
				Image_ReadFromFileName(im,name);
			}
			else
			{
				Image_ReadRawFP(im,width,height,streamFP);	
			}

			rmse = CodeImager_Encode(encoder,im,compBuf,&frameCompLen,targetLen,decoder,&viewIm);

			if ( !compBuf )
				errexit("encoding failed!");

			assert( frameCompLen < compBufLen );

			printf("encoded frame to %d = %1.2f bpp\n",frameCompLen,(float)frameCompLen*8.0f/(width*height));

			if ( seekByRMSE )
			{
				if ( rmse < targetRMSE )
				{
					// error less than target; could pack smaller
					targetLen = frameCompLen - ((frameCompLen+15)>>4);
				}
				else
				{
					targetLen = frameCompLen + ((frameCompLen+15)>>4) + 1;
				}
			}

			FWrite(compFP,&frameCompLen,sizeof(int));
			
			FWrite(compFP,compBuf,frameCompLen);

			totCompLen += frameCompLen + sizeof(int);
			
			// decode it to the viewer
			// (need the decoded plane for delta-ing anyway)

			DDC.y = 0;
			DDC.Width = width;
			DDC.Window = DrawDriver_Lock(false);

			DrawDriver_GiveLinesCB(&DDC,viewIm.BGRplane,viewIm.height);
			
			DrawDriver_UnLock();

			DoMessages(viewer);
		}

		fclose(compFP);
		compFP = NULL;
		
		if ( streamFP )
			fclose(streamFP);
		streamFP = NULL;

		dprintf("-----------------------------------------------------------\n");
		dprintf("%-20s : %6d k -> %6d k = %1.2f bpp\n",
												FilePart(fromName),
												streamLen>>10,totCompLen>>10,
												(totCompLen*8.0f/(float)(streamLen/3)));

		compFP = fopen(toName,"rb");
		if ( !compFP )
			errexit("compFP fopen failed!");
			
		FRead(compFP,&width,sizeof(int));
		FRead(compFP,&height,sizeof(int));
		FRead(compFP,&frames,sizeof(int));
		FRead(compFP,&fps,sizeof(int));
		
		CodeImager_Destroy(decoder);
		decoder = CodeImager_Create(im->width,im->height);
	}

	//---------------------------------------
	// decode

	printf("unpacking %d frames (%d x %d) @ %d fps\n",frames,width,height,fps);

	if ( ! nodisplay )
	{
		DrawDriver_Lock(true);
		DrawDriver_UnLock();
	}

	spf = 1.0 / fps;
	while ( IsKeyDown(' ') || IsKeyDown(VK_RETURN) || IsKeyDown(VK_ESCAPE) );

	if ( dumpRawName )
	{
		if ( dumpBmps )
			dumpRawFP = NULL;
		else
			if ( ! (dumpRawFP = fopen(dumpRawName,"wb")) )
				dprintf("warning : open dumpRaw file failed; ignoring...\n");
	}

	decTime = 0.0f;
	totTime = timeTSC();
	pushTSC();

	for(f=0;f<frames;f++)
	{
	double nextFrameTime,startTime;

		nextFrameTime = timeTSC() + spf;

		FRead(compFP,&frameCompLen,sizeof(int));
		
		assert( frameCompLen < compBufLen );

		FRead(compFP,compBuf,frameCompLen);

		if ( nodisplay )
		{
			if ( dumpRawName )
			{
				startTime = timeTSC();
				CodeImager_Decode(decoder,&viewIm,compBuf,frameCompLen,NULL);
				decTime += timeTSC() - startTime;

				if ( dumpBmps )
				{
				char name[1024];
					sprintf(name,"%s%d.bmp",dumpRawName,f);
					Image_WriteToBMP(&viewIm,name,width,height);
				}
				else
				{
					Image_WriteRawFP(&viewIm,width,height,dumpRawFP);
				}
			}
			else
			{
			Driver_Window FakeWindow;

				FakeWindow.Buffer = viewIm.BGRplane;
				FakeWindow.Width = viewIm.width;
				FakeWindow.Height = viewIm.height;
				FakeWindow.Stride = FakeWindow.Width*2;
				FakeWindow.Mode = DRIVER_MODE_555;
				FakeWindow.UserY = 0;

				startTime = timeTSC();
				CodeImager_Decode(decoder,&viewIm,compBuf,frameCompLen,&FakeWindow);
				decTime += timeTSC() - startTime;
			}
		}
		else
		{
		Driver_Window MyWindow;

			MyWindow = * DrawDriver_Lock(false);
			MyWindow.Width  = min(MyWindow.Width,(uint)width);
			MyWindow.Height = min(MyWindow.Height,(uint)height);

			if ( dumpRawName )
			{
				startTime = timeTSC();
				CodeImager_Decode(decoder,&viewIm,compBuf,frameCompLen,NULL);
				decTime += timeTSC() - startTime;

				DDC.y = 0;
				DDC.Width = width;
				DDC.Window = &MyWindow;
				DrawDriver_GiveLinesCB(&DDC,viewIm.BGRplane,height);
				
				if ( dumpBmps )
				{
				char name[1024];
					sprintf(name,"%s%d.bmp",dumpRawName,f);
					Image_WriteToBMP(&viewIm,name,width,height);
				}
				else
				{
					Image_WriteRawFP(&viewIm,width,height,dumpRawFP);
				}
			}
			else
			{
				startTime = timeTSC();
				CodeImager_Decode(decoder,&viewIm,compBuf,frameCompLen,&MyWindow);
				decTime += timeTSC() - startTime;
			}

			DrawDriver_UnLock();
			
			do
			{	
				if ( IsKeyDown(VK_ESCAPE) )
				{
					goto escaped;
				}
				if ( IsKeyDown(' ') || IsKeyDown(VK_RETURN) )
				{
					paused ^= 1;
				}
				while ( IsKeyDown(' ') || IsKeyDown(VK_RETURN) ||  IsKeyDown(VK_ESCAPE) );

				DoMessages(viewer);

				while( timeTSC() < nextFrameTime )
				{
					// YIELD !
					Sleep(1);
				}
			} while( paused );
		}
	}
	escaped:

	totTime = timeTSC() - totTime;
	showPopTSCper(stdout,"decode",width*height*f,"pel");

	fclose(compFP);
	if ( dumpRawFP )
		fclose(dumpRawFP);
	
	//---------------------------------------

	CodeImager_Destroy(encoder);
	CodeImager_Destroy(decoder);

	Image_Free(im);

	free(compBuf);

	if ( ! nodisplay )
	{
		DrawDriver_Shutdown();
		DestroyWindow(viewer);
	}

	dprintf("actual display fps = %2.2f (time = %2.2f secs)\n",f/totTime,totTime);
	dprintf("   decode only fps = %2.2f (time = %2.2f secs)\n",f/decTime,decTime);
	if ( f == frames )
		dprintf("bandwidth used = %d kbyps = %d kbaud\n",(int)(totCompLen/totTime)>>10,(int)(totCompLen*8/totTime)>>10);

	dprintf("done.\n");

	#ifdef _DEBUG
	errputs("press enter");
	fgetc(stdin);
	#endif

return 0;
}


BOOL ParseCommandLine( char *CmdLine, char ***Argv, int *Argc )
{
int Cnt;
char *Str, *End, *NewStr;

	*Argv = NULL;
	*Argc = 1;

	// First, count the number of strings in the command-line

	for( Str = CmdLine; *Str; Str++ )
	{
		if( !isspace( Str[ 0 ] ) && (isspace( Str[ 1 ] ) || Str[ 1 ] == 0) )
		{
			(*Argc)++;
		}
	}

	// Now allocate space for the Argv array

	*Argv = (char **)calloc( *Argc, sizeof( char * ) );

	if( *Argv == NULL )    return( FALSE );

	Cnt = 0;

	(*Argv)[ Cnt ] = "Program Name";
	Cnt ++;

	// Now fetch each string from the command-line

	Str = CmdLine;

	while( *Str )
	{
		while( isspace( *Str ) && *Str )
		{
			Str++;
		}

		if( *Str )
		{
			for( End = Str + 1; !isspace( *End ) && *End; End++ )
				;

			NewStr = (char *)malloc( End - Str + 1 );

			if( NewStr == NULL )
			{
				while( --Cnt >= 0 )
				{
					free( (*Argv)[ Cnt ] );
				}

				return( FALSE );
			}

			(*Argv)[ Cnt ] = NewStr;

			while( Str < End )
			{
				*NewStr++ = *Str++;
			}

			*NewStr = '\0';

			Cnt++;
		}
	}

return( TRUE );
}

static void DoMessages(HWND hwnd)
{
MSG msg;
	while( PeekMessage( &msg, hwnd, 0, 0 , PM_NOREMOVE) )
	{
		GetMessage( &msg, hwnd, 0, 0);
		TranslateMessage( &msg );
		DispatchMessage( &msg );
	}

}

static bool IsKeyDown(int KeyCode)
{
	return (GetAsyncKeyState(KeyCode) & 0x8001) ? true : false;
}

bool ExistsBmp(const char * bmpNameBase,int i,char * foundName)
{
char str[1024],tail[256];
int dig;
	sprintf(tail,"%d.bmp",i);
	for(dig=0;dig<4;dig++)
	{
	int z;
	FILE * fp;
		strcpy(str,bmpNameBase);
		for(z=0;z<dig;z++)
		{
			strcat(str,"0");
		}
		strcat(str,tail);
		fp = fopen(str,"rb");
		if ( fp )
		{
			if ( foundName )
				strcpy(foundName,str);
			fclose(fp);
			return true;
		}
	}
return false;
}

int CountBmps(const char * bmpNameBase,int * pbaseN)
{
int count;
int baseN;
	baseN = 0;
	while ( ! ExistsBmp(bmpNameBase,baseN,NULL) )
	{
		baseN++;
		if ( baseN >= 100 ) return 0;
	}
	count = 0;
	while( ExistsBmp(bmpNameBase,count+baseN,NULL) )
	{
		count++;
	}
	if ( pbaseN )
		*pbaseN = baseN;
return count;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?