diff --git a/djvu.c b/djvu.c index 4d6dcd7a5..7772c41f1 100644 --- a/djvu.c +++ b/djvu.c @@ -31,6 +31,7 @@ typedef struct DjvuDocument { ddjvu_context_t *context; ddjvu_document_t *doc_ref; + ddjvu_format_t *pixelformat; } DjvuDocument; typedef struct DjvuPage { @@ -92,6 +93,14 @@ static int openDocument(lua_State *L) { return luaL_error(L, "cannot open DJVU file <%s>", filename); } + doc->pixelformat = ddjvu_format_create(DDJVU_FORMAT_GREY8, 0, NULL); + if (! doc->pixelformat) { + return luaL_error(L, "cannot create DJVU pixelformat for <%s>", filename); + } + ddjvu_format_set_row_order(doc->pixelformat, 1); + ddjvu_format_set_y_direction(doc->pixelformat, 1); + ddjvu_format_set_ditherbits(doc->pixelformat, 4); + return 1; } @@ -99,14 +108,18 @@ static int closeDocument(lua_State *L) { DjvuDocument *doc = (DjvuDocument*) luaL_checkudata(L, 1, "djvudocument"); // should be save if called twice - if(doc->doc_ref != NULL) { + if (doc->doc_ref != NULL) { ddjvu_document_release(doc->doc_ref); doc->doc_ref = NULL; } - if(doc->context != NULL) { + if (doc->context != NULL) { ddjvu_context_release(doc->context); doc->context = NULL; } + if (doc->pixelformat != NULL) { + ddjvu_format_release(doc->pixelformat); + doc->pixelformat = NULL; + } return 0; } @@ -178,7 +191,7 @@ static int openPage(lua_State *L) { DjvuDocument *doc = (DjvuDocument*) luaL_checkudata(L, 1, "djvudocument"); int pageno = luaL_checkint(L, 2); - if(pageno < 1 || pageno > ddjvu_document_get_pagenum(doc->doc_ref)) { + if (pageno < 1 || pageno > ddjvu_document_get_pagenum(doc->doc_ref)) { return luaL_error(L, "cannot open page #%d, out of range (1-%d)", pageno, ddjvu_document_get_pagenum(doc->doc_ref)); } @@ -190,7 +203,7 @@ static int openPage(lua_State *L) { page->page_ref = ddjvu_page_create_by_pageno(doc->doc_ref, pageno - 1); while (! ddjvu_page_decoding_done(page->page_ref)) handle(L, doc->context, TRUE); - if(! page->page_ref) { + if (! page->page_ref) { return luaL_error(L, "cannot open page #%d", pageno); } @@ -230,6 +243,23 @@ static int getUsedBBox(lua_State *L) { return 4; } +static int getOriginalPageSize(lua_State *L) { + DjvuDocument *doc = (DjvuDocument*) luaL_checkudata(L, 1, "djvudocument"); + int pageno = luaL_checkint(L, 2); + + ddjvu_status_t r; + ddjvu_pageinfo_t info; + + while ((r=ddjvu_document_get_pageinfo( + doc->doc_ref, pageno-1, &info))context, TRUE); + } + + lua_pushnumber(L, info.width); + lua_pushnumber(L, info.height); + + return 2; +} /* * Return a table like following: @@ -255,6 +285,17 @@ static int getPageText(lua_State *L) { DjvuDocument *doc = (DjvuDocument*) luaL_checkudata(L, 1, "djvudocument"); int pageno = luaL_checkint(L, 2); + /* get page height for coordinates transform */ + ddjvu_pageinfo_t info; + ddjvu_status_t r; + while ((r=ddjvu_document_get_pageinfo( + doc->doc_ref, pageno-1, &info))context, TRUE); + } + if (r>=DDJVU_JOB_FAILED) + return luaL_error(L, "cannot get page #%d information", pageno); + + /* start retrieving page text */ miniexp_t sexp, se_line, se_word; int i = 1, j = 1, counter_l = 1, counter_w=1, nr_line = 0, nr_word = 0; @@ -278,7 +319,7 @@ static int getPageText(lua_State *L) { /* retrive one line entry */ se_line = miniexp_nth(i, sexp); nr_word = miniexp_length(se_line); - if(nr_word == 0) { + if (nr_word == 0) { continue; } @@ -292,16 +333,18 @@ static int getPageText(lua_State *L) { lua_pushnumber(L, miniexp_to_int(miniexp_nth(1, se_line))); lua_settable(L, -3); - lua_pushstring(L, "y0"); - lua_pushnumber(L, miniexp_to_int(miniexp_nth(2, se_line))); + lua_pushstring(L, "y1"); + lua_pushnumber(L, + info.height - miniexp_to_int(miniexp_nth(2, se_line))); lua_settable(L, -3); lua_pushstring(L, "x1"); lua_pushnumber(L, miniexp_to_int(miniexp_nth(3, se_line))); lua_settable(L, -3); - lua_pushstring(L, "y1"); - lua_pushnumber(L, miniexp_to_int(miniexp_nth(4, se_line))); + lua_pushstring(L, "y0"); + lua_pushnumber(L, + info.height - miniexp_to_int(miniexp_nth(4, se_line))); lua_settable(L, -3); /* now loop through each word in the line */ @@ -325,16 +368,18 @@ static int getPageText(lua_State *L) { lua_pushnumber(L, miniexp_to_int(miniexp_nth(1, se_word))); lua_settable(L, -3); - lua_pushstring(L, "y0"); - lua_pushnumber(L, miniexp_to_int(miniexp_nth(2, se_word))); + lua_pushstring(L, "y1"); + lua_pushnumber(L, + info.height - miniexp_to_int(miniexp_nth(2, se_word))); lua_settable(L, -3); lua_pushstring(L, "x1"); lua_pushnumber(L, miniexp_to_int(miniexp_nth(3, se_word))); lua_settable(L, -3); - lua_pushstring(L, "y1"); - lua_pushnumber(L, miniexp_to_int(miniexp_nth(4, se_word))); + lua_pushstring(L, "y0"); + lua_pushnumber(L, + info.height - miniexp_to_int(miniexp_nth(4, se_word))); lua_settable(L, -3); lua_pushstring(L, "word"); @@ -355,8 +400,8 @@ static int getPageText(lua_State *L) { static int closePage(lua_State *L) { DjvuPage *page = (DjvuPage*) luaL_checkudata(L, 1, "djvupage"); - // should be save if called twice - if(page->page_ref != NULL) { + // should be safe if called twice + if (page->page_ref != NULL) { ddjvu_page_release(page->page_ref); page->page_ref = NULL; } @@ -380,47 +425,41 @@ static int drawPage(lua_State *L) { ddjvu_render_mode_t djvu_render_mode = (int) luaL_checkint(L, 6); unsigned char adjusted_low[16], adjusted_high[16]; int i, adjust_pixels = 0; - ddjvu_format_t *pixelformat; ddjvu_rect_t pagerect, renderrect; - uint8_t *imagebuffer = NULL; + uint8_t *imagebuffer = malloc((bb->w)*(bb->h)+1); + + /*printf("@page %d, @@zoom:%f, offset: (%d, %d)\n", page->num, dc->zoom, dc->offset_x, dc->offset_y);*/ - imagebuffer = malloc((bb->w)*(bb->h)+1); /* fill pixel map with white color */ memset(imagebuffer, 0xFF, (bb->w)*(bb->h)+1); - pixelformat = ddjvu_format_create(DDJVU_FORMAT_GREY8, 0, NULL); - ddjvu_format_set_row_order(pixelformat, 1); - ddjvu_format_set_y_direction(pixelformat, 1); - ddjvu_format_set_gamma(pixelformat, dc->gamma); - /*ddjvu_format_set_ditherbits(dc->pixelformat, 2);*/ - /* render full page into rectangle specified by pagerect */ pagerect.x = 0; pagerect.y = 0; pagerect.w = page->info.width * dc->zoom; pagerect.h = page->info.height * dc->zoom; + /*printf("--pagerect--- (x: %d, y: %d), w: %d, h: %d.\n", 0, 0, pagerect.w, pagerect.h);*/ /* copy pixels area from pagerect specified by renderrect. - + * * ddjvulibre library does not support negative offset, positive offset * means moving towards right and down. * - * However, djvureader.lua handles offset differently. It use negative + * However, djvureader.lua handles offset differently. It uses negative * offset to move right and down while positive offset to move left * and up. So we need to handle positive offset manually when copying * imagebuffer to blitbuffer (framebuffer). */ - renderrect.x = luaL_checkint(L, 4); - renderrect.y = luaL_checkint(L, 5); - /*renderrect.x = MAX(-dc->offset_x, 0);*/ - /*renderrect.y = MAX(-dc->offset_y, 0);*/ + renderrect.x = MAX(-dc->offset_x, 0); + renderrect.y = MAX(-dc->offset_y, 0); renderrect.w = MIN(pagerect.w - renderrect.x, bb->w); renderrect.h = MIN(pagerect.h - renderrect.y, bb->h); + /*printf("--renderrect--- (%d, %d), w:%d, h:%d\n", renderrect.x, renderrect.y, renderrect.w, renderrect.h);*/ /* ddjvulibre library only supports rotation of 0, 90, 180 and 270 degrees. - * This four kinds of rotations can already be achieved by native system. + * These four kinds of rotations can already be achieved by native system. * So we don't set rotation here. */ @@ -428,12 +467,12 @@ static int drawPage(lua_State *L) { djvu_render_mode, &pagerect, &renderrect, - pixelformat, + page->doc->pixelformat, bb->w, imagebuffer); - uint8_t *bbptr = (uint8_t*)bb->data; - uint8_t *pmptr = (uint8_t*)imagebuffer; + uint8_t *bbptr = bb->data; + uint8_t *pmptr = imagebuffer; int x, y; /* if offset is positive, we are moving towards up and left. */ int x_offset = MAX(0, dc->offset_x); @@ -460,7 +499,7 @@ static int drawPage(lua_State *L) { else bbptr[x] = (high << 4) | low; } - if(bb->w & 1) { + if (bb->w & 1) { bbptr[x] = 255 - (pmptr[x*2] & 0xF0); } /* go to next line */ @@ -469,9 +508,6 @@ static int drawPage(lua_State *L) { } free(imagebuffer); - pmptr = imagebuffer = NULL; - ddjvu_format_release(pixelformat); - return 0; } @@ -500,6 +536,7 @@ static const struct luaL_Reg djvudocument_meth[] = { {"getPages", getNumberOfPages}, {"getToc", getTableOfContent}, {"getPageText", getPageText}, + {"getOriginalPageSize", getOriginalPageSize}, {"close", closeDocument}, {"getCacheSize", getCacheSize}, {"cleanCache", cleanCache},