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

📄 fimage.cxx

📁 PIXIL is a small footprint operating environment, complete with PDA PIM applications, a browser and
💻 CXX
字号:
#include <Flek/math.H>#include <Flek/FImage.H>#include <string.h>//#include <iostream.h>//#include <fstream.h>typedef unsigned long ulong;typedef unsigned long *ulongPtr;typedef unsigned short ushort;typedef unsigned short *ushortPtr;typedef unsigned char uchar;typedef unsigned char *ucharPtr;#define INT_MULT(a,b,t)  ((t) = (a) * (b) + 0x80, ((((t) >> 8) + (t)) >> 8))#define INT_BLEND(a,b,alpha,tmp)  (INT_MULT((a)-(b), alpha, tmp) + (b))FImage::FImage(){    Data = 0;    W = 0;    H = 0;    Channels = 4;}FImage::FImage(int w, int h, int channels){    W = w;    H = h;    Channels = channels;    Data = new uchar[W * H * Channels];}FImage::FImage(FImage * src){    W = src->width();    H = src->height();    Channels = src->channels();    Data = new uchar[W * H * Channels];    memcpy((void *) Data, (void *) *(src->begin()), W * H * Channels);}FImage::~FImage(){    if (Data)	delete[]Data;}voidFImage::channels(int dest_channels){    uchar *src = Data;    int src_channels = Channels;    int k_max = min(src_channels, dest_channels);    uchar *r = new uchar[W * H * dest_channels];    uchar *dest = r;    unsigned char *end = dest + dest_channels * W * H;    for (; dest < end; dest += dest_channels, src += src_channels) {	for (int k = 0; k < k_max; k++)	    dest[k] = src[k];    }    if ((Channels == 3) && (dest_channels == 4)) {	dest = r;	for (; dest < end; dest += dest_channels)	    dest[3] = 255;    }    delete[]Data;    Data = r;    Channels = dest_channels;}voidFImage::flip_vertical(){    uchar row[Channels * W];    for (int i = 0; i < H / 2; i++) {	memcpy(row, &Data[Channels * W * i], Channels * W);	memcpy(&Data[Channels * W * i], &Data[Channels * W * (H - i - 1)],	       Channels * W);	memcpy(&Data[Channels * W * (H - i - 1)], row, Channels * W);    }}voidFImage::clear(uchar r, uchar g, uchar b, uchar a){    int i;    if (Channels >= 4)	for (i = 0; i < Channels * W * H; i += Channels) {	    Data[i] = r;	    Data[i + 1] = g;	    Data[i + 2] = b;	    Data[i + 3] = a;    } else if (Channels == 3) {	for (i = 0; i < Channels * W * H; i += Channels) {	    Data[i] = r;	    Data[i + 1] = g;	    Data[i + 2] = b;	}    } else if (Channels == 2) {	for (i = 0; i < Channels * W * H; i += Channels) {	    Data[i] = r;	    Data[i + 1] = g;	}    } else if (Channels == 1) {	for (i = 0; i < Channels * W * H; i += Channels)	    Data[i] = r;    }}FImage *FImage::scale(int x, int y){    FImage *r = new FImage(x, y, Channels);    uchar *dest = *(r->begin());    for (int i = 0; i < y; i++)	for (int j = 0; j < x; j++)	    for (int k = 0; k < Channels; k++, dest++) {		float tx = ((float) j / (float) x);		float ty = ((float) i / (float) y);		int ix = (int) (tx * W);		int iy = (int) (ty * H);		dest[0] = Data[iy * Channels * W + ix * Channels + k];	    }    return r;}/* * All operations are done "in-place" on image A and do not return a  * new image for efficiency.  If you want a new image, copy image A * and then work on the copy. */voidcomposite(unsigned char *dest,	  const unsigned char *src,	  int opacity, int length, int dest_channels, int src_channels){    int a;    register long t1;    unsigned char *end = dest + dest_channels * length;    for (; dest < end; dest += dest_channels, src += src_channels) {	if (src_channels > 3) {	    a = INT_MULT(src[3], opacity, t1);	    // b + (1-b)*a	    if (dest_channels > 3)		dest[3] = min(src[3] + INT_MULT(255 - src[3], dest[3], t1), 255);	//INT_MULT(dest[3], a, t1); //dest[3] = 255;	} else	    a = opacity;	dest[0] = INT_BLEND(src[0], dest[0], a, t1);	dest[1] = INT_BLEND(src[1], dest[1], a, t1);	dest[2] = INT_BLEND(src[2], dest[2], a, t1);    }}FImage *composite(FImage * A, FImage * B, int xo, int yo, float value){    int xi = max(xo, 0);    int yi = max(yo, 0);    int xf = min(max(xo + B->width(), 0), A->width());    int yf = min(max(yo + B->height(), 0), A->height());    for (int row = yi; row < yf; row++)	composite(*(*A) (xi, row), *(*B) (xi - xo, row - yo),		  (int) (value * 255), xf - xi, A->channels(), B->channels());    return A;}voidadd(unsigned char *dest,    const unsigned char *src,    int opacity, int length, int dest_channels, int src_channels){    int a;    register long t1;    unsigned char *end = dest + dest_channels * length;    for (; dest < end; dest += dest_channels, src += src_channels) {	if (src_channels > 3) {	    a = INT_MULT(src[3], opacity, t1);	    if (dest_channels > 3)		dest[3] = 255;	} else	    a = opacity;	dest[0] =	    INT_BLEND(clamp_upper(src[0] + dest[0], 255), dest[0], a, t1);	dest[1] =	    INT_BLEND(clamp_upper(src[1] + dest[1], 255), dest[1], a, t1);	dest[2] =	    INT_BLEND(clamp_upper(src[2] + dest[2], 255), dest[2], a, t1);    }}FImage *add(FImage * A, FImage * B, int xo, int yo, float value){    int xi = max(xo, 0);    int yi = max(yo, 0);    int xf = min(max(xo + B->width(), 0), A->width());    int yf = min(max(yo + B->height(), 0), A->height());    for (int row = yi; row < yf; row++)	add(*(*A) (xi, row), *(*B) (xi - xo, row - yo), (int) (value * 255),	    xf - xi, A->channels(), B->channels());    return A;}voidsubtract(unsigned char *dest,	 const unsigned char *src,	 int opacity, int length, int dest_channels, int src_channels){    int a;    register long t1;    unsigned char *end = dest + dest_channels * length;    for (; dest < end; dest += dest_channels, src += src_channels) {	if (src_channels > 3) {	    a = INT_MULT(src[3], opacity, t1);	    if (dest_channels > 3)		dest[3] = 255;	} else	    a = opacity;	dest[0] = INT_BLEND(clamp_lower(dest[0] - src[0], 0), dest[0], a, t1);	dest[1] = INT_BLEND(clamp_lower(dest[1] - src[1], 0), dest[1], a, t1);	dest[2] = INT_BLEND(clamp_lower(dest[2] - src[2], 0), dest[2], a, t1);    }}FImage *subtract(FImage * A, FImage * B, int xo, int yo, float value){    int xi = max(xo, 0);    int yi = max(yo, 0);    int xf = min(max(xo + B->width(), 0), A->width());    int yf = min(max(yo + B->height(), 0), A->height());    for (int row = yi; row < yf; row++)	subtract(*(*A) (xi, row), *(*B) (xi - xo, row - yo),		 (int) (value * 255), xf - xi, A->channels(), B->channels());    return A;}voiddifference(unsigned char *dest,	   const unsigned char *src,	   int opacity, int length, int dest_channels, int src_channels){    int a;    register long t1;    unsigned char *end = dest + dest_channels * length;    for (; dest < end; dest += dest_channels, src += src_channels) {	if (src_channels > 3) {	    a = INT_MULT(src[3], opacity, t1);	    if (dest_channels > 3)		dest[3] = 255;	} else	    a = opacity;	dest[0] =	    INT_BLEND(max(dest[0], src[0]) - min(dest[0], src[0]), dest[0], a,		      t1);	dest[1] =	    INT_BLEND(max(dest[1], src[1]) - min(dest[1], src[1]), dest[1], a,		      t1);	dest[2] =	    INT_BLEND(max(dest[2], src[2]) - min(dest[2], src[2]), dest[2], a,		      t1);    }}FImage *difference(FImage * A, FImage * B, int xo, int yo, float value){    int xi = max(xo, 0);    int yi = max(yo, 0);    int xf = min(max(xo + B->width(), 0), A->width());    int yf = min(max(yo + B->height(), 0), A->height());    for (int row = yi; row < yf; row++)	difference(*(*A) (xi, row), *(*B) (xi - xo, row - yo),		   (int) (value * 255), xf - xi, A->channels(),		   B->channels());    return A;}voidlighten_only(unsigned char *dest,	     const unsigned char *src,	     int opacity, int length, int dest_channels, int src_channels){    int a;    register long t1;    unsigned char *end = dest + dest_channels * length;    for (; dest < end; dest += dest_channels, src += src_channels) {	if (src_channels > 3) {	    a = INT_MULT(src[3], opacity, t1);	    if (dest_channels > 3)		dest[3] = 255;	} else	    a = opacity;	dest[0] = INT_BLEND(max(dest[0], src[0]), dest[0], a, t1);	dest[1] = INT_BLEND(max(dest[1], src[1]), dest[1], a, t1);	dest[2] = INT_BLEND(max(dest[2], src[2]), dest[2], a, t1);    }}FImage *lighten_only(FImage * A, FImage * B, int xo, int yo, float value){    int xi = max(xo, 0);    int yi = max(yo, 0);    int xf = min(max(xo + B->width(), 0), A->width());    int yf = min(max(yo + B->height(), 0), A->height());    for (int row = yi; row < yf; row++)	lighten_only(*(*A) (xi, row), *(*B) (xi - xo, row - yo),		     (int) (value * 255), xf - xi, A->channels(),		     B->channels());    return A;}voiddarken_only(unsigned char *dest,	    const unsigned char *src,	    int opacity, int length, int dest_channels, int src_channels){    int a;    register long t1;    unsigned char *end = dest + dest_channels * length;    for (; dest < end; dest += dest_channels, src += src_channels) {	if (src_channels > 3) {	    a = INT_MULT(src[3], opacity, t1);	    if (dest_channels > 3)		dest[3] = 255;	} else	    a = opacity;	dest[0] = INT_BLEND(min(dest[0], src[0]), dest[0], a, t1);	dest[1] = INT_BLEND(min(dest[1], src[1]), dest[1], a, t1);	dest[2] = INT_BLEND(min(dest[2], src[2]), dest[2], a, t1);    }}FImage *darken_only(FImage * A, FImage * B, int xo, int yo, float value){    int xi = max(xo, 0);    int yi = max(yo, 0);    int xf = min(max(xo + B->width(), 0), A->width());    int yf = min(max(yo + B->height(), 0), A->height());    for (int row = yi; row < yf; row++)	darken_only(*(*A) (xi, row), *(*B) (xi - xo, row - yo),		    (int) (value * 255), xf - xi, A->channels(),		    B->channels());    return A;}voiddivide(unsigned char *dest,       const unsigned char *src,       int opacity, int length, int dest_channels, int src_channels){    int a;    register long t1;    unsigned char *end = dest + dest_channels * length;    for (; dest < end; dest += dest_channels, src += src_channels) {	if (src_channels > 3) {	    a = INT_MULT(src[3], opacity, t1);	    if (dest_channels > 3)		dest[3] = min(dest[3], src[3]);	} else	    a = opacity;	dest[0] =	    INT_BLEND(min((dest[0] * 256) / (1 + src[0]), 255), dest[0], a,		      t1);	dest[1] =	    INT_BLEND(min((dest[1] * 256) / (1 + src[1]), 255), dest[1], a,		      t1);	dest[2] =	    INT_BLEND(min((dest[2] * 256) / (1 + src[2]), 255), dest[2], a,		      t1);    }}FImage *divide(FImage * A, FImage * B, int xo, int yo, float value){    int xi = max(xo, 0);    int yi = max(yo, 0);    int xf = min(max(xo + B->width(), 0), A->width());    int yf = min(max(yo + B->height(), 0), A->height());    for (int row = yi; row < yf; row++)	divide(*(*A) (xi, row), *(*B) (xi - xo, row - yo),	       (int) (value * 255), xf - xi, A->channels(), B->channels());    return A;}voidmultiply(unsigned char *dest,	 const unsigned char *src,	 int opacity, int length, int dest_channels, int src_channels){    int a;    register long t1;    unsigned char *end = dest + dest_channels * length;    for (; dest < end; dest += dest_channels, src += src_channels) {	if (src_channels > 3) {	    a = INT_MULT(src[3], opacity, t1);	    if (dest_channels > 3)		dest[3] = min(dest[3], src[3]);	} else	    a = opacity;	dest[0] = INT_BLEND(INT_MULT(src[0], dest[0], t1), dest[0], a, t1);	dest[1] = INT_BLEND(INT_MULT(src[1], dest[1], t1), dest[1], a, t1);	dest[2] = INT_BLEND(INT_MULT(src[2], dest[2], t1), dest[2], a, t1);    }}FImage *multiply(FImage * A, FImage * B, int xo, int yo, float value){    int xi = max(xo, 0);    int yi = max(yo, 0);    int xf = min(max(xo + B->width(), 0), A->width());    int yf = min(max(yo + B->height(), 0), A->height());    for (int row = yi; row < yf; row++)	multiply(*(*A) (xi, row), *(*B) (xi - xo, row - yo),		 (int) (value * 255), xf - xi, A->channels(), B->channels());    return A;}voidscreen(unsigned char *dest,       const unsigned char *src,       int opacity, int length, int dest_channels, int src_channels){    int a;    register long t1;    unsigned char *end = dest + dest_channels * length;    for (; dest < end; dest += dest_channels, src += src_channels) {	if (src_channels > 3) {	    a = INT_MULT(src[3], opacity, t1);	    if (dest_channels > 3)		dest[3] = min(dest[3], src[3]);	} else	    a = opacity;	dest[0] =	    INT_BLEND(255 - INT_MULT(255 - src[0], 255 - dest[0], t1),		      dest[0], a, t1);	dest[1] =	    INT_BLEND(255 - INT_MULT(255 - src[1], 255 - dest[1], t1),		      dest[1], a, t1);	dest[2] =	    INT_BLEND(255 - INT_MULT(255 - src[2], 255 - dest[2], t1),		      dest[2], a, t1);    }}FImage *screen(FImage * A, FImage * B, int xo, int yo, float value){    int xi = max(xo, 0);    int yi = max(yo, 0);    int xf = min(max(xo + B->width(), 0), A->width());    int yf = min(max(yo + B->height(), 0), A->height());    for (int row = yi; row < yf; row++)	screen(*(*A) (xi, row), *(*B) (xi - xo, row - yo),	       (int) (value * 255), xf - xi, A->channels(), B->channels());    return A;}voidoverlay(unsigned char *dest,	const unsigned char *src,	int opacity, int length, int dest_channels, int src_channels){    int a;    register long t1;    unsigned char *end = dest + dest_channels * length;    for (; dest < end; dest += dest_channels, src += src_channels) {	if (src_channels > 3) {	    a = INT_MULT(src[3], opacity, t1);	    if (dest_channels > 3)		dest[3] = min(dest[3], src[3]);	} else	    a = opacity;	dest[0] =	    INT_BLEND(INT_MULT		      (dest[0],		       dest[0] + INT_MULT(2 * src[0], 255 - dest[0], t1), t1),		      dest[0], a, t1);	dest[1] =	    INT_BLEND(INT_MULT		      (dest[1],		       dest[0] + INT_MULT(2 * src[1], 255 - dest[1], t1), t1),		      dest[1], a, t1);	dest[2] =	    INT_BLEND(INT_MULT		      (dest[2],		       dest[0] + INT_MULT(2 * src[2], 255 - dest[2], t1), t1),		      dest[2], a, t1);    }}FImage *overlay(FImage * A, FImage * B, int xo, int yo, float value){    int xi = max(xo, 0);    int yi = max(yo, 0);    int xf = min(max(xo + B->width(), 0), A->width());    int yf = min(max(yo + B->height(), 0), A->height());    for (int row = yi; row < yf; row++)	overlay(*(*A) (xi, row), *(*B) (xi - xo, row - yo),		(int) (value * 255), xf - xi, A->channels(), B->channels());    return A;}

⌨️ 快捷键说明

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