You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

294 lines
9.2 KiB
C++

//////////////////////////////////////////////////////////////////////////////
//Îļþ ImageVector.h
//Ö÷Òª¹¦ÄÜ:
//
//³ÌÐò±àд: 2005-12-07
/////////////////////////////////////////////////////////////////////////////
#pragma once
#include "ImageTraceBase.h"
namespace NImage
{
#define TG_FORWARD (+1)
#define TG_BACKWARD (-1)
typedef struct __stuLinkRecord
{
union{
struct{
void *m_pData;
int dataType;
};
char user_data[8];
};
struct __stuLinkRecord *m_pPrev;
struct __stuLinkRecord *m_pNext;
} CLinkRecord;
typedef struct __stuLinkHead
{
CLinkRecord *m_pHead;
CLinkRecord *m_pLast;
CLinkRecord *m_pCurrent;
int count;
} CLinkHead;
typedef enum __emLinkLoc{
TG_ERROR=-1,
TG_HEAD,
TG_TAIL,
TG_AFTER,
TG_BEFORE,
TG_CURRENT
} emLinkLoc;
typedef enum __emListStatusCode{
LSC_SUCCESS = 0,
LSC_MATCH_FOUND,
LSC_MATCH_NOT_FOUND,
LSC_BAD_SEARCH_DIR,
LSC_BAD_START_LOC,
LSC_BAD_STOP_LOC,
LSC_BAD_LIST,
LSC_BAD_COMPARE_FUNCTION,
LSC_ITEMS_NOT_PURGED,
LSC_PURGE_POLY_FAILED
} emListStatusCode;
class CLinkList
{
public:
CLinkList(void);
int AddListItem(CLinkHead *list, emLinkLoc loc, void *data, int dataType);
CLinkHead* CreateList(void);
void * DeleteListItem(CLinkHead *list, emLinkLoc del_loc, emLinkLoc ret_loc);
int GetListCount(CLinkHead *list);
int GetDataType(CLinkHead *list);
void * GetListData(CLinkHead *list);
emListStatusCode PurgeList(CLinkHead *list);
void RearrangeList(CLinkHead *list, int dir);
emLinkLoc SetListCurrpntr(CLinkHead *list, emLinkLoc set_loc);
int AppendList(CLinkHead *ldst, CLinkHead *lsrc);
int DestroyFreeList(CLinkHead *p_list);
int EmptyFreeList(CLinkHead *p_list);
void * SetListData(CLinkHead *list, void *data);
int AddListData(CLinkHead *list, emLinkLoc loc, void *data);
int GetListUserData(CLinkHead *list, void *user_data);
int SetListUserData(CLinkHead *list, emLinkLoc set_loc, void *data);
void * GetListUserDataAddr(CLinkHead *list);
protected:
void* ChangeListData(CLinkHead* list, void *prev_data, void *new_data);
int ClearList(CLinkHead* p_list);
CLinkHead* CreateFillList(int count, int size);
emListStatusCode SearchList(CLinkHead* list, emLinkLoc start_loc, emLinkLoc stop_loc, emLinkLoc sdir,
int (*cmp) (void *, void *), void *cmp_data);
void* SeekDelete(CLinkHead* list, void *data);
int SetListDataType(CLinkHead* list, int dataType);
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef POSITION (*FUN_AddImageCurve) (CCurve *curve);
class CFlushPoly
{
public:
CFlushPoly(void);
virtual ~CFlushPoly(void);
void update_min_max_pnt(CPoint *p_imgp, CPoint *p_min_imgp, CPoint *p_max_imgp);
double img_points_dist(CPoint *p_imgp0, CPoint *p_imgp1);
int flush_polyline(CLinkHead *p_polyline_list, double min_polyline_lenght);
int opt_flush_polyline(CLinkHead *p_polyline_list, double pnt_error_tolerance, double min_polyline_lenght);
CPoint2D m_pointOrg;
CSize8 m_scale;
CScreenXY* m_pSxy;
FUN_AddImageCurve m_pFunAddCurve;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define HORIZONTAL_LINE 0
#define VERTICAL_LINE 1
#define read_bit(m,n) (((((BYTE *)(m))[(n) >> 3]) & (1 << (7-((n) & 7)))) ? 1:0)
#define read_bit2(fp,m,n) (((((BYTE *)(m))[(n) >> 3]) & (1 << (7-((n) & 7)))) ? (fp):(1-(fp)))
#define set_bit(m,n) ((BYTE *)(m))[(n) >> 3] |= (1 << (7-((n) & 7)))
#define clear_bit(m,n) ((BYTE *)(m))[(n) >> 3] &= (~(1 << (7-((n) & 7))))
#define clear_pixel(m,n,b) \
{ \
if((b)!=0) \
set_bit(m,n); \
else \
clear_bit(m,n); \
}
#define get_line_size(x) ((((x)+31)/32)*4)
#define get_raw_img_line(p,lsz,nl) ((BYTE*)GetPixelAddress(0, nl))
#define same_point(p0,p1) (((p0)->x==(p1)->x) && ((p0)->y==(p1)->y))
#define line_type(p0,p1) (((p0)->x==(p1)->x)?VERTICAL_LINE:HORIZONTAL_LINE)
#define pnt_distance_2(p0,p1) ((((p0)->x-(p1)->x)*((p0)->x-(p1)->x))+ \
(((p0)->y-(p1)->y)*((p0)->y-(p1)->y)))
typedef struct __PolylineRecord{
CLinkHead *p_poly_list;
CPoint prev_pnt0;
CPoint last_pnt0;
CPoint pnt0;
CPoint prev_pnt1;
CPoint last_pnt1;
CPoint pnt1;
} polyline;
typedef struct ins_polyline_record
{
int insert_location;
CPoint link_pnt;
CPoint pnt;
polyline *p_polyline;
} ins_polyline;
typedef struct scan_data_record
{
int current_line;
BYTE *p_raw_ptr;
BYTE *p_lines;
BYTE *p_line;
BYTE *p_next_line;
BYTE *p_nnext_line;
BYTE *v_open;
CLinkHead *p_polylines_list;
CLinkHead **pp_gating_polylines;
int number_of_polylines;
} scan_data;
typedef struct vect_poly_record
{
CLinkHead *p_poly_list;
CPoint prev_pnt;
CPoint last_pnt;
CPoint pnt;
} vect_poly;
typedef struct __stuScanError
{
int back_ground;
double pnt_error_tolerance; //ÈÝÐíÁ¿
double min_polyline_lenght;
} SCAN_ERROR;
//for tree
typedef struct node_record
{
int red;
void *data;
void *key;
struct node_record *l;
struct node_record *r;
} NodeRecord;
typedef struct tree_record
{
int (*compare_keys) (void *, void *);
int sizeof_key;
void *init_key;
NodeRecord *head;
NodeRecord *z;
NodeRecord *x;
NodeRecord *g;
NodeRecord *p;
NodeRecord *gg;
} TreeRecord;
typedef void *HTREE;
class CHTree
{
public:
CHTree(void);
HTREE tree_create(int sizeof_key,void *init_key, int (*compare_keys)(void *,void *));
int tree_insert(HTREE htree,void *key,void *data);
void * tree_search(HTREE htree,void *key);
int tree_search_multi(HTREE htree,void *key, int (*search_callback)(void *,void *), void *p_param);
int tree_free(HTREE htree);
int tree_empty(HTREE htree);
void * tree_delete(HTREE htree,void *key);
void * tree_delete_from_data(HTREE htree,void *key,void *data);
NodeRecord* alloc_node(TreeRecord * p_tree, void *key, int red, void *data, NodeRecord * l, NodeRecord * r);
int tree_search_equals(TreeRecord* p_tree, void *key, NodeRecord* x, int (*search_callback) (void *, void *), void *p_param);
static void free_node(NodeRecord * p_node, int free_data);
static void tree_empty_ll(TreeRecord* p_tree, NodeRecord* x);
static NodeRecord *rotate(TreeRecord* p_tree, void *key, NodeRecord* y);
static int tree_cmp_keys(TreeRecord* p_tree, void *key1, void *key2);
static int split(TreeRecord* p_tree, void *key);
static void tree_free_ll(TreeRecord * p_tree, NodeRecord * x);
};
//ͼÏñÈ«×Ô¶¯Ê¸Á¿»¯
class CImageVector :
public CImageTraceBase
{
public:
CImageVector(void);
virtual ~CImageVector(void);
int CenterLineConvert(double pnt_error_tolerance, double min_polyline_lenght); //Êä³öÖÐÐÄÏß
int DoubleLineConvert(double pnt_error_tolerance, double min_polyline_lenght); //Êä³öÂÖÀªÏߣ¨Ë«Ïߣ©
CFlushPoly m_flush;
SCAN_ERROR m_error;
protected:
int BmpFileGetBackground(int x_samples, int y_samples);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
protected://Êä³öÖÐÐÄÏß
CLinkHead* CL_GetNodePoints(void);
HTREE CL_GetPointsTree(CLinkHead * p_pnts_list);
int CL_ThinImage(void);
int CL_DoThinning(BYTE * p_prev_mod_line, BYTE * p_curr_mod_line);
int CL_DoStep(BYTE * p_prev_mod_line, BYTE * p_curr_mod_line, int (*step_check_func) (BYTE *));
int CL_DoVectorize(HTREE node_pnts_htree, CLinkHead * p_node_pnts_list);
int CL_FindStartPoint(int yy_start, CPoint * p_imgp);
void CL_GetNextPoint(CPoint * p_start_imgp, int direction, CPoint * p_imgp);
int CL_TracePoint( int curr_direction, HTREE node_pnts_htree, vect_poly * p_vect_poly,
CPoint * p_imgp, int *p_poly_flushed_flag );
vect_poly* CL_CreateVectPoly(CPoint * p_imgp);
void CL_FreeVectPoly(vect_poly * p_vect_poly);
int CL_AddVectPolyPoint(vect_poly * p_vect_poly, CPoint * p_imgp);
int CL_GetImagePixel(int back_ground, int xx, int yy);
void CL_ClearImagePixel(int back_ground, int xx, int yy);
CHTree m_tree;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
protected://Êä³öÂÖÀªÏߣ¨Ë«Ïߣ©
int DL_NextLine(scan_data * p_scd);
int DL_ScanCurrentLine(scan_data * p_scd);
int DL_CreateNewPolyline(scan_data * p_scd, CPoint* p_img_pnt0, CPoint* p_img_pnt1);
int DL_RemovePolyline(scan_data * p_scd, polyline * p_polyline);
int DL_FlushAllPolylines(scan_data * p_scd);
int DL_ResyncPolylineLists(scan_data * p_scd);
int DL_AddLine(scan_data* p_scd, CPoint* p_img_pnt0, CPoint* p_img_pnt1);
int DL_AddPointInPoly(polyline * p_ins_polyline, CPoint * p_imgp, int insert_location);
int DL_AddPolyGate(scan_data * p_scd, int gate, polyline * p_polyline);
int DL_RemovePolyGate(scan_data * p_scd, int gate, polyline * p_polyline);
int DL_TryToJoinPolylines(scan_data * p_scd, polyline * p_owner_polyline, CPoint * p_join_pnt, int pnt_location);
int DL_TransferPolylinePoints(polyline * p_dest_polyline, polyline * p_src_polyline, int insert_location, int direction);
int DL_GetInsertInfo(scan_data * p_scd, CPoint * p_img_pnt0, CPoint * p_img_pnt1, ins_polyline * p_iply);
int DL_GetInsertLink( CLinkHead* p_gating_poly_list, CPoint* p_img_pnt0, CPoint* p_img_pnt1, ins_polyline * p_iply);
};
};
extern CLinkList m_link;