From 3bf6a6c26f5dda79b6de3b236c9867fcf6a3f17b Mon Sep 17 00:00:00 2001 From: Matthias Kramm <kramm@quiss.org> Date: Tue, 8 Jun 2010 13:01:12 -0700 Subject: [PATCH] reduced memory requirements for Illustrator files --- lib/pdf/BitmapOutputDev.cc | 27 +++++++++++++++------------ lib/pdf/bbox.c | 33 ++++++++++++++++++++++++++------- lib/pdf/bbox.h | 6 ++++-- 3 files changed, 45 insertions(+), 21 deletions(-) diff --git a/lib/pdf/BitmapOutputDev.cc b/lib/pdf/BitmapOutputDev.cc index d54c8ea..a858765 100644 --- a/lib/pdf/BitmapOutputDev.cc +++ b/lib/pdf/BitmapOutputDev.cc @@ -174,8 +174,8 @@ static int dbg_btm_counter=1; void BitmapOutputDev::flushBitmap() { - int width = rgbdev->getBitmapWidth(); - int height = rgbdev->getBitmapHeight(); + int bitmap_width = rgbdev->getBitmapWidth(); + int bitmap_height = rgbdev->getBitmapHeight(); if(sizeof(SplashColor)!=3) { msg("<error> sizeof(SplashColor)!=3"); @@ -196,7 +196,7 @@ void BitmapOutputDev::flushBitmap() Guchar*alpha = rgbbitmap->getAlphaPtr(); Guchar*alpha2 = stalepolybitmap->getDataPtr(); - int width8 = (stalepolybitmap->getWidth()+7)/8; + int bitmap_width8 = (stalepolybitmap->getWidth()+7)/8; /*char filename[80]; sprintf(filename, "flush%d_mask.png", dbg_btm_counter); @@ -206,14 +206,17 @@ void BitmapOutputDev::flushBitmap() sprintf(filename, "flush%d_bitmap.png", dbg_btm_counter); writeBitmap(rgbbitmap, filename);*/ - ibbox_t* boxes = get_bitmap_bboxes((unsigned char*)alpha, width, height); - ibbox_t*b; + ibbox_t pagebox = {-movex, -movey, -movex + this->width, -movey + this->height, 0}; + ibbox_t bitmapbox = {0, 0, bitmap_width, bitmap_height, 0}; + ibbox_t c = ibbox_clip(&bitmapbox, &pagebox); + ibbox_t* boxes = get_bitmap_bboxes((unsigned char*)(alpha+c.ymin*bitmap_width+c.xmin), c.xmax - c.xmin, c.ymax - c.ymin, bitmap_width); + ibbox_t*b; for(b=boxes;b;b=b->next) { - int xmin = b->xmin; - int ymin = b->ymin; - int xmax = b->xmax; - int ymax = b->ymax; + int xmin = b->xmin - this->movex; + int ymin = b->ymin - this->movey; + int xmax = b->xmax - this->movex; + int ymax = b->ymax - this->movey; /* clip against (-movex, -movey, -movex+width, -movey+height) */ @@ -248,10 +251,10 @@ void BitmapOutputDev::flushBitmap() img->height = rangey; int x,y; for(y=0;y<rangey;y++) { - SplashColorPtr in=&rgb[((y+ymin)*width+xmin)*sizeof(SplashColor)]; + SplashColorPtr in=&rgb[((y+ymin)*bitmap_width+xmin)*sizeof(SplashColor)]; gfxcolor_t*out = &img->data[y*rangex]; - Guchar*ain = &alpha[(y+ymin)*width+xmin]; - Guchar*ain2 = &alpha2[(y+ymin)*width8]; + Guchar*ain = &alpha[(y+ymin)*bitmap_width+xmin]; + Guchar*ain2 = &alpha2[(y+ymin)*bitmap_width8]; if(this->emptypage) { for(x=0;x<rangex;x++) { /* the first bitmap on the page doesn't need to have an alpha channel- diff --git a/lib/pdf/bbox.c b/lib/pdf/bbox.c index 1f24567..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;y<height;y++) { - unsigned char*a = &alpha[y*width]; + unsigned char*a = &alpha[y*rowsize]; for(x=0;x<width;x++) { if(a[x]) break; } @@ -79,6 +79,7 @@ typedef struct _head { typedef struct _context { void**group; unsigned char*alpha; + int rowsize; int width; int height; head_t*heads; @@ -193,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; @@ -211,9 +227,11 @@ static void** annotate(context_t*context) } } int pos = 0; + int apos = 0; for(y=1;y<height;y++) { pos += width; - if(alpha[pos]) { + apos += context->rowsize; + if(alpha[apos]) { if(group[pos-width]) link_to(context,pos,pos-width); else @@ -223,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]) @@ -403,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; @@ -457,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 diff --git a/lib/pdf/bbox.h b/lib/pdf/bbox.h index 25675c8..8ee9487 100644 --- a/lib/pdf/bbox.h +++ b/lib/pdf/bbox.h @@ -10,9 +10,11 @@ typedef struct _ibbox { struct _ibbox*next; } ibbox_t; -ibbox_t* ibbox_new(int x1, int y1, int x2, int y2); +ibbox_t ibbox_clip(ibbox_t* outer, ibbox_t* inner); + +ibbox_t* ibbox_new(int x1, int y1, int x2, int y2, int rowsize); void ibbox_destroy(ibbox_t*b); -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); #ifdef __cplusplus } -- 1.7.10.4