📄 image.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 + -