/*********************************************************************** * * BitMap Openration modules * * Copyright (c) 1997-1999 Microsoft Corporation. * *********************************************************************** * BitMap Specifications * * Coordinate * (0,0) X (255,0) * +--------------* * | * Y | * | * | * | * * * (0,255) * Memory Boundary : Word Boundary * * Entry List * BMPDefine, * BMPZoomUp, * BMPOutline ***********************************************************************/ #include "stdafx.h" #include "vdata.h" #include "extfunc.h" #define BMPWIDMAX 256 #define BMPDEPMAX 256 #define BMPMAX 8 struct BMPDef { int width, depth; unsigned char *buf; int bWid; }; void BMPInit(void); int BMPDefine(unsigned char *buf,int xWid,int yWid); int BMPFreDef(int bmpno); int BMPMkCont(int BMPNo,int wkBMP,int refBMP,int lsthdl); static int SearchON(int BMPNo,int x,int y); static int outline(int BMPNo,int x,int y,int lsthdl,int wkBMP,int refBMP); static int ContributeOutside(int BMPNo,int wkBMP,struct vecdata *org,int lsthdl); static int ContributeInside(int BMPNo,int wkBMP,struct vecdata *org,int lsthdl); int rdot(int BMP,int x,int y); void wdot(int BMP,int x,int y,int onoff); int ReverseRight(int BMPNo,int x,int y); static void cpybuf(int src,int dst); int BMPReverse(int bmpNo); int BMPClear(int bmpNo); struct BMPDef BMPTbl[BMPMAX]={0}; /* On Bit Most left position */ static unsigned char bitptbl[256] = { 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static unsigned char wmaskB[8]={ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; static unsigned char rightmask[8] = { 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01 }; /*********************************************************************** * BMP Initialize */ /* */ void /* */ BMPInit() /* * returns; none ***********************************************************************/ { int i; for ( i = 0; i < BMPMAX; i++) BMPTbl[i].buf=(unsigned char *)0; return; } /*********************************************************************** * Define BitMap */ /* */ int /* */ BMPDefine( /* */ unsigned char *buf, /* */ int xWid, /* */ int yWid) /* * returns : 0-(BMPMAX-1), -1 ***********************************************************************/ { int i; /* Check Size */ if ( xWid > BMPWIDMAX || xWid < 0 || yWid > BMPWIDMAX || yWid < 0) goto ERET; /* Set Define */ for ( i = 0; i < BMPMAX; i++) { if (BMPTbl[i].buf==(unsigned char *)0) { BMPTbl[i].bWid = (xWid + 15)/16*2; BMPTbl[i].width = xWid; BMPTbl[i].depth = yWid; BMPTbl[i].buf = buf; return(i); } } ERET: return( -1); } /*********************************************************************** * Free BMP define */ /* */ int /* */ BMPFreDef( int bmpno) /* * returns : 0, -1 ***********************************************************************/ { if ( bmpno < 0 || bmpno >= BMPMAX) return -1; else { BMPTbl[bmpno].buf = 0; return 0; } } /*********************************************************************** * Get Outline */ /* */ int /* */ BMPMkCont( int BMPNo, int wkBMP, int refBMP, int lsthdl) /* * returns : Number of Contour, -1 * REMARKS : Used BMP be destroyed ***********************************************************************/ { int x, y; int ncont; int sts; VDNew( lsthdl); sts = 0; ncont = 0; cpybuf( BMPNo, wkBMP); cpybuf( BMPNo, refBMP); for ( y = 0; y < BMPTbl[BMPNo].depth; y++) { x = 0; while ( (x = SearchON( wkBMP, x, y)) x; orgy = org->y; vd = *org; dir = 0; /* if (ReverseRight( wkBMP, vd.x, vd.y)) return( -1); */ do { if (VDSetData( lsthdl, &vd)) return(-1); switch( dir) { case 0: if (ReverseRight( wkBMP, vd.x, vd.y)) return( -1); vd.y++; if ( rdot( BMPNo, vd.x-1, vd.y)) dir = 3; else if ( rdot( BMPNo, vd.x, vd.y)) dir = 0; else dir = 1; break; case 1: vd.x++; if ( rdot( BMPNo, vd.x, vd.y)) dir = 0; else if ( rdot( BMPNo, vd.x, vd.y-1)) dir = 1; else dir = 2; break; case 2: vd.y--; if (ReverseRight( wkBMP, vd.x, vd.y)) return( -1); if ( rdot( BMPNo, vd.x, vd.y-1)) dir = 1; else if ( rdot( BMPNo, vd.x-1, vd.y-1)) dir = 2; else dir = 3; break; case 3: vd.x--; if ( rdot( BMPNo, vd.x-1, vd.y-1)) dir = 2; else if ( rdot( BMPNo, vd.x-1, vd.y)) dir = 3; else dir = 0; break; } } while( vd.x!=orgx || vd.y != orgy); VDClose(lsthdl); return( 0); } /*********************************************************************** * Contribute Outside Contour */ /* */ static int /* */ ContributeInside( int BMPNo, int wkBMP, struct vecdata *org, int lsthdl) /* * returns : 0, -1 ***********************************************************************/ { int orgx, orgy; struct vecdata vd; int dir; orgx = org->x; orgy = org->y; vd = *org; dir = 1; do { if (VDSetData( lsthdl, &vd)) return(-1); switch( dir) { case 0: if (ReverseRight( wkBMP, vd.x, vd.y)) return( -1); vd.y++; if ( rdot( BMPNo, vd.x-1, vd.y)==0) /* right */ dir = 3; else if ( rdot( BMPNo, vd.x, vd.y)==0) /* left */ dir = 0; else dir = 1; break; case 1: vd.x++; if ( rdot( BMPNo, vd.x, vd.y)==0) /* right */ dir = 0; else if ( rdot( BMPNo, vd.x, vd.y-1)==0) /* left */ dir = 1; else dir = 2; break; case 2: vd.y--; if (ReverseRight( wkBMP, vd.x, vd.y)) return( -1); if ( rdot( BMPNo, vd.x, vd.y-1)==0) dir = 1; else if ( rdot( BMPNo, vd.x-1, vd.y-1)==0) dir = 2; else dir = 3; break; case 3: vd.x--; if ( rdot( BMPNo, vd.x-1, vd.y-1)==0) dir = 2; else if ( rdot( BMPNo, vd.x-1, vd.y)==0) dir = 3; else dir = 0; break; } } while( vd.x!=orgx || vd.y != orgy); VDClose(lsthdl); return( 0); } /*********************************************************************** * Read Dot */ /* */ int /* */ rdot( int BMP, int x, int y) /* * returns : 0, nonzero ***********************************************************************/ { unsigned char *radd; int rbit; int onoff; if ( x < 0 || y < 0 || x>=BMPTbl[BMP].width ||y>=BMPTbl[BMP].depth) return( 0); radd = BMPTbl[BMP].buf + BMPTbl[BMP].bWid*y + x/8; rbit = x % 8; onoff = (int)(wmaskB[rbit] & *radd); return onoff; } /*********************************************************************** * Write Dot */ /* */ void /* */ wdot( int BMP, int x, int y, int onoff) /* * returns : none ***********************************************************************/ { unsigned char *radd; int rbit; if ( x < 0 || y < 0 || x>=BMPTbl[BMP].width ||y>=BMPTbl[BMP].depth) return; radd = BMPTbl[BMP].buf + BMPTbl[BMP].bWid*y + x/8; rbit = x % 8; if ( onoff) *radd |= wmaskB[rbit]; else *radd &= ~wmaskB[rbit]; return; } /*********************************************************************** * Reverse right side ( Edge fill method) */ /* */ int /* */ ReverseRight( int BMPNo, int x, int y) /* * returns : 0, -1 ***********************************************************************/ { int rb; int bitp; unsigned char *wp; if ( BMPNo < 0 || BMPNo >= BMPMAX) return 0; if ( x < 0 || x >= BMPTbl[BMPNo].width || y < 0 || y >= BMPTbl[BMPNo].depth) return 0; rb = BMPTbl[BMPNo].bWid - x/8 -1; bitp = x%8; wp = BMPTbl[BMPNo].buf + y*BMPTbl[BMPNo].bWid + x/8; /* First Byte */ *wp ^= rightmask[bitp]; /* to right limit */ while( rb-->0) { wp++; *wp = (unsigned char)~(*wp); } return ( 0); } /*********************************************************************** * Copy Buffer */ /* */ static void /* */ cpybuf( int src, int dst) /* * returns : none ***********************************************************************/ { int siz; if ( src < 0 || src >= BMPMAX) return; if ( dst < 0 || dst >= BMPMAX) return; siz = BMPTbl[src].bWid * BMPTbl[src].depth; memcpy( BMPTbl[dst].buf, BMPTbl[src].buf, siz); } /*********************************************************************** * Reverse bitmap */ /* */ int /* */ BMPReverse( int bmpNo) /* * returns : none ***********************************************************************/ { int siz; char *buf; if ( bmpNo < 0 || bmpNo >= BMPMAX) return -1; else if (BMPTbl[bmpNo].buf==(unsigned char *)0) return -1; else { siz = BMPTbl[bmpNo].bWid * BMPTbl[bmpNo].depth; buf = (char *)BMPTbl[bmpNo].buf; while ( siz-->0) { *buf = (char)~*buf; buf++; } } return 0; } /*********************************************************************** * Clear BMP */ /* */ int /* */ BMPClear( int bmpNo) /* * returns : 0,-1 ***********************************************************************/ { int siz; if ( bmpNo < 0 || bmpNo >= BMPMAX) return -1; else if (BMPTbl[bmpNo].buf==(unsigned char *)0) return -1; siz = BMPTbl[bmpNo].bWid * BMPTbl[bmpNo].depth; memset( BMPTbl[bmpNo].buf, 0, siz); return 0; } /* EOF */