mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Small optimization in djvu.c:drawPage() --- there is no need to create and destroy
djvu pixel format on each redraw of the page as this can be done once on open and close
of the document. Also, set dither bits to 4 to help djvulibre choose the most
optimal dithering algorithm for the Kindle. Also, make coding style of "if(" -> "if ("
consistent (both instances were used, but "if (" was more frequent).
Conflicts:
djvu.c
This commit is contained in:
committed by
Qingping Hou
parent
7f6d3097a2
commit
b761418236
113
djvu.c
113
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))<DDJVU_JOB_OK) {
|
||||
handle(L, doc->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))<DDJVU_JOB_OK) {
|
||||
handle(L, doc->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},
|
||||
|
||||
Reference in New Issue
Block a user