📄 filescan.c
字号:
/*
* Ras2Vec by Davide Libenzi ( Raster to vector conversion program )
* Copyright (C) 1999 Davide Libenzi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@maticad.it>
*
*/
#include<windows.h>
#include<windowsx.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#include<math.h>
#include<float.h>
#include<limits.h>
#include"ras2vec.h"
#include"dbll_list.h"
#include"himage.h"
#include"thinner.h"
#include"flushpoly.h"
#include"filescan.h"
#include"log.h"
#include"util.h"
#define RESYNC_FREQUENCY 32
#define DELETED_POLYLINE ((void *)(-1))
typedef struct ins_polyline_record
{
int insert_location;
img_point link_pnt,
pnt;
polyline *p_polyline;
} ins_polyline;
typedef struct scan_data_record
{
int x_size,
y_size;
int img_line_size,
line_size;
int current_line;
int back_ground;
double pnt_error_tollerance,
min_polyline_lenght;
img_data imgd;
BYTE *p_img_mem,
*p_raw_ptr;
BYTE *p_lines,
*p_line,
*p_next_line,
*p_nnext_line;
BYTE *v_open;
FILE *fp_poly;
link_list_hdr *p_polylines_list;
link_list_hdr **pp_gating_polylines;
int number_of_polylines;
} scan_data;
static int add_point_in_poly(polyline * p_ins_polyline, img_point * p_imgp,
int insert_location);
static BYTE *tx_bits_mem(BYTE * p_line, int x_size, BYTE * p_bits, int back_ground);
static scan_data *alloc_scan_data(char *img_file_name, char *poly_file_name,
double pnt_error_tollerance,
double poly_lenght_factor);
static int free_scan_data(scan_data * p_scd);
static int add_poly_gate(scan_data * p_scd, int gate, polyline * p_polyline);
static int remove_poly_gate(scan_data * p_scd, int gate, polyline * p_polyline);
static int try_to_join_polylines(scan_data * p_scd, polyline * p_owner_polyline,
img_point * p_join_pnt, int pnt_location);
static int add_line(scan_data * p_scd, img_point * p_img_pnt0,
img_point * p_img_pnt1);
static int get_insert_link(link_list_hdr * p_gating_poly_list,
img_point * p_img_pnt0, img_point * p_img_pnt1,
ins_polyline * p_iply);
static int get_insert_info(scan_data * p_scd, img_point * p_img_pnt0,
img_point * p_img_pnt1, ins_polyline * p_iply);
static int create_new_polyline(scan_data * p_scd, img_point * p_img_pnt0,
img_point * p_img_pnt1);
static int remove_polyline(scan_data * p_scd, polyline * p_polyline);
static int transfer_polyline_points(polyline * p_dest_polyline,
polyline * p_src_polyline, int insert_location,
int direction);
static int resync_polyline_lists(scan_data * p_scd);
static int flush_all_polylines(scan_data * p_scd);
static int next_line(scan_data * p_scd);
static int scan_current_line(scan_data * p_scd);
/* OK */
static int add_point_in_poly(polyline * p_ins_polyline, img_point * p_imgp,
int insert_location)
{
switch (insert_location)
{
case (TG_HEAD):
{
if ((p_ins_polyline->prev_pnt0.x == p_ins_polyline->pnt0.x) &&
(p_ins_polyline->pnt0.x == p_imgp->x))
{
p_ins_polyline->last_pnt0 = p_ins_polyline->pnt0;
if (!ll_set_list_user_data(p_ins_polyline->p_poly_list, (link_loc) insert_location,
p_imgp))
return (FALSE);
p_ins_polyline->pnt0 = *p_imgp;
}
else
{
if ((p_ins_polyline->prev_pnt0.y == p_ins_polyline->pnt0.y) &&
(p_ins_polyline->pnt0.y == p_imgp->y))
{
p_ins_polyline->last_pnt0 = p_ins_polyline->pnt0;
if (!ll_set_list_user_data(p_ins_polyline->p_poly_list, (link_loc) insert_location,
p_imgp))
return (FALSE);
p_ins_polyline->pnt0 = *p_imgp;
}
else
{
if (!ll_add_list_data(p_ins_polyline->p_poly_list, insert_location, p_imgp))
return (FALSE);
p_ins_polyline->prev_pnt0 = p_ins_polyline->last_pnt0 = p_ins_polyline->pnt0;
p_ins_polyline->pnt0 = *p_imgp;
}
}
}
break;
case (TG_TAIL):
{
if ((p_ins_polyline->prev_pnt1.x == p_ins_polyline->pnt1.x) &&
(p_ins_polyline->pnt1.x == p_imgp->x))
{
p_ins_polyline->last_pnt1 = p_ins_polyline->pnt1;
if (!ll_set_list_user_data(p_ins_polyline->p_poly_list, (link_loc) insert_location,
p_imgp))
return (FALSE);
p_ins_polyline->pnt1 = *p_imgp;
}
else
{
if ((p_ins_polyline->prev_pnt1.y == p_ins_polyline->pnt1.y) &&
(p_ins_polyline->pnt1.y == p_imgp->y))
{
p_ins_polyline->last_pnt1 = p_ins_polyline->pnt1;
if (!ll_set_list_user_data(p_ins_polyline->p_poly_list, (link_loc) insert_location,
p_imgp))
return (FALSE);
p_ins_polyline->pnt1 = *p_imgp;
}
else
{
if (!ll_add_list_data(p_ins_polyline->p_poly_list, insert_location, p_imgp))
return (FALSE);
p_ins_polyline->prev_pnt1 = p_ins_polyline->last_pnt1 = p_ins_polyline->pnt1;
p_ins_polyline->pnt1 = *p_imgp;
}
}
}
break;
default:
return (FALSE);
}
return (TRUE);
}
/* OK */
static BYTE *tx_bits_mem(BYTE * p_line, int x_size, BYTE * p_bits, int back_ground)
{
int ii,
bit = 7;
register BYTE curr_byte = *p_bits;
static BYTE bits[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
memset(p_line, 0, x_size + 2);
if (back_ground != 0)
{
for (ii = 0; ii < x_size; ii++)
{
if (!(curr_byte & bits[bit]))
p_line[ii + 1] = 1;
if ((--bit) < 0)
{
DWORD *p_dw_bits = (DWORD *)++ p_bits;
bit = 7;
while ((ii < x_size) && (*p_dw_bits == 0xffffffff))
++p_dw_bits, ii += 32;
p_bits = (BYTE *) p_dw_bits;
if (ii < x_size)
curr_byte = *p_bits;
}
}
}
else
{
for (ii = 0; ii < x_size; ii++)
{
if (curr_byte & bits[bit])
p_line[ii + 1] = 1;
if ((--bit) < 0)
{
DWORD *p_dw_bits = (DWORD *)++ p_bits;
bit = 7;
while ((ii < x_size) && (*p_dw_bits == 0x00000000))
++p_dw_bits, ii += 32;
p_bits = (BYTE *) p_dw_bits;
if (ii < x_size)
curr_byte = *p_bits;
}
}
}
return (p_line);
}
/* OK */
static scan_data *alloc_scan_data(char *img_file_name, char *poly_file_name,
double pnt_error_tollerance,
double poly_lenght_factor)
{
int ii;
scan_data *p_scd;
BYTE *p_img_line;
bw_bmp_header bmph;
if ((p_scd = (scan_data *) malloc(sizeof(scan_data))) == NULL)
return (NULL);
memset(p_scd, 0, sizeof(scan_data));
if ((p_scd->p_img_mem = (BYTE *) get_image(img_file_name, IMAGE_OPEN_READ,
&p_scd->imgd)) == NULL)
{
free(p_scd);
return (NULL);
}
bmph = *((bw_bmp_header *) p_scd->p_img_mem);
if ((bmph.bfh.bfType != *((WORD *) "BM")) ||
(bmph.bih.biSize != sizeof(BITMAPINFOHEADER)) ||
(bmph.bih.biCompression != BI_RGB) || (bmph.bih.biBitCount != 1) ||
(bmph.bih.biPlanes != 1) || (bmph.bih.biClrUsed != 2))
{
free_image(&p_scd->imgd);
free(p_scd);
return (NULL);
}
p_scd->p_raw_ptr = bmp_get_raw_ptr(p_scd->p_img_mem);
p_scd->x_size = bmph.bih.biWidth;
p_scd->y_size = bmph.bih.biHeight;
p_scd->back_ground = bmp_file_get_background(&bmph, p_scd->p_img_mem, 100, 100);
p_scd->pnt_error_tollerance = pnt_error_tollerance;
p_scd->min_polyline_lenght = (poly_lenght_factor > 0.0) ?
(((double) max(p_scd->x_size, p_scd->y_size)) / poly_lenght_factor) : 1.0;
p_scd->line_size = p_scd->x_size + 2;
p_scd->img_line_size = get_line_size(p_scd->x_size);
if ((p_scd->p_lines = (BYTE *) malloc(3 * p_scd->line_size)) == NULL)
{
free_image(&p_scd->imgd);
free(p_scd);
return (NULL);
}
memset(p_scd->p_lines, 0, 3 * p_scd->line_size);
p_scd->p_line = p_scd->p_lines;
p_scd->p_next_line = p_scd->p_line + p_scd->line_size;
p_scd->p_nnext_line = p_scd->p_next_line + p_scd->line_size;
if ((p_scd->v_open = (BYTE *) malloc(p_scd->line_size)) == NULL)
{
free(p_scd->p_lines);
free_image(&p_scd->imgd);
free(p_scd);
return (NULL);
}
memset(p_scd->v_open, 0, p_scd->line_size);
p_img_line = get_raw_img_line(p_scd->p_raw_ptr, p_scd->img_line_size, 0);
tx_bits_mem(p_scd->p_next_line, p_scd->x_size, p_img_line, p_scd->back_ground);
if (p_scd->y_size > 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -