X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fpdf%2Fbbox.c;h=ac7285cc41543eb6ecb95a008624769a7f3e4b2c;hb=HEAD;hp=226d1bbbab124fd6c47c5827b23157ae22b656d4;hpb=c10fb05b68fa1c717ef7d62d84bfb29008d41c33;p=swftools.git diff --git a/lib/pdf/bbox.c b/lib/pdf/bbox.c index 226d1bb..ac7285c 100644 --- a/lib/pdf/bbox.c +++ b/lib/pdf/bbox.c @@ -30,7 +30,7 @@ void ibbox_destroy(ibbox_t*b) } } -ibbox_t*get_bitmap_bboxes_simple(unsigned char*alpha, int width, int height) +ibbox_t*get_bitmap_bboxes_simple(unsigned char*alpha, int width, int height, int rowsize) { int ymin = -1; int ymax = -1; @@ -39,7 +39,7 @@ ibbox_t*get_bitmap_bboxes_simple(unsigned char*alpha, int width, int height) int x,y; for(y=0;yprev); context->heads = h->next; } + free(h); } #define POINTS_TO_HEAD(ptr) (((head_t*)(ptr))->magic==HEAD_MAGIC) @@ -192,6 +194,21 @@ static inline void merge(context_t*context, int set1, int set2) } } +ibbox_t ibbox_clip(ibbox_t* outer, ibbox_t* inner) +{ + ibbox_t i = {inner->xmin, inner->ymin, inner->xmax, inner->ymax, 0}; + if(i.xmax > outer->xmax) i.xmax = outer->xmax; + if(i.ymax > outer->ymax) i.ymax = outer->ymax; + if(i.xmax < outer->xmin) i.xmax = outer->xmin; + if(i.ymax < outer->ymin) i.ymax = outer->ymin; + + if(i.xmin > outer->xmax) i.xmin = outer->xmax; + if(i.ymin > outer->ymax) i.ymin = outer->ymax; + if(i.xmin < outer->xmin) i.xmin = outer->xmin; + if(i.ymin < outer->ymin) i.ymin = outer->ymin; + return i; +} + static void** annotate(context_t*context) { unsigned char*alpha = context->alpha; @@ -210,9 +227,11 @@ static void** annotate(context_t*context) } } int pos = 0; + int apos = 0; for(y=1;yrowsize; + if(alpha[apos]) { if(group[pos-width]) link_to(context,pos,pos-width); else @@ -222,7 +241,7 @@ static void** annotate(context_t*context) /* once this code is stable we should copy&paste it out of the loop, change the loop end to width-1 and add the pos-width+1 case */ - if(alpha[pos+x]) { + if(alpha[apos+x]) { if(group[pos+x-width]) { link_to(context,pos+x,pos+x-width); if(group[pos+x-1]) @@ -264,17 +283,49 @@ static void overlap_bboxes(context_t*context) } while(changed); } +typedef struct _circle_coord { + S16 x,y; +} circle_coord_t; + +static int compare_circle_coord(const void *_v1, const void *_v2) +{ + circle_coord_t*v1=(circle_coord_t*)_v1; + circle_coord_t*v2=(circle_coord_t*)_v2; + return (v1->x*v1->x + v1->y*v1->y) - (v2->x*v2->x + v2->y*v2->y); +} + static head_t* search_vicinity(context_t*context, head_t*h, int max_radius, double*cos, double*sin) { + static circle_coord_t*circle_order = 0; + static int circle_order_size = 0; + + if(!circle_order) { + circle_order_size = (max_radius*(max_radius+1))/2; + circle_order = malloc(sizeof(circle_coord_t)*circle_order_size); + int x,y; + int i = 0; + for(y=0;ygroup; - /* FIXME: this function isn't very efficient. We need a better way to iterate - through all points, sorted by distance, in the neighborhood of a coordinate */ - for(t=3;tx+cos[s]*t/4.0+0.5; - int y=h->y+sin[s]*t/4.0+0.5; + for(s=0;s<4;s++) { + int x=h->x+xx*signx[s]; + int y=h->y+yy*signy[s]; if(x>=0 && y>=0 && xwidth && yheight) { int pos = y*context->width+x; if(data[pos]) { @@ -315,17 +366,26 @@ static void fix_small_boxes(context_t*context) while(h) { head_t*next = h->next; if(!h->seen) { - if(h->bbox.xmax - h->bbox.ymin < 16 - && h->bbox.ymax - h->bbox.ymin < 16) { + if(h->bbox.xmax - h->bbox.xmin < 32 + || h->bbox.ymax - h->bbox.ymin < 32) { head_t*other = search_vicinity(context, h, 64, costab, sintab); if(other) { merge(context, h->pos, other->pos); changed = 1; break; } else { + //printf("nothing in the vicinity of %d,%d,%d,%d\n", h->bbox); h->seen = 1; } - } + } /*else { + printf("area %d,%d,%d,%d is large enough (%dx%d)\n", + h->bbox.xmin, + h->bbox.ymin, + h->bbox.xmax, + h->bbox.ymax, + h->bbox.xmax - h->bbox.xmin, + h->bbox.ymax - h->bbox.ymin); + } */ } h = next; } @@ -361,14 +421,15 @@ static void display(context_t*context) } } -ibbox_t*get_bitmap_bboxes(unsigned char*alpha, int width, int height) +ibbox_t*get_bitmap_bboxes(unsigned char*alpha, int width, int height, int rowsize) { int size = width*height; if(width<=1 || height<=1) - return get_bitmap_bboxes_simple(alpha, width, height); + return get_bitmap_bboxes_simple(alpha, width, height, rowsize); context_t context; context.alpha = alpha; + context.rowsize = rowsize; context.width = width; context.height = height; context.heads = 0; @@ -377,6 +438,9 @@ ibbox_t*get_bitmap_bboxes(unsigned char*alpha, int width, int height) void**group = annotate(&context); fix_small_boxes(&context); overlap_bboxes(&context); +#ifdef MAIN + display(&context); +#endif ibbox_t*bboxes = 0; @@ -412,6 +476,6 @@ int main(int argn, char*argv[]) "\1\0\0\0\0\0\1\0" "\1\1\1\0\0\0\0\0"; - get_bitmap_bboxes(alpha, 8,8); + get_bitmap_bboxes(alpha, 8,8, 8); } #endif