mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Add support for colour JPEG images.
I used the luminance match algorithm for converting RGB colour images to grayscale as it gives the best visual results (but at the cost of speed).
This commit is contained in:
committed by
Qingping Hou
parent
2103461a43
commit
cac63cd390
42
pic.c
42
pic.c
@@ -102,6 +102,25 @@ uint8_t *readJPEG(const char *fname, int *width, int *height, int *components)
|
||||
return (uint8_t *)image_buffer;
|
||||
}
|
||||
|
||||
/* Uses luminance match for approximating the human perception of colour,
|
||||
* as per http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
|
||||
* L = 0.299*Red + 0.587*Green + 0.114*Blue */
|
||||
static uint8_t *rgbToGrayscale(uint8_t *image, int width, int height)
|
||||
{
|
||||
int x, y;
|
||||
uint8_t *buf = malloc(width*height+1);
|
||||
|
||||
if (!buf) return NULL;
|
||||
|
||||
for (x = 0; x<width; x++)
|
||||
for (y=0; y<height; y++) {
|
||||
int pos = 3*(x+y*width);
|
||||
buf[x+y*width] = (uint8_t)(0.299*((double)image[pos]) + 0.587*((double)image[pos+1]) + 0.114*((double)image[pos+2]));
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int openDocument(lua_State *L) {
|
||||
int width, height, components;
|
||||
const char *filename = luaL_checkstring(L, 1);
|
||||
@@ -110,18 +129,27 @@ static int openDocument(lua_State *L) {
|
||||
luaL_getmetatable(L, "picdocument");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
unsigned char *image = readJPEG(filename, &width, &height, &components);
|
||||
if (!image)
|
||||
return luaL_error(L, "cannot open jpeg file");
|
||||
uint8_t *raw_image = readJPEG(filename, &width, &height, &components);
|
||||
if (!raw_image)
|
||||
return luaL_error(L, "Cannot open jpeg file");
|
||||
|
||||
if (components != 1)
|
||||
if (components == 1)
|
||||
doc->image = raw_image;
|
||||
else if (components == 3) {
|
||||
uint8_t *gray_image = rgbToGrayscale(raw_image, width, height);
|
||||
if (!gray_image) {
|
||||
free(raw_image);
|
||||
return luaL_error(L, "Cannot convert to grayscale");
|
||||
} else {
|
||||
free(raw_image);
|
||||
doc->image = gray_image;
|
||||
}
|
||||
} else
|
||||
return luaL_error(L, "Unsupported image format");
|
||||
|
||||
doc->image = image;
|
||||
doc->width = width;
|
||||
doc->height = height;
|
||||
doc->components = components;
|
||||
//printf("openDocument(%s) decoded image: %dx%dx%d\n", filename, width, height, components);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -132,6 +160,7 @@ static int openPage(lua_State *L) {
|
||||
PicPage *page = (PicPage*) lua_newuserdata(L, sizeof(PicPage));
|
||||
luaL_getmetatable(L, "picpage");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
page->width = doc->width;
|
||||
page->height = doc->height;
|
||||
page->doc = doc;
|
||||
@@ -158,6 +187,7 @@ static int closeDocument(lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* uses very simple nearest neighbour scaling */
|
||||
static void scaleImage(uint8_t *result, uint8_t *image, int width, int height, int new_width, int new_height)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
Reference in New Issue
Block a user