#include "image.hpp" #include "macs.hpp" #include "system.h" #include "system.h" #include #ifdef __DOS #include #else #include #endif #include extern unsigned char current_background; char *imerr_messages[]={"No error", "Error occured while reading", "Incorrect file type", "File is corrupted", "File not found", "Memory allocation trouble", "Operation/file type not supported", "Error occured while writing, (disk full?)"}; short imerror=0; short swpfile_num=0; short current_error() { return imerror; } void clear_errors() { if (imerror) { printf("Program stopped, error : "); if (imerror<=imMAX_ERROR) printf("%s\n",imerr_messages[imerror]); else printf("Unsonsponsered error code, you got trouble\n"); #ifdef __DOS_ONLY sound(300); delay(100); nosound(); #else printf("%c%c\n",7,8); #endif exit(1); } } void set_error(short x) { imerror=x; } short last_error() { short ec; ec=imerror; imerror=0; return ec; } linked_list image_list; image_descriptor::image_descriptor(short length, short height, int keep_dirties, int static_memory) { clipx1=0; clipy1=0; l=length; h=height; clipx2=l-1; clipy2=h-1; keep_dirt=keep_dirties; static_mem=static_memory; } void image::change_size(short new_width, short new_height, unsigned char *page) { delete_page(); w=new_width; h=new_height; make_page(new_width,new_height,page); } image::~image() { image_list.unlink((linked_node *)this); delete_page(); if (special) delete special; } void make_block(size_t size) { void *dat=jmalloc(size,"make_block : tmp"); CONDITION(dat,"Memory error : could not make block\n"); if (dat) jfree((char *)dat); } unsigned char image::pixel(short x, short y) { CONDITION(x>=0 && x=0 && y=0 && x=0 && y=special->x1_clip() && x<=special->x2_clip() && y>=special->y1_clip() && y<=special->y2_clip()) (*(scan_line(y)+x))=color; } else (*(scan_line(y)+x))=color; } image::image(short width, short height, unsigned char *page_buffer, short create_descriptor) { w=width; h=height; if (create_descriptor || page_buffer) { if (create_descriptor==2) special=new image_descriptor(width,height,1,(page_buffer!=NULL)); else special=new image_descriptor(width,height,0,(page_buffer!=NULL)); } else special=NULL; make_page(width,height,page_buffer); image_list.add_end((linked_node *) this); } image::image(spec_entry *e, bFILE *fp) { short i; fp->seek(e->offset,0); w=fp->read_short(); h=fp->read_short(); special=NULL; make_page(w,h,NULL); for (i=0;iread(scan_line(i),w); image_list.add_end((linked_node *) this); } image::image(bFILE *fp) { short i; w=fp->read_short(); h=fp->read_short(); special=NULL; make_page(w,h,NULL); for (i=0;iread(scan_line(i),w); image_list.add_end((linked_node *) this); } void image_uninit() { /* image *im; while (image_list.first()) { im=(image *)image_list.first(); image_list.unlink((linked_node *)im); delete im; } */ } void image_cleanup(int ret, void *arg) { image_uninit(); } void image_init() { unsigned char bt[2]; unsigned short wrd,*up; bt[0]=1; bt[1]=0; up=(unsigned short *)bt; wrd=int_to_intel(*up); if (wrd!=0x01) { printf("Compiled under wrong ENDING-nes, edit system.h and try again\n"); printf("1 (intel) = %d\n",(int)wrd); exit(1); } imerror=0; } long image::total_pixels(unsigned char background) { short i,j; long co; unsigned char *c; for (co=0,i=height()-1;i>=0;i--) { c=scan_line(i); for (j=width()-1;j>=0;j--,c++) if (*c!=background) co++; } return co; } void image::clear(short color) { short i; if (color==-1) color=current_background; if (special) { if (special->x1_clip()<=special->x2_clip()) for (i=special->y2_clip();i>=special->y1_clip();i--) memset(scan_line(i)+special->x1_clip(),color, special->x2_clip()-special->x1_clip()+1); } else for (i=height()-1;i>=0;i--) memset(scan_line(i),color,width()); add_dirty(0,0,width()-1,height()-1); } image *image::copy() { image *im; unsigned char *c,*dat; int i; dat=(unsigned char *)jmalloc(width(),"image copy"); im=new image(width(),height()); for (i=height()-1;i>=0;i--) { c=scan_line(i); memcpy(dat,c,width()); c=im->scan_line(i); memcpy(c,dat,width()); } jfree((char *)dat); return im; } void image::line(short x1, short y1,short x2, short y2, unsigned char color) { short i,xc,yc,er,n,m,xi,yi,xcxi,ycyi,xcyi; unsigned dcy,dcx; // check to make sure that both endpoint are on the screen short cx1,cy1,cx2,cy2; // check to see if the line is completly clipped off get_clip(cx1,cy1,cx2,cy2); if ((x1cx2 && x2>cx2) || (y1cy2 && y2>cy2)) return ; if (x1>x2) // make sure that x1 is to the left { i=x1; x1=x2; x2=i; // if not swap points i=y1; y1=y2; y2=i; } // clip the left side if (x1cx2) { int my=(y2-y1); int mx=(x2-x1),b; if (!mx) return ; if (my) { b=y1-(y2-y1)*x1/mx; y2=my*cx2/mx+b; x2=cx2; } else x2=cx2; } if (y1>y2) // make sure that y1 is on top { i=x1; x1=x2; x2=i; // if not swap points i=y1; y1=y2; y2=i; } // clip the bottom if (y2>cy2) { int mx=(x2-x1); int my=(y2-y1),b; if (!my) return ; if (mx) { b=y1-(y2-y1)*x1/mx; x2=(cy2-b)*mx/my; y2=cy2; } else y2=cy2; } // clip the top if (y1cx2 || x2>cx2 || y1cy2 || y2>cy2) return ; if (x1>x2) { xc=x2; xi=x1; } else { xi=x2; xc=x1; } // assume y1<=y2 from above swap operation yi=y2; yc=y1; add_dirty(xc,yc,xi,yi); dcx=x1; dcy=y1; xc=(x2-x1); yc=(y2-y1); if (xc<0) xi=-1; else xi=1; if (yc<0) yi=-1; else yi=1; n=abs(xc); m=abs(yc); ycyi=abs(2*yc*xi); er=0; if (n>m) { xcxi=abs(2*xc*xi); for (i=0;i<=n;i++) { *(scan_line(dcy)+dcx)=color; if (er>0) { dcy+=yi; er-=xcxi; } er+=ycyi; dcx+=xi; } } else { xcyi=abs(2*xc*yi); for (i=0;i<=m;i++) { *(scan_line(dcy)+dcx)=color; if (er>0) { dcx+=xi; er-=ycyi; } er+=xcyi; dcy+=yi; } } } void image::put_image(image *screen, short x, short y, char transparent) { short i,j,xl,yl; unsigned char *pg1,*pg2,*source,*dest; if (screen->special) // the screen is clipped then we onl want to put // part of the image put_part(screen,x,y,0,0,width()-1,height()-1,transparent); else { if (xwidth() && yheight()) { xl=width(); if (x+xl>screen->width()) // clip to the border of the screen xl=screen->width()-x; yl=height(); if (y+yl>screen->height()) yl=screen->height()-y; int startx=0,starty=0; if (x<0) { startx=-x; x=0; } if (y<0) { starty=-y; y=0; } if (xl<0 || yl<0) return ; screen->add_dirty(x,y,x+xl-1,y+yl-1); for (j=starty;jscan_line(y); pg2=scan_line(j); if (transparent) { for (i=startx,source=pg2+startx,dest=pg1+x;ispecial) { x1=screen->special->bound_x1(x1); y1=screen->special->bound_y1(y1); x2=screen->special->bound_x2(x2); y2=screen->special->bound_y2(y2); } else { if (x1<0) x1=0; if (y2<0) y1=0; if (x2>=screen->width()) x2=screen->width()-1; if (y2>=screen->height()) y2=screen->height()-1; } if (x2<0 || y2<0 || x1>=screen->width() || y1>=screen->height()) return ; screen->add_dirty(x1,y1,x2,y2); w=width(); if (allign) { start=x1%w; starty=y1%height(); } else { start=0; starty=0; } for (j=y1;j<=y2;j++) { pg1=screen->scan_line(j); pg2=scan_line(starty++); if (starty>=height()) starty=0; i=x1; xx=start; while (i<=x2) { xl=min(w-xx,x2-i+1); memcpy(&pg1[i],&pg2[xx],xl); xx=0; i+=xl; } } } void image::put_part(image *screen, short x, short y, short x1, short y1, short x2, short y2, char transparent) { short xl,yl,j,i; short cx1,cy1,cx2,cy2; unsigned char *pg1,*pg2,*source,*dest; CHECK(x1<=x2 && y1<=y2); screen->get_clip(cx1,cy1,cx2,cy2); // see if the are to be put is outside of actual image, if so adjust // to fit in the image if (x1<0) { x+=-x1; x1=0; } if (y1<0) { y+=-y1; y1=0; } if (x2>=width()) x2=width()-1; if (y2>=height()) y2=height()-1; if (x1>x2 || y1>y2) return ; // return if it was adjusted so that nothing will be put // see if the image gets clipped of the screen if (x>cx2 || y>cy2 || x+(x2-x1)cx2) { x2=cx2-x+x1; } if (y+y2-y1+1>cy2) { y2=cy2-y+y1; } if (x1>x2 || y1>y2) return ; xl=x2-x1+1; yl=y2-y1+1; screen->add_dirty(x,y,x+xl-1,y+yl-1); pg1=screen->scan_line(y); pg2=scan_line(y1); if (transparent) { for (j=0;jnext_line(y+j,pg1); pg2=next_line(y1+j,pg2); } } else for (j=0;jnext_line(y+j,pg1); pg2=next_line(y1+j,pg2); } } void image::put_part_xrev(image *screen, short x, short y, short x1, short y1, short x2, short y2, char transparent) { short xl,yl,j,i; short cx1,cy1,cx2,cy2; unsigned char *pg1,*pg2,*source,*dest; CHECK(x1<=x2 && y1<=y2); i=x1; x1=width()-x2-1; // reverse the x locations x2=width()-i-1; if (x1<0) { x-=x1; x1=0; } if (y1<0) { y-=y1; y1=0; } if (screen->special) { screen->special->get_clip(cx1,cy1,cx2,cy2); if (x>cx2 || y>cy2 || x+(x2-x1)<0 || y+(y2-y1)<0) return ; if (xcx2) { x2=cx2-x+x1; } if (y+y2-y1+1>cy2) { y2=cy2-y+y1; } } else if (x>screen->width() || y>screen->height() || x+x2<0 || y+y2<0) return ; if (xwidth() && yheight() && x1=width()) x2=width()-1; if (y2>=height()) y2=height()-1; xl=x2-x1+1; if (x+xl>screen->width()) xl=screen->width()-x; yl=y2-y1+1; if (y+yl>screen->height()) yl=screen->height()-y; screen->add_dirty(x,y,x+xl-1,y+yl-1); for (j=0;jscan_line(y+j); pg2=scan_line(y1+j); if (transparent) { for (i=0,source=&pg2[x1],dest=&pg1[x+xl-1];ispecial) { screen->special->get_clip(cx1,cy1,cx2,cy2); if (x>cx2 || y>cy2 || x+(x2-x1)<0 || y+(y2-y1)<0) return ; if (xcx2) { x2=cx2+x1-x; } if (y+y2-y1>cy2) { y2=cy2+y1-y; } } else if (x>screen->width() || y>screen->height() || x+x1<0 || y+y1<0) return ; ml=mask->width(); mh=mask->height(); if (xwidth() && yheight() && x1=width()) x2=width()-1; if (y2>=height()) y2=height()-1; xl=x2-x1+1; if (x+xl>screen->width()) xl=screen->width()-x-1; yl=y2-y1+1; if (y+yl>screen->height()) yl=screen->height()-y-1; screen->add_dirty(x,y,x+xl-1,y+yl-1); for (j=0;jscan_line(y+j); pg2=scan_line(y1+j); pg3=mask->scan_line(masky++); if (masky>=mh) // wrap the mask around if out of bounds masky=0; for (i=0;i=ml) // wrap x around if it goes to far maskx=0; } } } } unsigned char image::brightest_color(palette *pal) { unsigned char *p,r,g,b,bri; short i,j; long brv; brv=0; bri=0; for (j=0;jget(p[i],r,g,b); if ((long)r*(long)g*(long)b>brv) { brv=(long)r*(long)g*(long)b; bri=p[i]; } } } return bri; } unsigned char image::darkest_color(palette *pal, short noblack) { unsigned char *p,r,g,b,bri; short i,j; long brv,x; brv=(long)258*(long)258*(long)258; bri=0; for (j=0;jget(p[i],r,g,b); x=(long)r*(long)g*(long)b; if (xset_clip(x1,y1,x2,y2); // set the image descriptor what the clip // should be it will adjust to fit wiothin the image. } void image::get_clip (short &x1, short &y1, short &x2, short &y2) { if (special) special->get_clip(x1,y1,x2,y2); else { x1=0; y1=0; x2=width()-1; y2=height()-1; } } void image::in_clip (short x1, short y1, short x2, short y2) { if (special) { if (x1x1_clip()) x1=special->x1_clip(); if (y1y1_clip()) y1=special->y1_clip(); if (x2>special->x2_clip()) x2=special->x2_clip(); if (y2>special->y2_clip()) y2=special->y2_clip(); } set_clip(x1,y1,x2,y2); } // this function reduces the number of dirty rectanges // to 1 by find the minmum area that can contain all the rectangles and // making this the new dirty area void image_descriptor::reduce_dirties() { dirty_rect *p,*q; short x1,y1,x2,y2,nn; x1=6000; y1=6000; x2=0; y2=0; p=(dirty_rect *)dirties.first(); nn=dirties.number_nodes(); while (nn>0) { if (p->dx1dx1; if (p->dy1dy1; if (p->dx2>x2) x2=p->dx2; if (p->dy2>y2) y2=p->dy2; q=p; p=(dirty_rect *)p->next(); dirties.unlink((linked_node *)q); delete q; nn--; } dirties.add_front((linked_node *) new dirty_rect(x1,y1,x2,y2)); } void image_descriptor::delete_dirty(int x1, int y1, int x2, int y2) { short i,ax1,ay1,ax2,ay2; dirty_rect *p,*next; if (keep_dirt) { if (x1<0) x1=0; if (y1<0) y1=0; if (x2>=(int)l) x2=l-1; if (y2>=(int)h) y2=h-1; if (x1>x2) return; if (y1>y2) return ; i=dirties.number_nodes(); if (!i) return ; else { for (p=(dirty_rect *)dirties.first();i;i--,p=(dirty_rect *)next) { next=(dirty_rect *)p->next(); // are the two touching? if (!(x2dx1 || y2dy1 || x1>p->dx2 || y1>p->dy2)) { // does it take a x slice off? (across) if (x2>=p->dx2 && x1<=p->dx1) { if (y2>=p->dy2 && y1<=p->dy1) { dirties.unlink((linked_node *)p); delete p; } else if (y2>=p->dy2) p->dy2=y1-1; else if (y1<=p->dy1) p->dy1=y2+1; else { dirties.add_front((linked_node *) new dirty_rect(p->dx1,p->dy1,p->dx2,y1-1)); p->dy1=y2+1; } } // does it take a y slice off (down) else if (y2>=p->dy2 && y1<=p->dy1) { if (x2>=p->dx2) p->dx2=x1-1; else if (x1<=p->dx1) p->dx1=x2+1; else { dirties.add_front((linked_node *) new dirty_rect(p->dx1,p->dy1,x1-1,p->dy2)); p->dx1=x2+1; } } // otherwise it just takes a little chunk off else { if (x2>=p->dx2) { ax1=p->dx1; ax2=x1-1; } else if (x1<=p->dx1) { ax1=x2+1; ax2=p->dx2; } else { ax1=p->dx1; ax2=x1-1; } if (y2>=p->dy2) { ay1=y1; ay2=p->dy2; } else if (y1<=p->dy1) { ay1=p->dy1; ay2=y2; } else { ay1=y1; ay2=y2; } dirties.add_front((linked_node *) new dirty_rect(ax1,ay1,ax2,ay2)); if (x2>=p->dx2 || x1<=p->dx1) { ax1=p->dx1; ax2=p->dx2; } else { ax1=x2+1; ax2=p->dx2; } if (y2>=p->dy2) { if (ax1==p->dx1) { ay1=p->dy1; ay2=y1-1; } else { ay1=y1; ay2=p->dy2; } } else if (y1<=p->dy1) { if (ax1==p->dx1) { ay1=y2+1; ay2=p->dy2; } else { ay1=p->dy1; ay2=y2; } } else { if (ax1==p->dx1) { ay1=p->dy1; ay2=y1-1; } else { ay1=y1; ay2=y2; } } dirties.add_front((linked_node *) new dirty_rect(ax1,ay1,ax2,ay2)); if (x1>p->dx1 && x2dx2) { if (y1>p->dy1 && y2dy2) { dirties.add_front((linked_node *) new dirty_rect(p->dx1,p->dy1,p->dx2,y1-1)); dirties.add_front((linked_node *) new dirty_rect(p->dx1,y2+1,p->dx2,p->dy2)); } else if (y1<=p->dy1) dirties.add_front((linked_node *) new dirty_rect(p->dx1,y2+1,p->dx2,p->dy2)); else dirties.add_front((linked_node *) new dirty_rect(p->dx1,p->dy1,p->dx2,y1-1)); } else if (y1>p->dy1 && y2dy2) dirties.add_front((linked_node *) new dirty_rect(p->dx1,y2+1,p->dx2,p->dy2)); dirties.unlink((linked_node *) p); delete p; } } } } } } // specifies that an area is a dirty void image_descriptor::add_dirty(int x1, int y1, int x2, int y2) { short i; dirty_rect *p; if (keep_dirt) { if (x1<0) x1=0; if (y1<0) y1=0; if (x2>=(int)l) x2=l-1; if (y2>=(int)h) y2=h-1; if (x1>x2) return; if (y1>y2) return ; i=dirties.number_nodes(); if (!i) dirties.add_front((linked_node *) new dirty_rect(x1,y1,x2,y2)); else if (i>=MAX_DIRTY) { dirties.add_front((linked_node *) new dirty_rect(x1,y1,x2,y2)); reduce_dirties(); // reduce to one dirty rectangle, we have to many } else { for (p=(dirty_rect *)dirties.first();i>0;i--) { // check to see if this new rectangle completly encloses the check rectangle if (x1<=p->dx1 && y1<=p->dy1 && x2>=p->dx2 && y2>=p->dy2) { dirty_rect *tmp=(dirty_rect*) p->next(); dirties.unlink((linked_node *)p); delete p; if (!dirties.first()) i=0; else p=tmp; } else if (!(x2dx1 || y2dy1 || x1>p->dx2 || y1>p->dy2)) { /* if (x1<=p->dx1) { a+=p->dx1-x1; ax1=x1; } else ax1=p->dx1; if (y1<=p->dy1) { a+=p->dy1-y1; ay1=y1; } else ay1=p->dy1; if (x2>=p->dx2) { a+=x2-p->dx2; ax2=x2; } else ax2=p->dx2; if (y2>=p->dy2) { a+=y2-p->dy2; ay2=y2; } else ay2=p->dy2; if (a<50) { p->dx1=ax1; // then expand the dirty p->dy1=ay1; p->dx2=ax2; p->dy2=ay2; return ; } else */ { if (x1dx1) add_dirty(x1,max(y1,p->dy1),p->dx1-1,min(y2,p->dy2)); if (x2>p->dx2) add_dirty(p->dx2+1,max(y1,p->dy1),x2,min(y2,p->dy2)); if (y1dy1) add_dirty(x1,y1,x2,p->dy1-1); if (y2>p->dy2) add_dirty(x1,p->dy2+1,x2,y2); return ; } p=(dirty_rect *)p->next(); } else p=(dirty_rect *)p->next(); } CHECK(x1<=x2 && y1<=y2); dirties.add_end((linked_node *)new dirty_rect(x1,y1,x2,y2)); } } } void image::bar (short x1, short y1, short x2, short y2, unsigned char color) { short y; if (x1>x2 || y1>y2) return ; if (special) { x1=special->bound_x1(x1); y1=special->bound_y1(y1); x2=special->bound_x2(x2); y2=special->bound_y2(y2); } else { if (x1<0) x1=0; if (y1<0) y1=0; if (x2>=width()) x2=width()-1; if (y2>=height()) y2=height()-1; } if (x2<0 || y2<0 || x1>=width() || y1>=height() || x2x2 || y1>y2) return ; if (special) { x1=special->bound_x1(x1); y1=special->bound_y1(y1); x2=special->bound_x2(x2); y2=special->bound_y2(y2); } else { if (x1<0) x1=0; if (y1<0) y1=0; if (x2>=width()) x2=width()-1; if (y2>=height()) y2=height()-1; } if (x2<0 || y2<0 || x1>=width() || y1>=height() || x2>sh))>>(bt-sh-1); } jfree((char *)ex); } void image::dither(palette *pal) { short x,y,i,j; unsigned char dt_matrix[]={0, 136,24, 170, 68, 204,102,238, 51, 187, 17,153, 119,255, 85,221}; unsigned char *sl; for (y=height()-1;y>=0;y--) { sl=scan_line(y); for (i=0,j=y%4,x=width()-1;x>=0;x--) { if (pal->red(sl[x])>dt_matrix[j*4+i]) sl[x]=255; else sl[x]=0; if (i==3) i=0; else i++; } } } void image_descriptor::clear_dirties() { dirty_rect *dr; dr=(dirty_rect *)dirties.first(); while (dr) { dirties.unlink(dr); delete dr; dr=(dirty_rect *)dirties.first(); } } void image::resize(short new_width, short new_height) { int old_width=width(),old_height=height(); unsigned char *im=(unsigned char *)jmalloc(width()*height(),"image::resized"); memcpy(im,scan_line(0),width()*height()); delete_page(); make_page(new_width,new_height,NULL); w=new_width; // set the new hieght and width h=new_height; unsigned char *sl1,*sl2; short y,y2,x2; double yc,xc,yd,xd; yc=(double)old_height/(double)new_height; xc=(double)old_width/(double)new_width; for (y2=0,yd=0;y2resize(new_width,new_height); } void image::scroll(short x1, short y1, short x2, short y2, short xd, short yd) { short cx1,cy1,cx2,cy2; CHECK(x1>=0 && y1>=0 && x1get_clip(cx1,cy1,cx2,cy2); x1=max(x1,cx1); y1=max(cy1,y1); x2=min(x2,cx2); y2=min(y2,cy2); } short xsrc,ysrc,xdst,ydst,xtot=x2-x1-abs(xd)+1,ytot,xt; unsigned char *src,*dst; if (xd<0) { xsrc=x1-xd; xdst=x1; } else { xsrc=x2-xd; xdst=x2; } if (yd<0) { ysrc=y1-yd; ydst=y1; } else { ysrc=y2-yd; ydst=y2; } for (ytot=y2-y1-abs(yd)+1;ytot;ytot--) { src=scan_line(ysrc)+xsrc; dst=scan_line(ydst)+xdst; if (xd<0) for (xt=xtot;xt;xt--) *(dst++)=*(src++); else for (xt=xtot;xt;xt--) *(dst--)=*(src--); if (yd<0) { ysrc++; ydst++; } else { ysrc--; ydst--; } } add_dirty(x1,y1,x2,y2); } image *image::create_smooth(short smoothness) { short i,j,k,l,t,d; image *im; CHECK(smoothness>=0); if (!smoothness) return NULL; d=smoothness*2+1; d=d*d; im=new image(width(),height()); for (i=0;ismoothness && i+ksmoothness) t+=pixel(i+k,j+l); else t+=pixel(i,j); im->putpixel(i,j,t/d); } return im; } void image::wiget_bar(short x1, short y1, short x2, short y2, unsigned char light, unsigned char med, unsigned char dark) { line(x1,y1,x2,y1,light); line(x1,y1,x1,y2,light); line(x2,y1+1,x2,y2,dark); line(x1+1,y2,x2-1,y2,dark); bar(x1+1,y1+1,x2-1,y2-1,med); } class fill_rec { public : short x,y; fill_rec *last; fill_rec(short X, short Y, fill_rec *Last) { x=X; y=Y; last=Last; } } ; void image::flood_fill(short x, short y, unsigned char color) { unsigned char *sl,*above,*below; fill_rec *recs=NULL,*r; unsigned char fcolor; sl=scan_line(y); fcolor=sl[x]; if (fcolor==color) return ; do { if (recs) { r=recs; recs=recs->last; x=r->x; y=r->y; delete r; } sl=scan_line(y); if (sl[x]==fcolor) { while (sl[x]==fcolor && x>0) x--; if (sl[x]!=fcolor) x++; if (y>0) { above=scan_line(y-1); if (above[x]==fcolor) { r=new fill_rec(x,y-1,recs); recs=r; } } if (y0) { above=scan_line(y-1); if (x>0 && above[x-1]!=fcolor && above[x]==fcolor) { r=new fill_rec(x,y-1,recs); recs=r; } } if (y0 && below[x-1]!=fcolor && below[x]==fcolor) { r=new fill_rec(x,y+1,recs); recs=r; } } x++; } while (sl[x]==fcolor && x0) { above=scan_line(y-1); if (above[x]==fcolor) { r=new fill_rec(x,y-1,recs); recs=r; } } if (ycy2) y2=cy2; if (x2>cx2) x2=cx2; CHECK(x2>=x1 && y2>=y1); if (x2clear(); else for (y=y1,ry=0,dity=(y1%4)*4;y<=y2;y++,ry++) { sl1=ret->scan_line(ry); // sl1 is the scan linefo the return image sl2=scan_line(y); // sl2 is the orginal image scan line memset(sl1,0,(x2-x1+8)/8); for (bo=7,rx=0,x=x1,ditx=x1%4;x<=x2;x++) { if (last_loaded()->red(sl2[x])>dither_matrix[ditx+dity]) sl1[rx]|=1<3) ditx=0; } dity+=4; if (dity>12) dity=0; } return ret; } void image::flip_x() { unsigned char *rev=(unsigned char *)jmalloc(width(),"image tmp::flipped_x"),*sl; CONDITION(rev,"memory allocation"); int y,x,i; for (y=0;y=0;x--,i++) rev[i]=sl[x]; memcpy(sl,rev,width()); } jfree(rev); } void image::flip_y() { unsigned char *rev=(unsigned char *)jmalloc(width(),"image::flipped_y"),*sl; CONDITION(rev,"memory allocation"); int y; for (y=0;y