|
|
/***********************************************************************
* * 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;
if (!buf) { goto ERET; } /* 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)) <BMPTbl[BMPNo].width) { if ((sts = outline( BMPNo, x, y,lsthdl, wkBMP, refBMP))<0) goto RET;
ncont++; x++; } } sts = ncont; cpybuf(refBMP,BMPNo); RET: return( sts); } /***********************************************************************
* Search ON dot */ /* */ static int /* */ SearchON( int BMPNo, int x, int y) /*
* returns : found position, Width(Not Found case) ***********************************************************************/ { int bpos; /* byte position */ int sbitpos; /* Start Byte Bit position */ unsigned char *p;
bpos = x/8; sbitpos = x % 8; p = BMPTbl[BMPNo].buf + BMPTbl[BMPNo].bWid*y + bpos; /* First Byte */ if ( *p & rightmask[sbitpos]) x = bpos*8 + bitptbl[(int)(*p& rightmask[sbitpos])]; else { bpos++; x = bpos*8; for ( ; bpos < BMPTbl[BMPNo].bWid; bpos++, x+=8) { p++; if (*p) { x += bitptbl[(int)*p]; break; } } } return( x); } /***********************************************************************
* make outline data */ /* */ static int /* */ outline( /* */ int BMPNo, /* */ int x, /* */ int y, /* */ int lsthdl, /* */ int wkBMP, /* */ int refBMP) /*
* returns : 0, -1 **********************************************************************/ { int inout; struct vecdata vd; int sts;
/* Check Inside/Outside */ if ( rdot( refBMP, x, y) ==rdot( wkBMP, x, y)) /* OUTSIDE */ inout = 0; else /* INSIDE */ inout = 1;
/* copy buffer */ cpybuf( wkBMP, BMPNo); /* contribute */ vd.x = (short)x; vd.y = (short)y; vd.atr = 0; if ( inout==0) sts = ContributeOutside( BMPNo, wkBMP, &vd, lsthdl); else sts = ContributeInside( BMPNo, wkBMP, &vd, lsthdl); return( sts); } /***********************************************************************
* Contribute Outside Contour */ /* */ static int /* */ ContributeOutside(int BMPNo, int wkBMP, struct vecdata *org, int lsthdl) /*
* returns : 0, -1 * Direction 2 * | * | * 3-------+-------1 * | * | * 0 ***********************************************************************/ { int orgx, orgy; struct vecdata vd; int dir;
if (!org) { return -1; } orgx = org->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;
if (!org) { return -1; } 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 */
|