#include"Image.h" #include"octtree.h" #include #define IMax(x,y) ((x)>(y)?(x):(y)) //>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Image utilities Point Image::Crop(ImgRGBColor ccl) { if(!IsData()) GENNFERR("(Crop)Image does not contain data"); if(itype!=ITYPE_RGB) GENNFERR("(CropByColor)Image type not supported"); int psize=(Bpp>>3); int x,y,axl=xlen*psize; int ystop=ylen*Pitch; RGBPixel *tptr; ImgRGBColor col; int xlow,xhigh,ylow,yhigh; xlow=xlen*psize; ylow=ylen*Pitch; yhigh=xhigh=-1; BYTE *dtp=Lock(); for(y=0;yxhigh) xhigh=x; if(y>yhigh) yhigh=y; } } xlow/=psize; xhigh/=psize; ylow/=Pitch; yhigh/=Pitch; UnLock(); Crop(xlow,ylow,xhigh,yhigh); return Point(xlow,ylow); } void Image::Crop(int x1,int y1,int x2, int y2) { if(!IsData()) GENNFERR("(Crop)Image does not contain data"); if(x1<0) x1=0; if(x2<0) x2=0; if(y1<0) y1=0; if(y2<0) y2=0; if(x1>=xlen) x1=xlen-1; if(x2>=xlen) x2=xlen-1; if(y1>=xlen) y1=ylen-1; if(y2>=ylen) y2=ylen-1; if(x1>x2 || y1>y2) GENNFERR("(Crop)Invalid Crop Dimensions"); int nxlen,nylen,x,y; nxlen=x2-x1+1; nylen=y2-y1+1; int psize=(Bpp>>3); int sx,sy,axl=nxlen*psize; int ystop=nylen*nxlen*psize; BYTE *dtp=Lock(); BYTE *ndt=new BYTE[nxlen*nylen*psize+4]; //+4 for overrun for(y=0,sy=y1*Pitch;y>3); int x,y,axl=xlen*psize; int ystop=ylen*Pitch; if(itype==ITYPE_RGB) { RGBPixel *tptr; ImgRGBColor col; for(y=0;ySet(bcol,Mask); } } else { //place 8 Bit implementation here } UnLock(); } float Image::GetBrightness() { if(!IsData()) GENNFERR("(Swap)Image does not contain data"); BYTE *dtp=Lock(); int psize=(Bpp>>3); int x,y,axl=xlen*psize; int ystop=ylen*Pitch; float rsum,gsum,bsum; rsum=gsum=bsum=0.0f; if(itype==ITYPE_RGB) { RGBPixel *tptr; ImgRGBColor col; for(y=0;y>3); int x,y,axl=xlen*psize; int ystop=ylen*Pitch; float rsum,gsum,bsum; rsum=gsum=bsum=0.0f; if(itype==ITYPE_RGB) { RGBPixel *tptr; ImgRGBColor col; for(y=0;ySet(col,Mask); } } else { //place 8 Bit implementation here for(int i=0;i<256;i++) pal[i].BrightenBy(bght); } UnLock(); } void Image::ContrastBy(float cont) { if(!IsData()) GENNFERR("(Swap)Image does not contain data"); BYTE *dtp=Lock(); int psize=(Bpp>>3); int x,y,axl=xlen*psize; int ystop=ylen*Pitch; float rsum,gsum,bsum; rsum=gsum=bsum=0.0f; if(itype==ITYPE_RGB) { RGBPixel *tptr; ImgRGBColor col; for(y=0;ySet(col,Mask); } } else { //place 8 Bit implementation here for(int i=0;i<256;i++) pal[i].ContrastBy(cont); } UnLock(); } void Image::FillHistogram(Histogram *hist,RMETHOD rmet) { if(!IsData()) GENNFERR("(Swap)Image does not contain data"); hist->Clear(); BYTE *dtp=Lock(); int psize=(Bpp>>3); int x,y,axl=xlen*psize; int ystop=ylen*Pitch; float rsum,gsum,bsum; rsum=gsum=bsum=0.0f; if(itype==ITYPE_RGB) { RGBPixel *tptr; ImgRGBColor col; for(y=0;yData[col.r]++; break; case RMD_GREENC: hist->Data[col.g]++; break; case RMD_BLUEC: hist->Data[col.b]++; break; } } } else { //place 8 Bit implementation here } hist->Peak=GetWidth()*GetHeight(); UnLock(); } void Image::FillHistogram(RGBHistogram *hist) { if(!IsData()) GENNFERR("(Swap)Image does not contain data"); hist->Clear(); BYTE *dtp=Lock(); int psize=(Bpp>>3); int x,y,axl=xlen*psize; int ystop=ylen*Pitch; if(itype==ITYPE_RGB) { RGBPixel *tptr; ImgRGBColor col; for(y=0;yRHist.Data[col.r]++; hist->GHist.Data[col.g]++; hist->BHist.Data[col.b]++; } } else { //place 8 Bit implementation here } hist->GHist.Peak=hist->BHist.Peak=hist->RHist.Peak=GetWidth()*GetHeight(); UnLock(); } void Image::AutoAdjust() { RGBHistogram hist(*this); AdjustToRange(hist.GetTop(),hist.GetBottom()); } void Image::AdjustToRange(ImgRGBColor &maxcol,ImgRGBColor &mincol) { if(!IsData()) GENNFERR("(Swap)Image does not contain data"); int min=256,max=0,span=0; min=mincol.rmax?maxcol.r:max; max=maxcol.g>max?maxcol.g:max; max=maxcol.b>max?maxcol.b:max; span=max-min; if(span==0) return; BYTE *dtp=Lock(); int psize=(Bpp>>3); int x,y,axl=xlen*psize; int ystop=ylen*Pitch; if(itype==ITYPE_RGB) { RGBPixel *tptr; ImgRGBColor col; for(y=0;ySet(col,Mask); } } else { //place 8 Bit implementation here for(int i=0;i<256;i++) { pal[i].r=((pal[i].r-min)*256)/span; pal[i].g=((pal[i].g-min)*256)/span; pal[i].b=((pal[i].b-min)*256)/span; pal[i].Bound(); } } UnLock(); } void Image::Swap(const ImgRGBColor &src,const ImgRGBColor &dst) { if(!IsData()) GENNFERR("(Swap)Image does not contain data"); BYTE *dtp=Lock(); int psize=(Bpp>>3); int x,y,axl=xlen*psize; int ystop=ylen*Pitch; if(itype==ITYPE_RGB) { RGBPixel *tptr; ImgRGBColor col; for(y=0;ySet(dst,Mask); } } else { //place 8 Bit implementation here } UnLock(); } void Image::MakeBW() { if(!IsData()) GENNFERR("(MakeBW)Image does not contain data"); BYTE *dtp=Lock(); if(itype==ITYPE_RGB) { int psize=(Bpp>>3); int x,y,axl=xlen*psize; int ystop=ylen*Pitch; RGBPixel *tptr; ImgRGBColor col; for(y=0;ySet(col,Mask); } } else { //place 8 Bit implementation here AllocPal(); for(int i=0;i<256;i++) pal[i].MakeBW(); } UnLock(); } void Image::Invert() { if(!IsData()) GENNFERR("(Invert)Image does not contain data"); BYTE *dtp=Lock(); if(itype==ITYPE_RGB) { RGBPixel *tptr; ImgRGBColor col; int psize=(Bpp>>3); int x,y,axl=xlen*psize; int ystop=ylen*Pitch; for(y=0;ySet(col,Mask); } } else { //8 Bit implementation AllocPal(); for(int i=0;i<256;i++) pal[i].Invert(); RealizePalette(); } UnLock(); } void Image::CreateBlank(int xl,int yl,ITYPE itp,int bpp,RGBMask &msk) { CreateBlank(xl,yl,itp,bpp); Mask=msk; } void Image::CreateBlank(int xl,int yl,ITYPE itp,int bpp) { if(xl<0 || yl<0) GENNFERR("(Create Fade) Invalid dimensions"); //if(bpp!=24 && bpp!=32 && bpp!=8) GENNFERR("(Create Fade) Invalid depth"); if(itp!=ITYPE_RGB && itp!=ITYPE_INDEXED) GENNFERR("(Create Fade) Invalid Image Type"); if(itp==ITYPE_RGB && bpp==8) GENNFERR("(Create Fade) RGB Image cannot be 8-bit"); if(itp==ITYPE_INDEXED && bpp!=8) GENNFERR("(Create Fade) Indexed Images must be 8-bit"); vxlen=xlen=xl; vylen=ylen=yl; itype=itp; Bpp=bpp; if(Bpp==32) Mask=RGBMask(0x00ff0000,0x0000ff00,0x000000ff,0xff000000); else Mask=RGBMask(0x00ff0000,0x0000ff00,0x000000ff); IAlloc(); } void Image::CreateFade(int xl,int yl,ImgRGBColor rgb1,ImgRGBColor rgb2,int ort,ITYPE itp,int bpp) { if(xl<0 || yl<0) GENNFERR("(Create Fade) Invalid dimensions"); //if(bpp!=24 && bpp!=32 && bpp!=8) GENNFERR("(Create Fade) Invalid depth"); if(itp!=ITYPE_RGB && itp!=ITYPE_INDEXED) GENNFERR("(Create Fade) Invalid Image Type"); if(itp==ITYPE_RGB && bpp==8) GENNFERR("(Create Fade) RGB Image cannot be 8-bit"); if(itp==ITYPE_INDEXED && bpp!=8) GENNFERR("(Create Fade) Indexed Images must be 8-bit"); vxlen=xlen=xl; vylen=ylen=yl; itype=itp; Bpp=bpp; int x,y,i; double r,g,b,dist,rinc,ginc,binc; IAlloc(); BYTE *dpt=Lock(); RGBPixel *tptr; ImgRGBColor col; if(ort) dist=xlen; else dist=ylen; int psize=(Bpp>>3); int axl=xlen*psize; switch(Bpp) { case 32: Mask=RGBMask(0x00ff0000,0x0000ff00,0x000000ff,0xff000000); break; case 24: Mask=RGBMask(0x00ff0000,0x0000ff00,0x000000ff,0x00000000); break; case 16: Mask=RGBMask(0x7c00,0x3e0,0x1f); break; case 8: //calculate pallette range rinc=((float)rgb2.r-rgb1.r)/255; ginc=((float)rgb2.g-rgb1.g)/255; binc=((float)rgb2.b-rgb1.b)/255; r=rgb1.r; g=rgb1.g; b=rgb1.b; AllocPal(); for(i=0;i<256;i++) { pal[i]=ImgRGBColor((int)r,(int)g,(int)b); r+=rinc; g+=ginc; b+=binc; } RealizePalette(); for(y=0;y8) { rinc=((float)rgb2.r-rgb1.r)/dist; ginc=((float)rgb2.g-rgb1.g)/dist; binc=((float)rgb2.b-rgb1.b)/dist; r=rgb1.r; g=rgb1.g; b=rgb1.b; if(ort) for(x=0;xSet(col,Mask); } r+=rinc; g+=ginc; b+=binc; } else for(y=0;ySet(col,Mask); } r+=rinc; g+=ginc; b+=binc; } }//end of cs UnLock(); } void Image::CreateSolid(int xl,int yl,ImgRGBColor col,ITYPE itp,int bpp) { if(xl<0 || yl<0) GENNFERR("(Create Solid) Invalid dimensions"); //if(bpp!=24 && bpp!=32 && bpp!=8) GENNFERR("(Create Solid) Invalid depth"); if (itp!=ITYPE_RGB && itp!=ITYPE_INDEXED) GENNFERR("(Create Solid) Invalid Image Type"); if(itp==ITYPE_RGB && bpp==8) GENNFERR("(Create Solid) RGB Image cannot be 8-bit"); if(itp==ITYPE_INDEXED && bpp!=8) GENNFERR("(Create Solid) Indexed Images must be 8-bit"); vxlen=xlen=xl; vylen=ylen=yl; itype=itp; Bpp=bpp; if(Bpp==32) Mask=RGBMask(0x00ff0000,0x0000ff00,0x000000ff,0xff000000); else Mask=RGBMask(0x00ff0000,0x0000ff00,0x000000ff); IAlloc(); FillColor(col); } void Image::FillColor(ImgRGBColor fcol) { int x,y,i; BYTE *dpt=Lock(); int psize=(Bpp>>3); int axl=xlen*psize; RGBPixel tcl(fcol,Mask); int ystop=ylen*Pitch; switch(Bpp) { case 32: case 24: case 16: for(y=0;y>3); int axl=xlen*psize; double xdiv=(xlen-1)/(float)gx,ydiv=(ylen-1)/(float)gy; double xcnt,ycnt; xcnt=ycnt=0.0; RGBPixel fpx(frg,Mask); RGBPixel bpx(bgk,Mask); switch(Bpp) { case 32: case 24: case 16: for(ycnt=0.0,y=0;ySet(frg,Mask); ycnt+=ydiv; } else for(xcnt=0.0,x=0;x>3; int x,y; int ystop=ylen*Pitch; if(byte==3) { for(y=0;y=1;x--) { dt[x*byte+y+0]-=dt[(x-1)*byte+y+0]; dt[x*byte+y+1]-=dt[(x-1)*byte+y+1]; dt[x*byte+y+2]-=dt[(x-1)*byte+y+2]; } } else if(byte==4) { for(y=0;y=1;x--) { dt[x*byte+y+0]-=dt[(x-1)*byte+y+0]; dt[x*byte+y+1]-=dt[(x-1)*byte+y+1]; dt[x*byte+y+2]-=dt[(x-1)*byte+y+2]; } } else GENNFERR("(Difference)Image Size not supported"); UnLock(); } void Image::UnDifference() { if(!IsData()) GENNFERR("(UnDifference)Image does not contain data"); BYTE *dt=Lock(); int byte=Bpp>>3; int x,y,b,xstop; int ystop=ylen*Pitch; xstop=xlen*byte; for(y=0;y>3); int axl=xlen*psize; BYTE *tndt,*ndt=new BYTE[xlen*ylen*2+4]; //+4 for overrun tndt=ndt; int x,y; BYTE *dt=Lock(); switch(itype) { case ITYPE_INDEXED: for(y=0;ySet(pal[dt[x+y*Pitch]],msk); break; case ITYPE_RGB: { ImgRGBColor col; RGBPixel *tptr; int ystop=ylen*Pitch; for(y=0;ySet(col,msk); } } break; } Mask=msk; Bpp=16; UnLock(); itype=ITYPE_RGB; IAlloc(); SetData(ndt); delete ndt; } void Image::MakeRGB(RGBMask msk) { if(!IsData()) GENNFERR("(MakeRGB)Image does not contain data"); if(itype==ITYPE_INDEXED) MakeRGB24(); int opsize,npsize,x,y,axl; opsize=Bpp>>3; npsize=msk.GetBpp()>>3; axl=xlen*opsize; BYTE *tndt,*ndt; ndt=new unsigned char[xlen*ylen*npsize+4]; //+4 for overrun if(ndt==NULL) GENFERR("MemoryAllocation Error"); tndt=ndt; BYTE *dt=Lock(); ImgRGBColor col; RGBPixel *tptr; int ystop=ylen*Pitch; for(y=0;ySet(col,msk); } UnLock(); Mask=msk; Bpp=msk.GetBpp(); itype=ITYPE_RGB; IAlloc(); SetData(ndt); delete ndt; } void Image::MakeRGB24() { if(!IsData()) GENNFERR("(MakeRGB24)Image does not contain data"); //if(Bpp==24) GENNFERR("(MakeRGB24)Image is 24 bit"); if(itype==ITYPE_INDEXED) { BYTE *tndt,*ndt=new BYTE[xlen*ylen*3+4]; //+4 for overrun tndt=ndt; int x,y; BYTE *dt=Lock(); int ystop=ylen*Pitch; for(y=0;ySet(pal[dt[x+y]],Mask); UnLock(); itype=ITYPE_RGB; Bpp=24; IAlloc(); SetData(ndt); delete ndt; } if(itype==ITYPE_RGB) MakeRGB(RGBMask(0xff0000,0xff00,0xff,0x00)); } void Image::CorrectPitch() //corrects the pitch of loaded image { int axl=xlen*(Bpp>>3); if(Pitch==axl) return; if(!IsData()) GENNFERR("(CorrectPitch)Image does not contain data"); int x,y; BYTE *data=Lock(); for(y=ylen-1;y>=0;y--) for(x=axl-1;x>=0;x--) data[x+Pitch*y]=data[x+axl*y]; UnLock(); } void Image::DePitch(BYTE *ndt) //return depicthed COPY of the data, must be deleted { BYTE *dat; int axl=xlen*(Bpp>>3); dat=Lock(); int x,y; for(y=0;y>3); int x,y,axl=xlen*psize; ImgRGBColor col; int ystop=ylen*Pitch; for(y=0;ySet(col,imask); } Mask=imask; UnLock(); } void Image::MaskFrom(RGBMask &omask) //Remask the data from this mask to correct mask { if(!IsData()) GENNFERR("(MaskFrom)Image does not contain data"); if(itype!=ITYPE_RGB) GENNFERR("(MaskFrom)Cannot Mask a non RGB Image"); if(!omask.IsValid()) GENNFERR("(MaskFrom)Invalid Mask"); if(omask==Mask) return; BYTE *dtp=Lock(); RGBPixel *tptr; int psize=(Bpp>>3); int x,y,axl=xlen*psize; ImgRGBColor col; int ystop=ylen*Pitch; for(y=0;ySet(col,Mask); } UnLock(); } void Image::DeInterlace() //deinterlaces a 4 interlaced image { if(!IsData()) GENNFERR("(Deinterlace)Image does not contain data"); BYTE *dtp=Lock(); int psize=(Bpp>>3); int x,y,axl=xlen*psize; BYTE *tndt,*ndt=new BYTE[xlen*ylen*psize+4]; //+4 for overrun tndt=ndt; if(itype==ITYPE_RGB) switch(Bpp) { case 24: case 32: break; case 16: break; } //end of cs else { //place 8 Bit implementation here int pass,skip,start,tln=0; for(pass=0;pass<4;pass++) { if(pass) {skip=16/(1<>1; } else {skip=8; start=0;} for(y=start;y>3); int inc=0,x,y,axl=xlen*psize; int ystop=ylen*Pitch; RGBPixel *tptr; ImgRGBColor col; switch(rm) { case RMD_REDC: for(y=0;ySet(col,Mask); } break; case RMD_BLUEC: for(y=0;ySet(col,Mask); } break; case RMD_GREENC: for(y=0;ySet(col,Mask); } break; case RMD_ALPHAC: for(y=0;ySet(col,Mask); } break; case RMD_MAX: for(y=0;ySet(col,Mask); } break; case RMD_BHT: for(y=0;ySet(col,Mask); } break; } } UnLock(); Bpp=8; itype=ITYPE_INDEXED; IAlloc(); SetData(newdata); MakeGrayscalePalette(); RealizePalette(); delete newdata; } void Image::CreateDifferentialMap() { if(!IsData()) GENNFERR("(MakeBW)Image does not contain data"); if(Bpp<=8) GENNFERR("(ReduceTo8Bit)Already 8bit"); BYTE *dtp=Lock(); if(itype==ITYPE_RGB) { int psize=(Bpp>>3); int x, y, axl = (xlen-1)*psize; int ystop = (ylen-1)*Pitch; RGBPixel *tptr0, *tptr1, *tptr2; ImgRGBColor col0, col1, col2; for(y=0;ySet(col0, Mask); } for(y=0;ySet(col0, Mask); } } UnLock(); } void Image::CreateDifferentialMap(float *im, int xdim) { if(!IsData()) GENNFERR("(MakeBW)Image does not contain data"); if(Bpp<=8) GENNFERR("(ReduceTo8Bit)Already 8bit"); BYTE *dtp=Lock(); if(itype==ITYPE_RGB) { int psize=(Bpp>>3); int i, j, x, y, axl = (xlen-1)*psize; int ystop = (ylen-1)*Pitch; RGBPixel *tptr0, *tptr1, *tptr2; ImgRGBColor col0, col1, col2; for(i=0,y=0;y(im[i*xdim+j]); col0.g = static_cast(abs((int)(((im[i*xdim+j+1]-im[i*xdim+j])+(im[(i+1)*xdim+j]-im[i*xdim+j]))*0.25f*32))); tptr0->Set(col0, Mask); } for(y=0;y(abs((int)(((col1.g-col0.g)+(col2.g-col0.g))*0.25f*4))); tptr0->Set(col0, Mask); } } UnLock(); } bool Image::operator==(Image &img) { if(itype!=img.itype || Bpp!=img.Bpp || xlen!=img.xlen || ylen!=img.ylen) return false; if(itype!=ITYPE_INDEXED) MaskTo(img.Mask); BYTE *ptr1,*ptr2; ptr1=(BYTE *)Lock(); ptr2=(BYTE *)img.Lock(); int y,axl=xlen*(Bpp>>3); for(y=0;y>3); BYTE *DDat=new BYTE[nxlen*nylen*psize]; int b; for(y=-pixs;y=xlen) { sx = xlen-1; } else { sx = x; } } if(y<0) { sy=0; } else { if(y>=ylen) { sy = ylen-1; } else { sy = y; } } for(b=0;b>3); UnLock(); } void Image::MakeSlopeMap(float xscale,float yscale,float zscale,ImgRGBColor lowcol,ImgRGBColor highcol) { if(!IsData()) GENNFERR("(MakeSlopeMap)Image does not contain data"); if(Bpp>8) ReduceTo8Bit(RMD_MAX); BYTE *dtp=Lock(); int psize=(Bpp>>3); int x, y, axl = (xlen-1)*psize; int ystop = (ylen-1)*Pitch; float gdist,tdist,ascale; int cp; ascale=(float)sqrt(xscale*xscale+yscale*yscale); for(y=Pitch;ygdist?tdist:gdist; tdist=(float)atan(fabs((dtp[x+y-Pitch]-cp)*zscale/yscale)); gdist=tdist>gdist?tdist:gdist; tdist=(float)atan(fabs((cp-dtp[x+y+Pitch])*zscale/yscale)); gdist=tdist>gdist?tdist:gdist; /* tdist=(float)atan(fabs((dtp[x+y-(Pitch+1)]-cp)*zscale/ascale)); gdist=tdist>gdist?tdist:gdist; tdist=(float)atan(fabs((cp-dtp[x+y+(Pitch+1)])*zscale/ascale)); gdist=tdist>gdist?tdist:gdist; tdist=(float)atan(fabs((dtp[x+(y-Pitch)+1]-cp)*zscale/ascale)); gdist=tdist>gdist?tdist:gdist; tdist=(float)atan(fabs((cp-dtp[x+y+Pitch+1])*zscale/ascale)); gdist=tdist>gdist?tdist:gdist; */ dtp[x+y-(Pitch+1)]=(BYTE)(gdist*256.0f/3.14159265359f); } MakePalette(lowcol,highcol); UnLock(); } void Image::MakeContourMap(float xscale,float yscale,float zscale, int step, ImgRGBColor bgcol, ImgRGBColor lolinecol,ImgRGBColor highlinecol) { if(!IsData()) GENNFERR("(MakeSlopeMap)Image does not contain data"); if(Bpp>8) ReduceTo8Bit(RMD_MAX); if(xlen<4 || ylen<4) return; BYTE *dtp=Lock(); int psize=(Bpp>>3); int x, y, axl = (xlen-1)*psize; int ystop = (ylen-1)*Pitch; int cp; int blim=256/step; for(y=0;y8) ReduceTo8Bit(RMD_MAX); BYTE *dtp=Lock(); int psize=(Bpp>>3); int x, y, axl = (xlen-1)*psize; int ystop = (ylen-1)*Pitch; float gdist,tdist,ascale; int cp; ascale=(float)sqrt(xscale*xscale+yscale*yscale); for(y=Pitch;ygdist?tdist:gdist; tdist=(float)atan(fabs((dtp[x+y-Pitch]-cp)*zscale/yscale)); gdist=tdist>gdist?tdist:gdist; tdist=(float)atan(fabs((cp-dtp[x+y+Pitch])*zscale/yscale)); gdist=tdist>gdist?tdist:gdist; gdist=gdist*(180.0f/3.14159265359f); dtp[x+y-(Pitch+1)]=(BYTE)(gdist*256.0f/3.14159265359f); if(gdist>limit) dtp[x+y-(Pitch+1)]=255; else dtp[x+y-(Pitch+1)]=0; } MakePalette(lowcol,highcol); UnLock(); } void Image::MakePalette(ImgRGBColor low,ImgRGBColor high) { AllocPal(); int i; float cr,cg,cb; float dr,dg,db; cr=(float)low.r; cg=(float)low.g; cb=(float)low.b; dr=(high.r-low.r)/256.0f; dg=(high.g-low.g)/256.0f; db=(high.b-low.b)/256.0f; for(i=0;i<256;i++) { pal[i]=ImgRGBColor((int)cr,(int)cg,(int)cb); cr+=dr; cb+=db; cg+=dg; } RealizePalette(); }