⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dcbm.c

📁 傅立叶变换和小波变换是图像压缩的重要工具。该代大戏是利用小波变换进行图像压缩。
💻 C
字号:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> 

#include <crblib/inc.h>
#include <crblib/fileutil.h>

#include "dcbm.h"
#include "winutil.h"

#pragma warning(disable : 4244)

/*********************************************/

#define LBM_cleanUp(err) if(1) { char str[200]; strcpy(str,fName); strcat(str,":"); strcat(str,err); MessageBox( windowH, str , "loadBitMap error", MB_OK ); return( NULL); } else

#define GET_2B(array,offset) ((uword) (ubyte)(array[offset+0]) + \
						 	(((uword) (ubyte)(array[offset+1])) << 8))
#define GET_4B(array,offset) ((ulong) (ubyte)(array[offset+0]) + \
						 	(((ulong) (ubyte)(array[offset+1])) << 8) + \
						 	(((ulong) (ubyte)(array[offset+2])) << 16) + \
						 	(((ulong) (ubyte)(array[offset+3])) << 24))

HBITMAP LoadBitMap(HWND windowH, HDC hdc, char * fName )
{
FILE * inFile;
BITMAPINFO * bmi;
void * bmdata;
HBITMAP hbm;

if ( (inFile = fopen(fName,"rb")) == NULL ) {
	char errstr[80];
	sprintf(errstr,"fopen failed, error : %d\n\0",errno);
	perror("fopen bitmap:");
	LBM_cleanUp(errstr);
}

	{
	ubyte bmpfileheader[14];
	ubyte bmpinfoheader[64];
	ulong bfOffBits;
	ulong headerSize;
	ulong biWidth = 0;
	long biHeight = 0;
	uword biPlanes;
	ulong biCompression;
	ulong biClrUsed = 0;
	int mapentrysize = 0;		/* 0 indicates no colormap */
	long bPad;
	ulong row_width;
	uword bits_per_pixel;

	/* Read and verify the bitmap file header */

	if (! FReadOk(inFile, bmpfileheader, 14))
		LBM_cleanUp("read short");

	if (GET_2B(bmpfileheader,0) != 0x4D42) /* 'BM' */
		LBM_cleanUp("bmp sign");

	bfOffBits = (ulong) GET_4B(bmpfileheader,10);

	/* We ignore the remaining fileheader fields */

	/* The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows),
	 * or 64 bytes (OS/2 2.x).	Check the first 4 bytes to find out which.
	 */
	if (! FReadOk(inFile, bmpinfoheader, 4))
		LBM_cleanUp("read short");

	headerSize = (ulong) GET_4B(bmpinfoheader,0);

	if (headerSize < 12 || headerSize > 64)
		LBM_cleanUp("bad header size");

	if (! FReadOk(inFile, bmpinfoheader+4, headerSize-4))
		LBM_cleanUp("read short");

	switch ((int) headerSize) {

			/* OS/2 1.x support removed */

		case 40:
		case 64:
			/* Decode Windows 3.x header (Microsoft calls this a BITMAPINFOHEADER) */
			/* or OS/2 2.x header, which has additional fields that we ignore */
			biWidth	= GET_4B(bmpinfoheader,4);
			biHeight = GET_4B(bmpinfoheader,8);
			biPlanes = GET_2B(bmpinfoheader,12);
			bits_per_pixel = (int) GET_2B(bmpinfoheader,14);
			biCompression = GET_4B(bmpinfoheader,16);
			biClrUsed = GET_4B(bmpinfoheader,32);
			if ( biClrUsed == 0 ) biClrUsed = 256;
			/* biSizeImage, biClrImportant fields are ignored */

			switch (bits_per_pixel) {

				case 8:			/* colormapped image */
					mapentrysize = 4;		/* Windows uses RGBQUAD colormap */
					break;
				case 24:			/* RGB image */
					mapentrysize = 0;
					break;
				default:
					LBM_cleanUp("bad depth");
					break;
			}

			break;
		default:
			LBM_cleanUp("bad header len");
			break;
	}

	/* Compute distance to bitmap data --- will adjust for colormap below */
	bPad = bfOffBits - (headerSize + 14);

	if ( ( bmi = malloc( sizeof(BITMAPINFO) + (mapentrysize * biClrUsed) ) ) == NULL )
		LBM_cleanUp("malloc");

	memcpy((char *)bmi,bmpinfoheader,headerSize);

	/* Read the colormap, if any */
	if (mapentrysize > 0 && biClrUsed > 0) {

		if (! FReadOk(inFile, ((char *)bmi) + headerSize , (mapentrysize * biClrUsed)))
			LBM_cleanUp("read short");

		/* account for size of colormap */
		bPad -= biClrUsed * mapentrysize;
	}

	/* Skip any remaining pad bytes */
	if (bPad < 0)			/* incorrect bfOffBits value? */
		LBM_cleanUp("bad header length");
	else if ( bPad > 0 ) {
		fseek(inFile,bPad,SEEK_CUR);
	}

	/* Compute row width in file, including padding to 4-byte boundary */
	if (bits_per_pixel == 24)
		row_width = biWidth * 3;
	else
		row_width = biWidth;

	row_width = ((((row_width-1)>>2) + 1)<<2) ;

	if ( (bmdata = malloc(row_width * abs(biHeight))) == NULL )
		LBM_cleanUp("malloc failed");

	FRead(inFile,bmdata,row_width * abs(biHeight)); // may read short due to compression

	}

fclose(inFile);

hbm = CreateDIBitmap( hdc, &(bmi->bmiHeader) , CBM_INIT , bmdata, bmi , DIB_RGB_COLORS	);

if ( hbm == NULL )
	LBM_cleanUp("CreateDIBitmap failed!");

free(bmdata);
free(bmi);

return hbm;
}

DCBM * LoadDCBM( HWND hwnd, HDC hdc, char *file)
{
HBITMAP bmp;
DCBM * ret;

bmp = LoadBitMap(hwnd,hdc,file);
if ( ! bmp ) return NULL;
ret = MakeDCBM(hdc,bmp);
DeleteObject(bmp);

return ret;
}

DCBM * MakeDCBM( HDC hdc, HBITMAP bitmap )
{
DCBM 		*dcbm;
BITMAP      bitmapbuff;
HDC			memorydc;
POINT 		size;
bool		good = false;

	if ( (memorydc = CreateCompatibleDC( hdc )) == NULL ) {
		ShowLastError("Create memory DC");
		return 0;
	}

    SelectObject( memorydc, bitmap );
    SetMapMode( memorydc, GetMapMode( hdc ) );
    GetObject( bitmap, sizeof( BITMAP ), (LPSTR) &bitmapbuff );

    DPtoLP( memorydc, &size, 1 );

	if ( (dcbm = malloc(sizeof(DCBM))) ) {
		dcbm->size.x = bitmapbuff.bmWidth;
		dcbm->size.y = bitmapbuff.bmHeight;
		dcbm->rasterOp = SRCCOPY;
		if ( (dcbm->bitmapdc = CreateCompatibleDC( hdc )) ) {	
			SelectObject(dcbm->bitmapdc,
				CreateBitmap(dcbm->size.x,dcbm->size.y,bitmapbuff.bmPlanes,bitmapbuff.bmBitsPixel,NULL) );
			SetMapMode( dcbm->bitmapdc, GetMapMode( hdc ) );

			if ( BitBlt( dcbm->bitmapdc, 0, 0, dcbm->size.x, dcbm->size.y, memorydc, 0, 0, dcbm->rasterOp) ) {
				good = true;
			} else {
				ShowLastError("Bit Blt");
			}
		} else {
			ShowLastError("Create Compatible DC");
		}
	}

    DeleteDC( memorydc );

	if ( ! good ) {
		FreeDCBM(dcbm);
		return NULL;
	}

return(dcbm);
}

DCBM * MakeDCBMHalf( HDC hdc, HBITMAP bitmap )
{
DCBM 		*dcbm;
BITMAP      bitmapbuff;
HDC			memorydc;
POINT 		size;

	if ( (memorydc = CreateCompatibleDC( hdc )) == NULL ) {
		ShowLastError("Create memory DC");
		return 0;
	}

    SelectObject( memorydc, bitmap );
    SetMapMode( memorydc, GetMapMode( hdc ) );
    GetObject( bitmap, sizeof( BITMAP ), (LPSTR) &bitmapbuff );

  	size.x = bitmapbuff.bmWidth;
    size.y = bitmapbuff.bmHeight;

    DPtoLP( memorydc, &size, 1 );

	dcbm = new(DCBM);
	dcbm->size.x = size.x/2;
	dcbm->size.y = size.y/2;
	dcbm->bitmapdc = CreateCompatibleDC( hdc );
	SelectObject(dcbm->bitmapdc,
		CreateBitmap(dcbm->size.x,dcbm->size.y,bitmapbuff.bmPlanes,bitmapbuff.bmBitsPixel,NULL) );
    SetMapMode( dcbm->bitmapdc, GetMapMode( hdc ) );

	SetStretchBltMode(memorydc,HALFTONE);
	SetBrushOrgEx(memorydc,0,0,NULL);

	if ( ! StretchBlt( dcbm->bitmapdc, 0, 0, dcbm->size.x, dcbm->size.y, memorydc, 0, 0, size.x, size.y, dcbm->rasterOp) ) {
		FreeDCBM(dcbm);
		dcbm = NULL;
	}
	
    DeleteDC( memorydc );

	dcbm->rasterOp = SRCCOPY;

return(dcbm);
}

DCBM * MakeDCBMscaled( HDC hdc, HBITMAP bitmap, float x_scale, float y_scale)
{
DCBM 		*dcbm;
BITMAP      bitmapbuff;
HDC			memorydc;
POINT 		size;
int x,y,sizex,sizey;

	if ( (memorydc = CreateCompatibleDC( hdc )) == NULL ) {
		ShowLastError("Create memory DC");
		return 0;
	}

    SelectObject( memorydc, bitmap );
    SetMapMode( memorydc, GetMapMode( hdc ) );
    GetObject( bitmap, sizeof( BITMAP ), (LPSTR) &bitmapbuff );

  	size.x = bitmapbuff.bmWidth;
    size.y = bitmapbuff.bmHeight;

    DPtoLP( memorydc, &size, 1 );

	dcbm = malloc(sizeof(DCBM));
	dcbm->size.x = abs(x_scale) * size.x;
	dcbm->size.y = abs(y_scale) * size.y;
	dcbm->bitmapdc = CreateCompatibleDC( hdc );
	SelectObject(dcbm->bitmapdc,
		CreateBitmap(dcbm->size.x,dcbm->size.y,bitmapbuff.bmPlanes,bitmapbuff.bmBitsPixel,NULL) );
    SetMapMode( dcbm->bitmapdc, GetMapMode( hdc ) );

	SetStretchBltMode(memorydc,HALFTONE);
	SetBrushOrgEx(memorydc,0,0,NULL);

	x = y = 0;
	sizex = x_scale * size.x;
	sizey = y_scale * size.y;
	if ( sizex < 0 ) x += abs(sizex) -1;
	if ( sizey < 0 ) y += abs(sizey) -1;

	if ( ! StretchBlt( dcbm->bitmapdc, x, y, sizex, sizey, memorydc, 0, 0, size.x, size.y, dcbm->rasterOp) ) {
		FreeDCBM(dcbm);
		dcbm = NULL;
	}
	
    DeleteDC( memorydc );

	dcbm->rasterOp = SRCCOPY;

return(dcbm);
}

DCBM  * CopyDCBM_stretching(DCBM *src,float x_scale,float y_scale)
{
DCBM 		*dcbm;
int			sizex,sizey,x,y;

	if ( (dcbm = malloc(sizeof(DCBM))) == NULL )
		return NULL;

	sizex = (((float)src->size.x) * x_scale);
	sizey = (((float)src->size.y) * y_scale);
	dcbm->size.x = abs(sizex);
	dcbm->size.y = abs(sizey);
	dcbm->bitmapdc = CreateCompatibleDC( src->bitmapdc );
	SelectObject(dcbm->bitmapdc,
		CreateCompatibleBitmap(src->bitmapdc,dcbm->size.x,dcbm->size.y));
    SetMapMode( dcbm->bitmapdc, GetMapMode( src->bitmapdc ) );

	SetStretchBltMode(src->bitmapdc,HALFTONE);
	SetBrushOrgEx(src->bitmapdc,0,0,NULL);

	x = y = 0;
	if ( sizex < 0 ) x += abs(sizex) -1;
	if ( sizey < 0 ) y += abs(sizey) -1;

	if ( ! StretchBlt( dcbm->bitmapdc, x, y, sizex, sizey,
						src->bitmapdc, 0, 0, src->size.x, src->size.y,
						dcbm->rasterOp) ) {
		FreeDCBM(dcbm);
		dcbm = NULL;
	}

return dcbm;
}

DCBMA * CopyDCBMA_stretching(DCBMA *src,float x_scale,float y_scale)
{
DCBMA * a;
int i;

	if ( (a = malloc(sizeof(DCBMA))) == NULL ) return NULL;

	a->numFrames = src->numFrames;

	if ( (a->frames = malloc(a->numFrames*sizeofpointer) ) == NULL ) { free(a); return NULL; }

	a->size.x = a->size.y = 0;

	for(i=0;i<a->numFrames;i++) {
		a->frames[i] = CopyDCBM_stretching(src->frames[i],x_scale,y_scale);

		if ( a->frames[i] == NULL ) {
			FreeDCBMA(a);
			return NULL;
		} else {

		if ( a->frames[i]->size.x > a->size.x )
			a->size.x = a->frames[i]->size.x;
		if ( a->frames[i]->size.y > a->size.y )
			a->size.y = a->frames[i]->size.y;

		}
	}

return a;
}

void FreeDCBM( DCBM * dcbm )
{
DeleteDC( dcbm->bitmapdc );
free(dcbm);
}

void DrawDCBMcenter(  HDC hdc, DCBM *dcbm, long x, long y )
{
x -= dcbm->size.x>>1;
y -= dcbm->size.y>>1;
DrawDCBM(hdc,dcbm,x,y);
}


void DrawDCBMinRectnoGrow( HDC hdc, DCBM *dcbm, RECT *r )
{
if ( dcbm->size.x < width(*r) && dcbm->size.y < height(*r) ) {
	DrawDCBMcenter(hdc,dcbm,midx(*r),midy(*r));
} else {
	DrawDCBMScaling(hdc,dcbm,r->left,r->top,width(*r),height(*r));
}
}

void DrawDCBMinRect( HDC hdc, DCBM *dcbm, RECT *r )
{
DrawDCBMScaling(hdc,dcbm,r->left,r->top,width(*r),height(*r));
}

void DrawDCBMScaling( HDC hdc, DCBM *dcbm, long x, long y, long sizex, long sizey )
{
if ( ! dcbm ) return;

	SetStretchBltMode(dcbm->bitmapdc,HALFTONE);
	SetBrushOrgEx(dcbm->bitmapdc,0,0,NULL);

	if ( sizex < 0 ) x += abs(sizex) -1;
	if ( sizey < 0 ) y += abs(sizey) -1;
	StretchBlt( hdc, x, y, sizex, sizey,
						dcbm->bitmapdc, 0, 0, dcbm->size.x, dcbm->size.y,
						dcbm->rasterOp);
}

void DrawDCBM( HDC hdc, DCBM *dcbm, long x, long y )
{
if ( ! dcbm ) return;
BitBlt( hdc, x, y, dcbm->size.x, dcbm->size.y, dcbm->bitmapdc, 0, 0, dcbm->rasterOp);
}

DCBMA * LoadDCBMA(HWND windowH,int frames,char ** files)
{
DCBMA * a;
HBITMAP bmp;
HDC hdc;
int i;

	if ( (a = malloc(sizeof(DCBMA))) == NULL ) return NULL;

	a->numFrames = frames;

	if ( (a->frames = malloc(frames*sizeofpointer)) == NULL ) { free(a); return NULL; }

	hdc = GetDC(windowH);

	for(i=0;i<frames;i++) {

		bmp = LoadBitMap(windowH,hdc,files[i]);

		a->frames[i] = MakeDCBM(hdc,bmp);

		DeleteObject(bmp);
	}

	ReleaseDC(windowH,hdc);

	a->size.x = a->size.y = 0;

	for(i=0;i<frames;i++) {
		
		if ( a->frames[i] == NULL ) {
			FreeDCBMA(a);
			return NULL;
		} else {

		if ( a->frames[i]->size.x > a->size.x )
			a->size.x = a->frames[i]->size.x;
		if ( a->frames[i]->size.y > a->size.y )
			a->size.y = a->frames[i]->size.y;

		}

	}

return a;
}

void DrawDCBMA( HWND w, DCBMA *DCBMA, long x, long y )
{
int i;
HDC hdc;

	for (i=0;i<DCBMA->numFrames;i++) {
		hdc = GetDC(w);
		DrawDCBM(hdc,DCBMA->frames[i],x,y);
		ReleaseDC(w,hdc);

		await(50); /* wait a 20th of a second. very half-assed */
	}
}

void DrawDCBMAScaling( HWND w, DCBMA *DCBMA, long x, long y, long sizex, long sizey )
{
int i;
HDC hdc;

	for (i=0;i<DCBMA->numFrames;i++) {
		hdc = GetDC(w);
		DrawDCBMScaling(hdc,DCBMA->frames[i],x,y,sizex,sizey);
		ReleaseDC(w,hdc);

		await(50); /* wait a 20th of a second. very half-assed */
	}
}

void DrawDCBMAcenter( HWND w, DCBMA *DCBMA, long x, long y )
{
x -= DCBMA->size.x>>1;
y -= DCBMA->size.y>>1;
DrawDCBMA(w,DCBMA,x,y);
}

void DrawDCBMAcenterScaling( HWND w, DCBMA *DCBMA, long x, long y, long sizex, long sizey )
{
x -= sizex>>1;
y -= sizey>>1;
DrawDCBMAScaling(w,DCBMA,x,y,sizex,sizey);
}

void FreeDCBMA( DCBMA * dcbma )
{
int i;

	if ( !dcbma ) return;

	for (i=0;i<dcbma->numFrames;i++) {
		if ( dcbma->frames[i] ) FreeDCBM(dcbma->frames[i]);
	}
	free(dcbma->frames);
	free(dcbma);

}


void DrawBitMap( HDC hdc, HBITMAP bitmap, long x, long y )
{
    BITMAP      bitmapbuff;
    HDC         memorydc;
    POINT       origin;
    POINT       size;

	if ( ! bitmap ) return;

    memorydc = CreateCompatibleDC( hdc );
    SelectObject( memorydc, bitmap );
    SetMapMode( memorydc, GetMapMode( hdc ) );
    GetObject( bitmap, sizeof( BITMAP ), (LPSTR) &bitmapbuff );

    origin.x = x;
    origin.y = y;
    size.x = bitmapbuff.bmWidth;
    size.y = bitmapbuff.bmHeight;

    DPtoLP( hdc, &origin, 1 );
    DPtoLP( memorydc, &size, 1 );

    BitBlt( hdc, origin.x, origin.y, size.x, size.y, memorydc, 0, 0, SRCCOPY);
    DeleteDC( memorydc );

} /* DrawBitmap */
 

⌨️ 快捷键说明

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