From 441d06166417c65be90a7e11d995656ee1ddd385 Mon Sep 17 00:00:00 2001 From: chrox Date: Fri, 19 Oct 2012 01:20:48 +0800 Subject: [PATCH] add DJVU reflow Conflicts: djvu.c koptreader.lua reader.lua --- Makefile | 2 +- djvu.c | 60 ++++++++++++++++++++++++----- k2pdfopt.c | 108 ++++++++++++++++++++++++++++++++++++++++++----------- k2pdfopt.h | 9 +++-- pdf.c | 7 ++-- 5 files changed, 146 insertions(+), 40 deletions(-) diff --git a/Makefile b/Makefile index 9f2c372fd..b911d4c86 100644 --- a/Makefile +++ b/Makefile @@ -157,7 +157,7 @@ kpdfview.o pdf.o blitbuffer.o util.o drawcontext.o einkfb.o input.o mupdfimg.o: $(CC) -c $(KPDFREADER_CFLAGS) $(EMU_CFLAGS) -I$(LFSDIR)/src $< -o $@ k2pdfopt.o: %.o: %.c - $(CC) -c -I$(MUPDFDIR)/ $(CFLAGS) $< -o $@ + $(CC) -c -I$(MUPDFDIR)/ -I$(DJVUDIR)/ $(CFLAGS) $< -o $@ djvu.o: %.o: %.c $(CC) -c $(KPDFREADER_CFLAGS) -I$(DJVUDIR)/ $< -o $@ diff --git a/djvu.c b/djvu.c index c2ba5a5ca..535e366fe 100644 --- a/djvu.c +++ b/djvu.c @@ -470,16 +470,54 @@ static int closePage(lua_State *L) { return 0; } -/* draw part of the page to bb. - * - * @page: DjvuPage user data - * @dc: DrawContext user data - * @bb: BlitBuffer user data - * @x: x offset within zoomed page - * @y: y offset within zoomed page - * - * width and height for the visible_area is obtained from bb. - */ +static int reflowPage(lua_State *L) { + + DjvuPage *page = (DjvuPage*) luaL_checkudata(L, 1, "djvupage"); + DrawContext *dc = (DrawContext*) luaL_checkudata(L, 2, "drawcontext"); + ddjvu_render_mode_t mode = (int) luaL_checkint(L, 3); + + double dpi = 250*(dc->zoom); + + int width, height; + k2pdfopt_djvu_reflow(page->page_ref, page->doc->context, mode, page->doc->pixelformat, dpi); + k2pdfopt_rfbmp_size(&width, &height); + + lua_pushnumber(L, (double)width); + lua_pushnumber(L, (double)height); + + return 2; +} + +static int drawReflowedPage(lua_State *L) { + uint8_t *pmptr = NULL; + + DjvuPage *page = (DjvuPage*) luaL_checkudata(L, 1, "djvupage"); + DrawContext *dc = (DrawContext*) luaL_checkudata(L, 2, "drawcontext"); + BlitBuffer *bb = (BlitBuffer*) luaL_checkudata(L, 3, "blitbuffer"); + + uint8_t *bbptr = bb->data; + k2pdfopt_rfbmp_ptr(&pmptr); + + int x_offset = 0; + int y_offset = 0; + + bbptr += bb->pitch * y_offset; + int x, y; + for(y = y_offset; y < bb->h; y++) { + for(x = x_offset/2; x < (bb->w/2); x++) { + int p = x*2 - x_offset; + bbptr[x] = (((pmptr[p + 1] & 0xF0) >> 4) | (pmptr[p] & 0xF0)) ^ 0xFF; + } + bbptr += bb->pitch; + pmptr += bb->w; + if (bb->w & 1) { + bbptr[x] = 255 - (pmptr[x*2] & 0xF0); + } + } + + return 0; +} + static int drawPage(lua_State *L) { DjvuPage *page = (DjvuPage*) luaL_checkudata(L, 1, "djvupage"); DrawContext *dc = (DrawContext*) luaL_checkudata(L, 2, "drawcontext"); @@ -605,6 +643,8 @@ static const struct luaL_Reg djvupage_meth[] = { {"getUsedBBox", getUsedBBox}, {"close", closePage}, {"__gc", closePage}, + {"reflow", reflowPage}, + {"rfdraw", drawReflowedPage}, {"draw", drawPage}, {NULL, NULL} }; diff --git a/k2pdfopt.c b/k2pdfopt.c index d982d6f9f..aff875d4c 100644 --- a/k2pdfopt.c +++ b/k2pdfopt.c @@ -30,13 +30,13 @@ */ // #define WILLUSDEBUGX 32 // #define WILLUSDEBUG -#include "k2pdfopt.h" #include #include #include #include #include #include +#include "k2pdfopt.h" #define HAVE_MUPDF @@ -408,43 +408,33 @@ static void bmp_contrast_adjust(WILLUSBITMAP *dest,WILLUSBITMAP *src,double cont static void bmp_convert_to_greyscale_ex(WILLUSBITMAP *dst, WILLUSBITMAP *src); static int bmpmupdf_pixmap_to_bmp(WILLUSBITMAP *bmp, fz_context *ctx, fz_pixmap *pixmap); +static void handle(int wait, ddjvu_context_t *ctx); static MASTERINFO _masterinfo, *masterinfo; -static WILLUSBITMAP _bmp, *bmp; static int master_bmp_inited = 0; static int master_bmp_width = 0; static int master_bmp_height = 0; -void k2pdfopt_mupdf_reflow_bmp(fz_context *ctx, fz_pixmap *pix, double rot_deg) { +static void k2pdfopt_reflow_bmp(MASTERINFO *masterinfo, WILLUSBITMAP *src) { PAGEINFO _pageinfo, *pageinfo; - WILLUSBITMAP _src, *src; WILLUSBITMAP _srcgrey, *srcgrey; - int i, status, white, pw, np, src_type, or_detect, orep_detect, - second_time_through; - int pagecount, pagestep, pages_done, is_gray, dpi; - double size, area_ratio, bormean; + int i, white, dpi; + double area_ratio; - masterinfo = &_masterinfo; masterinfo->debugfolder[0] = '\0'; - second_time_through = 0; white = src_whitethresh; /* Will be set by adjust_contrast() or set to src_whitethresh */ dpi = src_dpi; adjust_params_init(); set_region_widths(); - bmp = &_bmp; - src = &_src; srcgrey = &_srcgrey; - if (master_bmp_inited == 0) { bmp_init(&masterinfo->bmp); master_bmp_inited = 1; } - // free last used master bmp - bmp_free(&masterinfo->bmp); + bmp_free(&masterinfo->bmp); bmp_init(&masterinfo->bmp); - bmp_init(src); bmp_init(srcgrey); wrapbmp_init(); @@ -462,8 +452,6 @@ void k2pdfopt_mupdf_reflow_bmp(fz_context *ctx, fz_pixmap *pix, double rot_deg) bmp_fill(&masterinfo->bmp, 255, 255, 255); BMPREGION region; - - status = bmpmupdf_pixmap_to_bmp(src, ctx, pix); bmp_copy(srcgrey, src); adjust_contrast(src, srcgrey, &white); white_margins(src, srcgrey); @@ -479,22 +467,72 @@ void k2pdfopt_mupdf_reflow_bmp(fz_context *ctx, fz_pixmap *pix, double rot_deg) masterinfo->bgcolor = white; masterinfo->fit_to_page = dst_fit_to_page; /* Check to see if master bitmap might need more room */ - bmpregion_multicolumn_add(®ion, masterinfo, 1, pageinfo, - pages_done == 0. ? 0. : (int) (0.25 * src_dpi + .5)); + bmpregion_multicolumn_add(®ion, masterinfo, 1, pageinfo, (int) (0.25 * src_dpi + .5)); master_bmp_width = masterinfo->bmp.width; master_bmp_height = masterinfo->rows; bmp_free(srcgrey); +} + +void k2pdfopt_mupdf_reflow(fz_context *ctx, fz_pixmap *pix, double rot_deg) { + WILLUSBITMAP _src, *src; + src = &_src; + masterinfo = &_masterinfo; + bmp_init(src); + int status = bmpmupdf_pixmap_to_bmp(src, ctx, pix); + k2pdfopt_reflow_bmp(masterinfo, src); + bmp_free(src); +} + +void k2pdfopt_djvu_reflow(ddjvu_page_t *page, ddjvu_context_t *ctx, \ + ddjvu_render_mode_t mode, ddjvu_format_t *fmt, double dpi) { + WILLUSBITMAP _src, *src; + ddjvu_rect_t prect; + ddjvu_rect_t rrect; + int i, iw, ih, idpi, status; + + while (!ddjvu_page_decoding_done(page)) + handle(1, ctx); + + iw = ddjvu_page_get_width(page); + ih = ddjvu_page_get_height(page); + idpi = ddjvu_page_get_resolution(page); + prect.x = prect.y = 0; + prect.w = iw * dpi / idpi; + prect.h = ih * dpi / idpi; + rrect = prect; + + src = &_src; + masterinfo = &_masterinfo; + bmp_init(src); + + src->width = prect.w = iw * dpi / idpi; + src->height = prect.h = ih * dpi / idpi; + src->bpp = 8; + rrect = prect; + bmp_alloc(src); + if (src->bpp == 8) { + int ii; + for (ii = 0; ii < 256; ii++) + src->red[ii] = src->blue[ii] = src->green[ii] = ii; + } + + ddjvu_format_set_row_order(fmt, 1); + + status = ddjvu_page_render(page, mode, &prect, &rrect, fmt, + bmp_bytewidth(src), (char *) src->data); + + k2pdfopt_reflow_bmp(masterinfo, src); bmp_free(src); } -void k2pdfopt_mupdf_rfbmp_size(int *width, int *height) { +void k2pdfopt_rfbmp_size(int *width, int *height) { *width = master_bmp_width; *height = master_bmp_height; } -void k2pdfopt_mupdf_rfbmp_ptr(unsigned char** bmp_ptr_ptr) { +void k2pdfopt_rfbmp_ptr(unsigned char** bmp_ptr_ptr) { *bmp_ptr_ptr = masterinfo->bmp.data; } @@ -6336,3 +6374,29 @@ static int bmpmupdf_pixmap_to_bmp(WILLUSBITMAP *bmp, fz_context *ctx, } return (0); } + +static void handle(int wait, ddjvu_context_t *ctx) + { + const ddjvu_message_t *msg; + + if (!ctx) + return; + if (wait) + msg = ddjvu_message_wait(ctx); + while ((msg = ddjvu_message_peek(ctx))) + { + switch(msg->m_any.tag) + { + case DDJVU_ERROR: + fprintf(stderr,"ddjvu: %s\n", msg->m_error.message); + if (msg->m_error.filename) + fprintf(stderr,"ddjvu: '%s:%d'\n", + msg->m_error.filename, msg->m_error.lineno); + exit(10); + default: + break; + } + } + ddjvu_message_pop(ctx); +} + diff --git a/k2pdfopt.h b/k2pdfopt.h index 6067ff165..ae46de0ed 100644 --- a/k2pdfopt.h +++ b/k2pdfopt.h @@ -24,10 +24,13 @@ #define _K2PDFOPT_H #include +#include -void k2pdfopt_mupdf_reflow_bmp(fz_context *ctx, fz_pixmap *pix, double rot_deg); -void k2pdfopt_mupdf_rfbmp_size(int *width, int *height); -void k2pdfopt_mupdf_rfbmp_ptr(unsigned char** bmp_ptr_ptr); +void k2pdfopt_mupdf_reflow(fz_context *ctx, fz_pixmap *pix, double rot_deg); +void k2pdfopt_djvu_reflow(ddjvu_page_t *page, ddjvu_context_t *ctx, \ + ddjvu_render_mode_t mode, ddjvu_format_t *fmt, double dpi); +void k2pdfopt_rfbmp_size(int *width, int *height); +void k2pdfopt_rfbmp_ptr(unsigned char** bmp_ptr_ptr); #endif diff --git a/pdf.c b/pdf.c index ea6981758..314ce1c83 100644 --- a/pdf.c +++ b/pdf.c @@ -20,7 +20,6 @@ #include "blitbuffer.h" #include "drawcontext.h" #include "pdf.h" -#include "k2pdfopt.h" #include #include #include @@ -560,8 +559,8 @@ static int reflowPage(lua_State *L) { fz_gamma_pixmap(page->doc->context, pix, dc->gamma); } int width, height; - k2pdfopt_mupdf_reflow_bmp(page->doc->context, pix, 0); - k2pdfopt_mupdf_rfbmp_size(&width, &height); + k2pdfopt_mupdf_reflow(page->doc->context, pix, 0); + k2pdfopt_rfbmp_size(&width, &height); lua_pushnumber(L, (double)width); lua_pushnumber(L, (double)height); @@ -579,7 +578,7 @@ static int drawReflowedPage(lua_State *L) { BlitBuffer *bb = (BlitBuffer*) luaL_checkudata(L, 3, "blitbuffer"); uint8_t *bbptr = bb->data; - k2pdfopt_mupdf_rfbmp_ptr(&pmptr); + k2pdfopt_rfbmp_ptr(&pmptr); int x_offset = 0; int y_offset = 0;