From f5f2793506a56a3ff958722289faa6456068a6bd Mon Sep 17 00:00:00 2001 From: Frans de Jonge Date: Mon, 10 Jun 2019 15:28:43 +0200 Subject: [PATCH] [fix] DjVu gamma correction (#921) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing implementation only worked in 8-bit mode. By using the `ddjvu_format_set_gamma()` function that comes with djvulibre it suddenly and attractively becomes Not Our Problemâ„¢. I noticed this after doing a quick experiment with a custom power function `#ifdef __ANDROID_API__` like in https://stackoverflow.com/a/19488271/2470572 (For example, if Android define a custom power function, else `#define power(x, y) pow(x, y)`.) I believe the proper way to go about it would probably be to ignore document-specific implementations and to do it in the blitbuffer, but this is quicker. As a side effect, this fixes https://github.com/koreader/koreader/issues/3493. --- djvu.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/djvu.c b/djvu.c index 5ac10c7dc..d7110419b 100644 --- a/djvu.c +++ b/djvu.c @@ -32,6 +32,8 @@ #include "koptcrop.h" #include "djvu.h" +#define ABS(x) ((x<0)?(-x):(x)) + #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) @@ -654,6 +656,26 @@ static int drawPage(lua_State *L) { BlitBuffer *bb = (BlitBuffer*) lua_topointer(L, 3); ddjvu_render_mode_t djvu_render_mode = (int) luaL_checkint(L, 6); ddjvu_rect_t pagerect, renderrect; + // map KOReader gamma to djvulibre gamma + // djvulibre goes from 0.5 to 5.0 + double gamma = ABS(dc->gamma); // not sure why, but 1 is given as -1? + if (gamma == 2) { + // default + gamma = 2.2; + } else if (gamma < 2) { + // with this function, 0.8 = 5, 2 = 2.2 + gamma = 6.86666 - 2.33333 * gamma; + if (gamma > 5) { + gamma = 5; + } + } else if (gamma > 2) { + // with this function, 9 = 0.5, 2 = 2.2 + gamma = 2.68571 - 0.242856 * gamma; + if (gamma < 0.5) { + gamma = 0.5; + } + } + ddjvu_format_set_gamma(page->doc->pixelformat, gamma); int bbsize = (bb->w)*(bb->h)*page->doc->pixelsize; uint8_t *imagebuffer = bb->data; @@ -692,23 +714,6 @@ static int drawPage(lua_State *L) { if (!ddjvu_page_render(page->page_ref, djvu_render_mode, &pagerect, &renderrect, page->doc->pixelformat, bb->w*page->doc->pixelsize, imagebuffer)) memset(imagebuffer, 0xFF, bbsize); - /* Gamma correction of the blitbuffer, do we need to build this into BlitBuffer? */ - unsigned char gamma_map[256]; - unsigned char *s = imagebuffer; - int k, x, y; - - if (dc->gamma != -1.0) { - for (k = 0; k < 256; k++) - gamma_map[k] = pow(k / 255.0f, dc->gamma) * 255; - - for (y = 0; y < bb->h; y++) { - for (x = 0; x < bb->w; x++) { - k = y*bb->pitch + x; - s[k] = gamma_map[s[k]]; - } - } - } - return 0; }