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

📄 image.c

📁 傅立叶变换和小波变换是图像压缩的重要工具。该代大戏是利用小波变换进行图像压缩。
💻 C
字号:
#include "image.h"
#include <crblib/imutil.h>
#include <crblib/bmpio.h>
#include "mathutil.h"

void Image_MirrorExtend(Image *im,int fmw,int fmh)
{
ubyte * ptr;
int x,y;
int neww,newh;
int step;

	neww = im->width;
	newh = im->height;

	if ( neww == fmw && newh == fmh )
		return;

	step=3;

	// mirror to extend smaller images into this space

	ptr = im->BGRplane;
	for(y=0;y<fmh;y++)
	{
		for(x = 0;x < (neww - fmw);x++)
		{
		ubyte *toptr,*fmptr;
			toptr = ptr + step*(fmw + x);
			fmptr = ptr + step*(fmw - x - 2);
			toptr[0] = fmptr[0];
			toptr[1] = fmptr[1];
			toptr[2] = fmptr[2];
		}
		ptr += im->strideBytes;
	}
	for(y=0;y<(newh - fmh);y++)
	{
	ubyte *fmptr;
		fmptr = im->BGRplane + im->strideBytes * (fmh - y - 2);
		memcpy(ptr,fmptr,im->strideBytes);
		ptr += im->strideBytes;
	}
}

void Image_DoDelta(Image *im,Image *last)
{
int cnt;
ubyte *iptr,*lptr;
	cnt = im->width*im->height*3;
	iptr = im->BGRplane;
	lptr = last->BGRplane;
	while(cnt--)
	{
	int v;
		v = (*iptr - *lptr + 128);
		clamp255(v);
		*iptr++ = v;
		lptr++;
	}
}

void Image_ReadRawFP(Image * im,int width,int height,FILE * streamFP)
{
int len;
ubyte * ptr;
int x,y;

	// also mirror to extend smaller images into this space

	assert( im->width >= width );
	assert( im->height>= height);

	len = width*3;
	ptr = im->BGRplane;
	for(y=0;y<height;y++)
	{
		FRead(streamFP,ptr,len);
		for(x = 0;x < (im->width - width);x++)
		{
		ubyte *toptr,*fmptr;
			toptr = ptr + 3*(width + x);
			fmptr = ptr + 3*(width - x - 2);
			toptr[0] = fmptr[0];
			toptr[1] = fmptr[1];
			toptr[2] = fmptr[2];
		}
		ptr += im->strideBytes;
	}
	for(y=0;y<(im->height - height);y++)
	{
	ubyte *fmptr;
		fmptr = im->BGRplane + im->strideBytes * (height - y - 2);
		memcpy(ptr,fmptr,im->strideBytes);
		ptr += im->strideBytes;
	}

	Image_MirrorExtend(im,width,height);

}

void Image_WriteRawFP(Image * im,int width,int height,FILE * streamFP)
{
int len;
ubyte * ptr;
	len = width*3;
	ptr = im->BGRplane;
	while(height--)
	{
		FWrite(streamFP,ptr,len);
		ptr += im->strideBytes;
	}
}

Image *	Image_Create(int w,int h)
{
Image *im;

	im = new(Image);
	assert(im);

	im->width = w;
	im->height = h;
	im->strideBytes = (w*3 + 3)&(~3);

	im->BGRplane = malloc( im->height * im->strideBytes );
	assert( im->BGRplane );

return im;
}

void	Image_Free(Image *im)
{
	free(im->BGRplane);
	free(im);
}

Image *	Image_CreateFromFileName(char *fname)
{
myBMP * mybm;
Image * im;
int x,y;
ubyte *uptr,*iptr;

	mybm = loadImage(fname);
	if ( ! mybm ) return NULL;

	im = Image_Create(mybm->width,mybm->height);

	uptr = mybm->data;

	if ( mybm->type == MBTYPE_8BIT_GRAY || mybm->type == MBTYPE_8BIT_PAL )
	{
		for(y=0;y<im->height;y++)
		{
			iptr = im->BGRplane + y * im->strideBytes;
			for(x=0;x<im->width;x++)
			{
			ubyte b;
				b = *uptr++;
				*iptr++ = b;
				*iptr++ = b;
				*iptr++ = b;
			}
		}
	}
	else
	{
		memcpy(im->BGRplane,uptr,im->height * im->strideBytes );
	}

	freeBMP(mybm);

return im;
}

bool	Image_ReadFromFileName(Image *im,char *fname)
{
myBMP * mybm;
int x,y;
ubyte *uptr,*iptr;

	mybm = loadImage(fname);
	if ( ! mybm ) return false;

	uptr = mybm->data;

	assert( im->width >= mybm->width );
	assert( im->height >= mybm->height );

	if ( mybm->type == MBTYPE_8BIT_GRAY || mybm->type == MBTYPE_8BIT_PAL )
	{
		for(y=0;y<mybm->height;y++)
		{
			iptr = im->BGRplane + y * im->strideBytes;
			for(x=0;x<mybm->width;x++)
			{
			ubyte b;
				b = *uptr++;
				*iptr++ = b;
				*iptr++ = b;
				*iptr++ = b;
			}
		}
	}
	else
	{
		for(y=0;y<mybm->height;y++)
		{
			iptr = im->BGRplane + y * im->strideBytes;
			memcpy(iptr,uptr, mybm->width * 3 );
			uptr += mybm->width * 3;
		}
	}

	Image_MirrorExtend(im,mybm->width,mybm->height);

	freeBMP(mybm);

return true;
}

float	Image_DifferenceMSE(Image * im1,Image * im2)
{
int cnt;
float diff,mse,totsq;

	assert(im1->width  == im2->width);
	assert(im1->height == im2->height);

	totsq = 0.0f;

	{
	ubyte *p1,*p2;
	int y1,u1,v1,y2,u2,v2;
		p1 = im1->BGRplane;
		p2 = im2->BGRplane;
		for(cnt=im1->height*im1->width;cnt--;)
		{
//			RGB_to_LAB(p1[2],p1[1],p1[0],&y1,&u1,&v1); p1 += 3;
//			RGB_to_LAB(p2[2],p2[1],p2[0],&y2,&u2,&v2); p2 += 3;
			RGB_to_YUV(p1[2],p1[1],p1[0],&y1,&u1,&v1); p1 += 3;
			RGB_to_YUV(p2[2],p2[1],p2[0],&y2,&u2,&v2); p2 += 3;

			diff = (float)(y1 - y2);
			totsq += diff*diff;
			diff = (float)(u1 - u2)*0.5f;
			totsq += diff*diff;
			diff = (float)(v1 - v2)*0.5f;
			totsq += diff*diff;
		}
	}

	mse = (float)totsq/(im1->width*im1->height);

return mse;
}

/********** not real Image functions ****************/

void	Image_WriteFloatRaw(char *name,float *fplane,int w,int h)
{
FILE * fp;
int cnt;
	fp = fopen(name,"wb");
	assert(fp);

	for(cnt=w*h;cnt--;)
	{
	int i;
		i = ftoi((*fplane++) + 127.5f);
		clamp(i,0,255);
		fputc(i,fp);
	}

	fclose(fp);
}

void	Image_WriteUintRaw(char *name,uint *uplane,int w,int h)
{
FILE * fp;
int cnt;
	fp = fopen(name,"wb");
	assert(fp);

	for(cnt=w*h;cnt--;)
	{
	uint u;
		u = *uplane++;
		u <<= 4;
		clamp(u,0,255);
		fputc(u,fp);
	}

	fclose(fp);
}

void Image_DownSampFPlane(float *plane,int w,int h)
{
float *dptr,*uptr1,*uptr2;
int w2,h2,x;
	dptr = plane;
	uptr1 = plane;
	uptr2 = plane + w;
	w2 = w>>1;
	h2 = h>>1;
	while(h2--)
	{
		for(x=w2;x--;)
		{
		float val;
			val = (*uptr1++) + (*uptr1++) + (*uptr2++) + (*uptr2++);
			*dptr++ = val * 0.25f;
		}
		uptr1 += w;
		uptr2 += w;
	}
}

void Image_UpSampFPlane(  float *plane,int w,int h)
{
float *dptr,*uptr1,*uptr2;
int w2,h2,x,y;
void * temp;

	w2 = w>>1;
	h2 = h>>1;

	temp = malloc(w2*h2*4);
	memcpy(temp,plane,w2*h2*4);

	dptr = temp;
	uptr1 = plane;
	uptr2 = uptr1 + w;

	for(y=h2;y--;)
	{
		for(x=w2;x--;)
		{
		float v,vx,vy,vxy;
			v = dptr[0];
			if ( w2 > 0 && h2 > 0 )
			{
				vx = dptr[1]; vy = dptr[w2]; vxy = dptr[w2+1];
			}
			else if ( w2 > 0 )
			{
				vx = dptr[1]; vy = v; vxy = vx;
			}
			else if ( h2 > 0 )
			{
				vx = v; vy = dptr[w2]; vxy = vy;
			}
			else
			{
				vx = vy = vxy = v;
			}

			dptr++;

			*uptr1++ = v;
			*uptr1++ = (v + vx)*0.5f;
			*uptr2++ = (v + vy)*0.5f;
			*uptr2++ = (v + vxy)*0.5f;
		}
		uptr1 += w;
		uptr2 += w;
	}

	free(temp);
}


#pragma pack(1)
typedef struct 
{
	ulong      biSize;
	long       biWidth;
	long       biHeight;
	uword      biPlanes;
	uword      biBitCount;
	ulong      biCompression;
	ulong      biSizeImage;
	long       biXPelsPerMeter;
	long       biYPelsPerMeter;
	ulong      biClrUsed;
	ulong      biClrImportant;
} BITMAPINFOHEADER;

typedef struct 
{
	uword   bfType;
	ulong   bfSize;
	uword   bfReserved1;
	uword   bfReserved2;
	ulong   bfOffBits;
} BITMAPFILEHEADER;

typedef struct 
{
    ubyte    B;
    ubyte    G;
    ubyte    R;
    ubyte    rgbReserved;
} RGBQUAD;
#pragma pack()

#define BM_TAG	0x4D42		// 'BM'

bool	Image_WriteToBMP(Image * im,char * fname,int w,int h)
{
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
FILE * fp;
ulong bmp_row_bytes;
int y;

	if ( (fp = fopen(fname,"wb")) == NULL ) return false;

	bmih.biSize = sizeof(BITMAPINFOHEADER);

	bmih.biWidth = w;
	bmih.biHeight= h; //<> negative?

	bmih.biPlanes = 1;
	bmih.biCompression = 0;
	bmih.biXPelsPerMeter = bmih.biYPelsPerMeter = 10000;

	bmih.biClrImportant = bmih.biClrUsed = 0;		
	bmih.biBitCount = 24;
	bmp_row_bytes = (bmih.biWidth * 3 + 3)&(~3);

	bmih.biSizeImage = bmp_row_bytes * abs(bmih.biHeight);

	bmfh.bfType = BM_TAG;
	bmfh.bfSize = sizeof(BITMAPFILEHEADER) + bmih.biSize + bmih.biSizeImage ;

	bmfh.bfOffBits = bmfh.bfSize - bmih.biSizeImage ;

	if ( ! FWriteOk(fp, &bmfh , sizeof(BITMAPFILEHEADER) ) ) { fclose(fp); return false; }
	if ( ! FWriteOk(fp, &bmih , sizeof(BITMAPINFOHEADER) ) ) { fclose(fp); return false; }

	for(y=h-1;y>=0;y--)
	{
	ubyte * ptr;
		ptr = im->BGRplane + im->strideBytes * y;
		if ( ! FWriteOk(fp,ptr,bmp_row_bytes) ) { fclose(fp); return false; }
	}

	fclose(fp);

return true;
}

⌨️ 快捷键说明

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