Gfxprim
Threads by month
- ----- 2026 -----
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- 929 discussions
08 Sep '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 17fe2ed28b93515ca3cf486e1af6aff088a7d8bd (commit)
via 023357e5ae4971313f9a579e5b426039c0e5fb46 (commit)
from 62f3b9db48fe5159efdfd4dd01d51242d37e4375 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/17fe2ed28b93515ca3cf486e1af6aff088a7…
commit 17fe2ed28b93515ca3cf486e1af6aff088a7d8bd
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Sep 8 22:53:35 2013 +0200
loaders: Add LineConvert.
Adds LineConvert API for trivial pixel conversions
(i.e. RGB888 to BGR888 and so).
Make use of it in BMP and JPG loaders.
(more to come)
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/build/syms/Loaders_symbols.txt b/build/syms/Loaders_symbols.txt
index 9a933e7..e424e98 100644
--- a/build/syms/Loaders_symbols.txt
+++ b/build/syms/Loaders_symbols.txt
@@ -91,3 +91,6 @@ GP_ContainerSeek
GP_MatchZip
GP_OpenZip
+
+GP_LineConvertible
+GP_LineConvertGet
diff --git a/include/loaders/GP_LineConvert.h b/include/loaders/GP_LineConvert.h
new file mode 100644
index 0000000..c880aad
--- /dev/null
+++ b/include/loaders/GP_LineConvert.h
@@ -0,0 +1,60 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+/*
+
+ Converts a continuous line of pixels from buffer A to a line of pixels in
+ buffer B.
+
+ Supports only trivial conversions i.e. RGB888 to BGR888 and G1_LE to G1_BE,
+ etc.
+
+ The code is mainly used in image loaders when saving image from memory buffer
+ that has exactly same channels (in size and names) but placed differently in
+ buffer of pixel.
+
+ */
+
+
+#ifndef LOADERS_LINE_CONVERT_H
+#define LOADERS_LINE_CONVERT_H
+
+#include "core/GP_Pixel.h"
+
+typedef void (*GP_LineConvert)(const uint8_t *in, uint8_t *out, unsigned int len);
+
+/*
+ * The out array is terminated by GP_PIXEL_UNKNOWN.
+ *
+ * Returns output pixel type given input pixel type and table of posible output
+ * types.
+ *
+ * Returns GP_PIXEL_UNKNOWN if no conversion is posible.
+ */
+GP_PixelType GP_LineConvertible(GP_PixelType in, GP_PixelType out[]);
+
+/*
+ * Returns pointer to conversion function or NULL if there is none.
+ */
+GP_LineConvert GP_LineConvertGet(GP_PixelType in, GP_PixelType out);
+
+#endif /* LOADERS_LINE_CONVERT_H */
diff --git a/libs/loaders/GP_BMP.c b/libs/loaders/GP_BMP.c
index 430e9d7..b6f3a50 100644
--- a/libs/loaders/GP_BMP.c
+++ b/libs/loaders/GP_BMP.c
@@ -41,6 +41,7 @@
#include "core/GP_GetPutPixel.h"
#include "loaders/GP_ByteUtils.h"
+#include "loaders/GP_LineConvert.h"
#include "loaders/GP_BMP.h"
#define BMP_HEADER_OFFSET 0x0a /* info header offset - 4 bytes */
@@ -51,7 +52,6 @@
#define BUF_TO_2(buf, off) (buf[off] + (buf[off+1]<<8))
-
struct bitmap_info_header {
/*
* Offset to image data.
@@ -771,17 +771,27 @@ static int bmp_write_header(struct bitmap_info_header *header, FILE *f)
return 0;
}
+static GP_PixelType out_pixel_types[] = {
+ GP_PIXEL_RGB888,
+ GP_PIXEL_UNKNOWN,
+};
+
static int bmp_fill_header(const GP_Context *src, struct bitmap_info_header *header)
{
+ GP_PixelType out_pix;
+
switch (src->pixel_type) {
case GP_PIXEL_RGB888:
- case GP_PIXEL_BGR888:
header->bpp = 24;
break;
default:
- GP_DEBUG(1, "Unsupported pixel type (%s)",
- GP_PixelTypeName(src->pixel_type));
- return ENOSYS;
+ out_pix = GP_LineConvertible(src->pixel_type, out_pixel_types);
+
+ if (out_pix == GP_PIXEL_UNKNOWN) {
+ GP_DEBUG(1, "Unsupported pixel type %s",
+ GP_PixelTypeName(src->pixel_type));
+ return ENOSYS;
+ }
}
header->w = src->w;
@@ -803,9 +813,12 @@ static int bmp_fill_header(const GP_Context *src, struct bitmap_info_header *hea
static int bmp_write_data(FILE *f, const GP_Context *src, GP_ProgressCallback *callback)
{
int y;
- uint32_t padd_len = 0, x;
+ uint32_t padd_len = 0;
char padd[3] = {0};
uint8_t tmp[3 * src->w];
+ GP_LineConvert Convert;
+
+ Convert = GP_LineConvertGet(src->pixel_type, GP_PIXEL_RGB888);
if (src->bytes_per_row%4)
padd_len = 4 - src->bytes_per_row%4;
@@ -813,14 +826,8 @@ static int bmp_write_data(FILE *f, const GP_Context *src, GP_ProgressCallback *c
for (y = src->h - 1; y >= 0; y--) {
void *row = GP_PIXEL_ADDR(src, 0, y);
- if (src->pixel_type == GP_PIXEL_BGR888) {
- memcpy(tmp, row, 3 * src->w);
-
- for (x = 0; x < src->w; x++) {
- uint8_t *pix = tmp + 3 * x;
- GP_SWAP(pix[0], pix[2]);
- }
-
+ if (src->pixel_type != GP_PIXEL_RGB888) {
+ Convert(row, tmp, src->w);
row = tmp;
}
diff --git a/libs/loaders/GP_JPG.c b/libs/loaders/GP_JPG.c
index e48c864..3b52821 100644
--- a/libs/loaders/GP_JPG.c
+++ b/libs/loaders/GP_JPG.c
@@ -37,7 +37,8 @@
#include "../../config.h"
#include "core/GP_Debug.h"
-#include "GP_JPG.h"
+#include "loaders/GP_LineConvert.h"
+#include "loaders/GP_JPG.h"
#ifdef HAVE_JPEG
@@ -345,22 +346,21 @@ int GP_LoadJPGMetaData(const char *src_path, GP_MetaData *data)
return ret;
}
-static int save_rgb888(struct jpeg_compress_struct *cinfo,
- const GP_Context *src,
- GP_ProgressCallback *callback)
+static int save_convert(struct jpeg_compress_struct *cinfo,
+ const GP_Context *src,
+ GP_PixelType out_pix,
+ GP_ProgressCallback *callback)
{
- unsigned int x;
- uint8_t tmp[3 * src->w];
+ uint8_t tmp[(src->w * GP_PixelSize(out_pix)) / 8 + 1];
+ GP_LineConvert Convert;
+
+ Convert = GP_LineConvertGet(src->pixel_type, out_pix);
while (cinfo->next_scanline < cinfo->image_height) {
uint32_t y = cinfo->next_scanline;
+ void *in = GP_PIXEL_ADDR(src, 0, y);
- memcpy(tmp, GP_PIXEL_ADDR(src, 0, y), 3 * src->w);
-
- for (x = 0; x < src->w; x++) {
- uint8_t *pix = tmp + 3 * x;
- GP_SWAP(pix[0], pix[2]);
- }
+ Convert(in, tmp, src->w);
JSAMPROW row = (void*)tmp;
jpeg_write_scanlines(cinfo, &row, 1);
@@ -393,26 +393,37 @@ static int save(struct jpeg_compress_struct *cinfo,
return 0;
}
+static GP_PixelType out_pixel_types[] = {
+ GP_PIXEL_BGR888,
+ GP_PIXEL_G8,
+ GP_PIXEL_UNKNOWN
+};
+
int GP_SaveJPG(const GP_Context *src, const char *dst_path,
GP_ProgressCallback *callback)
{
FILE *f;
struct jpeg_compress_struct cinfo;
+ GP_PixelType out_pix;
struct my_jpg_err my_err;
int err;
GP_DEBUG(1, "Saving JPG Image '%s'", dst_path);
switch (src->pixel_type) {
- case GP_PIXEL_RGB888:
case GP_PIXEL_BGR888:
case GP_PIXEL_G8:
+ out_pix = src->pixel_type;
break;
default:
- GP_DEBUG(1, "Unsupported pixel type %s",
- GP_PixelTypeName(src->pixel_type));
- errno = ENOSYS;
- return 1;
+ out_pix = GP_LineConvertible(src->pixel_type, out_pixel_types);
+
+ if (out_pix == GP_PIXEL_UNKNOWN) {
+ GP_DEBUG(1, "Unsupported pixel type %s",
+ GP_PixelTypeName(src->pixel_type));
+ errno = ENOSYS;
+ return 1;
+ }
}
f = fopen(dst_path, "wb");
@@ -440,8 +451,7 @@ int GP_SaveJPG(const GP_Context *src, const char *dst_path,
cinfo.image_width = src->w;
cinfo.image_height = src->h;
- switch (src->pixel_type) {
- case GP_PIXEL_RGB888:
+ switch (out_pix) {
case GP_PIXEL_BGR888:
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
@@ -458,13 +468,10 @@ int GP_SaveJPG(const GP_Context *src, const char *dst_path,
jpeg_start_compress(&cinfo, TRUE);
- switch (src->pixel_type) {
- case GP_PIXEL_RGB888:
- err = save_rgb888(&cinfo, src, callback);
- break;
- default:
+ if (out_pix != src->pixel_type)
+ err = save_convert(&cinfo, src, out_pix, callback);
+ else
err = save(&cinfo, src, callback);
- }
if (err)
goto err3;
diff --git a/libs/loaders/GP_LineConvert.c b/libs/loaders/GP_LineConvert.c
new file mode 100644
index 0000000..9f3b70c
--- /dev/null
+++ b/libs/loaders/GP_LineConvert.c
@@ -0,0 +1,85 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#include "core/GP_Debug.h"
+#include "GP_LineConvert.h"
+
+static void xyz888_to_zyx888(const uint8_t *inbuf, uint8_t *outbuf, unsigned int len)
+{
+ unsigned int i;
+
+ for (i = 0; i < len; i++) {
+ outbuf[2] = inbuf[0];
+ outbuf[0] = inbuf[2];
+ outbuf[1] = inbuf[1];
+
+ outbuf+=3;
+ inbuf+=3;
+ }
+}
+
+GP_LineConvert GP_LineConvertGet(GP_PixelType in, GP_PixelType out)
+{
+ switch (in) {
+ case GP_PIXEL_RGB888:
+ switch (out) {
+ case GP_PIXEL_BGR888:
+ return xyz888_to_zyx888;
+ break;
+ default:
+ break;
+ }
+ break;
+ case GP_PIXEL_BGR888:
+ switch (out) {
+ case GP_PIXEL_RGB888:
+ return xyz888_to_zyx888;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+GP_PixelType GP_LineConvertible(GP_PixelType in, GP_PixelType out[])
+{
+ unsigned int i;
+
+ GP_DEBUG(1, "Trying to find conversion for %s", GP_PixelTypeName(in));
+
+ for (i = 0; out[i] != GP_PIXEL_UNKNOWN; i++) {
+ if (GP_LineConvertGet(in, out[i])) {
+ GP_DEBUG(1, "Found %s -> %s", GP_PixelTypeName(in),
+ GP_PixelTypeName(out[i]));
+ return out[i];
+ }
+ }
+
+ GP_DEBUG(1, "Not found");
+
+ return GP_PIXEL_UNKNOWN;
+}
http://repo.or.cz/w/gfxprim.git/commit/023357e5ae4971313f9a579e5b426039c0e5…
commit 023357e5ae4971313f9a579e5b426039c0e5fb46
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Sep 8 18:27:15 2013 +0200
backends: Linux FB: Declare local function as static.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/backends/GP_LinuxFB.c b/libs/backends/GP_LinuxFB.c
index 2849a7a..c14195f 100644
--- a/libs/backends/GP_LinuxFB.c
+++ b/libs/backends/GP_LinuxFB.c
@@ -202,7 +202,7 @@ static int allocate_console(struct fb_priv *fb, int flags)
return 0;
}
-void free_console(struct fb_priv *fb)
+static void free_console(struct fb_priv *fb)
{
/* restore blinking cursor */
if (ioctl(fb->con_fd, KDSETMODE, KD_TEXT))
-----------------------------------------------------------------------
Summary of changes:
build/syms/Loaders_symbols.txt | 3 +
.../{gfx/GP_HLineAA.h => loaders/GP_LineConvert.h} | 39 +++++----
libs/backends/GP_LinuxFB.c | 2 +-
libs/loaders/GP_BMP.c | 35 +++++---
libs/loaders/GP_JPG.c | 57 +++++++------
.../loaders/GP_LineConvert.c | 90 ++++++++++----------
6 files changed, 125 insertions(+), 101 deletions(-)
copy include/{gfx/GP_HLineAA.h => loaders/GP_LineConvert.h} (63%)
copy demos/c_simple/gaussian_noise.c => libs/loaders/GP_LineConvert.c (61%)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
02 Sep '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 62f3b9db48fe5159efdfd4dd01d51242d37e4375 (commit)
via 3f78c26fead7c7c20057735c752c841f754010a9 (commit)
via 5f3a2c0ec123ae0b6db9994fa948b1b032204acc (commit)
from cb3020fdd8ac170c98633ace520842f3c7d72896 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/62f3b9db48fe5159efdfd4dd01d51242d37e…
commit 62f3b9db48fe5159efdfd4dd01d51242d37e4375
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Sep 2 21:21:08 2013 +0200
loaders: ZIP: Silence unused warning.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_ZIP.c b/libs/loaders/GP_ZIP.c
index 42d08d5..83fe617 100644
--- a/libs/loaders/GP_ZIP.c
+++ b/libs/loaders/GP_ZIP.c
@@ -709,6 +709,7 @@ err0:
GP_Container *GP_OpenZip(const char *path)
{
+ (void) path;
GP_FATAL("zlib support not compiled in");
errno = ENOSYS;
return NULL;
http://repo.or.cz/w/gfxprim.git/commit/3f78c26fead7c7c20057735c752c841f7540…
commit 3f78c26fead7c7c20057735c752c841f754010a9
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Sep 2 23:00:40 2013 +0200
backends: Linux FB: Fix error codepath.
Correctly uninitialize keyboard and console on failure.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/backends/GP_LinuxFB.c b/libs/backends/GP_LinuxFB.c
index 8e96684..2849a7a 100644
--- a/libs/backends/GP_LinuxFB.c
+++ b/libs/backends/GP_LinuxFB.c
@@ -202,6 +202,19 @@ static int allocate_console(struct fb_priv *fb, int flags)
return 0;
}
+void free_console(struct fb_priv *fb)
+{
+ /* restore blinking cursor */
+ if (ioctl(fb->con_fd, KDSETMODE, KD_TEXT))
+ GP_WARN("Failed to ioctl KDSETMODE (restore KDMODE)");
+
+ /* switch back console */
+ if (fb->last_con_nr != -1)
+ ioctl(fb->con_fd, VT_ACTIVATE, fb->last_con_nr);
+
+ close(fb->con_fd);
+}
+
/* Backend API callbacks */
static void fb_poll(GP_Backend *self)
@@ -239,19 +252,11 @@ static void fb_exit(GP_Backend *self)
munmap(fb->fb_mem, fb->bsize);
close(fb->fb_fd);
- /* restore blinking cursor */
- if (ioctl(fb->con_fd, KDSETMODE, KD_TEXT))
- GP_WARN("Failed to ioctl KDSETMODE (restore KDMODE)");
-
- /* restore keyboard mode */
if (fb->flags & GP_FB_INPUT_KBD)
exit_kbd(fb);
- /* switch back console */
- if (fb->last_con_nr != -1)
- ioctl(fb->con_fd, VT_ACTIVATE, fb->last_con_nr);
+ free_console(fb);
- close(fb->con_fd);
free(self);
}
@@ -298,8 +303,8 @@ GP_Backend *GP_BackendLinuxFBInit(const char *path, int flags)
fb = GP_BACKEND_PRIV(backend);
- if (allocate_console(fb, flags & GP_FB_INPUT_KBD))
- goto err1;
+ if (allocate_console(fb, flags))
+ goto err0;
if (flags & GP_FB_INPUT_KBD) {
if (init_kbd(fb))
@@ -412,15 +417,11 @@ err4:
err3:
close(fd);
err2:
- close(fb->con_fd);
-
- /* reset keyboard */
- ioctl(fb->con_fd, KDSETMODE, KD_TEXT);
-
- /* switch back console */
- if (fb->last_con_nr != -1)
- ioctl(fb->con_fd, VT_ACTIVATE, fb->last_con_nr);
+ if (flags & GP_FB_INPUT_KBD)
+ exit_kbd(fb);
err1:
+ free_console(fb);
+err0:
free(backend);
return NULL;
}
http://repo.or.cz/w/gfxprim.git/commit/5f3a2c0ec123ae0b6db9994fa948b1b03220…
commit 5f3a2c0ec123ae0b6db9994fa948b1b032204acc
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Tue Aug 27 00:54:09 2013 +0200
loaders: BMP: Implement BGR888 Save.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_BMP.c b/libs/loaders/GP_BMP.c
index effb301..430e9d7 100644
--- a/libs/loaders/GP_BMP.c
+++ b/libs/loaders/GP_BMP.c
@@ -182,7 +182,7 @@ static int read_alphabitfields(FILE *f, struct bitmap_info_header *header)
int ret;
ret = GP_FRead(f, "L4 L4 L4 L4",
- &header->R_mask,
+ &header->R_mask,
&header->G_mask,
&header->B_mask,
&header->A_mask);
@@ -467,7 +467,7 @@ static uint8_t get_idx(struct bitmap_info_header *header,
{
switch (header->bpp) {
case 1:
- return !!(row[x/8] & (1<<(7 - x%8)));
+ return !!(row[x/8] & (1<<(7 - x%8)));
case 2:
return (row[x/4] >> (2*(3 - x%4))) & 0x03;
case 4:
@@ -653,7 +653,7 @@ int GP_OpenBMP(const char *src_path, FILE **f,
*h = header.h;
if (pixel_type != NULL)
- *pixel_type = match_pixel_type(&header);
+ *pixel_type = match_pixel_type(&header);
}
return 0;
@@ -775,6 +775,7 @@ static int bmp_fill_header(const GP_Context *src, struct bitmap_info_header *hea
{
switch (src->pixel_type) {
case GP_PIXEL_RGB888:
+ case GP_PIXEL_BGR888:
header->bpp = 24;
break;
default:
@@ -802,8 +803,9 @@ static int bmp_fill_header(const GP_Context *src, struct bitmap_info_header *hea
static int bmp_write_data(FILE *f, const GP_Context *src, GP_ProgressCallback *callback)
{
int y;
- uint32_t padd_len = 0;
+ uint32_t padd_len = 0, x;
char padd[3] = {0};
+ uint8_t tmp[3 * src->w];
if (src->bytes_per_row%4)
padd_len = 4 - src->bytes_per_row%4;
@@ -811,6 +813,17 @@ static int bmp_write_data(FILE *f, const GP_Context *src, GP_ProgressCallback *c
for (y = src->h - 1; y >= 0; y--) {
void *row = GP_PIXEL_ADDR(src, 0, y);
+ if (src->pixel_type == GP_PIXEL_BGR888) {
+ memcpy(tmp, row, 3 * src->w);
+
+ for (x = 0; x < src->w; x++) {
+ uint8_t *pix = tmp + 3 * x;
+ GP_SWAP(pix[0], pix[2]);
+ }
+
+ row = tmp;
+ }
+
if (fwrite(row, src->bytes_per_row, 1, f) != 1)
return EIO;
-----------------------------------------------------------------------
Summary of changes:
libs/backends/GP_LinuxFB.c | 39 ++++++++++++++++++++-------------------
libs/loaders/GP_BMP.c | 21 +++++++++++++++++----
libs/loaders/GP_ZIP.c | 1 +
3 files changed, 38 insertions(+), 23 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
27 Aug '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via cb3020fdd8ac170c98633ace520842f3c7d72896 (commit)
via 46abc0f23eeb1e9eb0b437a801ef0faf829e4fdd (commit)
via 6eba23eed3866d61f6416fe090b7df420b015c9c (commit)
via 4094a3e9d20c3bb436c89af9ca80a2d3d232e335 (commit)
via fbeb1a090772e74c6b8fefa7d46a80be03914aab (commit)
from 59508f340d3fd1d02e11371c913d4e7656f8ce4f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/cb3020fdd8ac170c98633ace520842f3c7d7…
commit cb3020fdd8ac170c98633ace520842f3c7d72896
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Tue Aug 27 00:14:04 2013 +0200
loaders: JPG: Fix cinfo init for GP_SaveJPG()
Set correctly color space and number of components.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_JPG.c b/libs/loaders/GP_JPG.c
index 097308b..e48c864 100644
--- a/libs/loaders/GP_JPG.c
+++ b/libs/loaders/GP_JPG.c
@@ -439,8 +439,20 @@ int GP_SaveJPG(const GP_Context *src, const char *dst_path,
cinfo.image_width = src->w;
cinfo.image_height = src->h;
- cinfo.input_components = src->pixel_type == GP_PIXEL_RGB888 ? 3 : 1;
- cinfo.in_color_space = JCS_RGB;
+
+ switch (src->pixel_type) {
+ case GP_PIXEL_RGB888:
+ case GP_PIXEL_BGR888:
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+ break;
+ case GP_PIXEL_G8:
+ cinfo.input_components = 1;
+ cinfo.in_color_space = JCS_GRAYSCALE;
+ break;
+ default:
+ GP_BUG("Don't know how to set color_space and compoments");
+ }
jpeg_set_defaults(&cinfo);
http://repo.or.cz/w/gfxprim.git/commit/46abc0f23eeb1e9eb0b437a801ef0faf829e…
commit 46abc0f23eeb1e9eb0b437a801ef0faf829e4fdd
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Aug 26 23:57:50 2013 +0200
filters: ResizeCubicFloat: Set errno.
Set errno to ENOSYS on currently unimplemented GP_PixelType.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/filters/GP_ResizeCubicFloat.c b/libs/filters/GP_ResizeCubicFloat.c
index f16ab7a..908e328 100644
--- a/libs/filters/GP_ResizeCubicFloat.c
+++ b/libs/filters/GP_ResizeCubicFloat.c
@@ -21,6 +21,7 @@
*****************************************************************************/
#include <math.h>
+#include <errno.h>
#include "core/GP_Context.h"
#include "core/GP_GetPutPixel.h"
@@ -81,8 +82,10 @@ int GP_FilterResizeCubic(const GP_Context *src, GP_Context *dst,
float col_r[src->h], col_g[src->h], col_b[src->h];
uint32_t i, j;
- if (src->pixel_type != GP_PIXEL_RGB888 || dst->pixel_type != GP_PIXEL_RGB888)
+ if (src->pixel_type != GP_PIXEL_RGB888 || dst->pixel_type != GP_PIXEL_RGB888) {
+ errno = ENOSYS;
return 1;
+ }
GP_DEBUG(1, "Scaling image %ux%u -> %ux%u %2.2f %2.2f",
src->w, src->h, dst->w, dst->h,
http://repo.or.cz/w/gfxprim.git/commit/6eba23eed3866d61f6416fe090b7df420b01…
commit 6eba23eed3866d61f6416fe090b7df420b015c9c
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Aug 25 16:18:02 2013 +0200
pywrap: filters: Update filters wrappings.
* Add the wrongly removed core import back
(fixes GP_Size map to int in swig)
* Add exceptions on filter failure
* Add filter submodule
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/py_simple/blur.py b/demos/py_simple/blur.py
index 478af96..3735346 100755
--- a/demos/py_simple/blur.py
+++ b/demos/py_simple/blur.py
@@ -15,7 +15,7 @@ def main():
# Load Image
img = loaders.Load(sys.argv[2])
# Do in-place gaussian blur
- filters.FilterGaussianBlur(img, img, radii, radii, None)
+ filters.GaussianBlur(img, img, radii, radii, None)
# Save result
loaders.SaveJPG(img, "out.jpg", None)
diff --git a/demos/py_simple/dither.py b/demos/py_simple/dither.py
index e40221e..d7ca1b8 100755
--- a/demos/py_simple/dither.py
+++ b/demos/py_simple/dither.py
@@ -13,7 +13,7 @@ def main():
# Load Image
img = loaders.Load(sys.argv[1])
# Use Floyd-Steinberg dithering
- res = filters.FilterFloydSteinberg_RGB888_Alloc(img, core.C.PIXEL_G1, None)
+ res = filters.FloydSteinberg_RGB888_Alloc(img, core.C.PIXEL_G1, None)
# Save result into grayscale png
res.loaders.SavePNG("out.png")
diff --git a/demos/py_simple/progress_callback.py b/demos/py_simple/progress_callback.py
index f712faf..b4b0b3e 100755
--- a/demos/py_simple/progress_callback.py
+++ b/demos/py_simple/progress_callback.py
@@ -26,7 +26,7 @@ def main():
exit(1)
try:
- img = filters.FilterGaussianBlurAlloc(img, 50, 50, callback)
+ img = img.filters.GaussianBlurAlloc(50, 50, callback)
print('')
except OSError:
print("Filter Aborted")
diff --git a/demos/py_simple/rotate90.py b/demos/py_simple/resize.py
similarity index 80%
copy from demos/py_simple/rotate90.py
copy to demos/py_simple/resize.py
index 099fb51..b9e65c1 100755
--- a/demos/py_simple/rotate90.py
+++ b/demos/py_simple/resize.py
@@ -15,8 +15,8 @@ def main():
# Load Image
src = loaders.Load(sys.argv[1])
- # Rotate by 90 degrees
- res = filters.FilterRotate90Alloc(src, None)
+ # Resize image to the half of the original
+ res = src.filters.ResizeAlloc(src.w//2, src.h//2, 2, None)
# Save Image
res.loaders.Save(sys.argv[2])
diff --git a/demos/py_simple/rotate90.py b/demos/py_simple/rotate90.py
index 099fb51..2dcb3f5 100755
--- a/demos/py_simple/rotate90.py
+++ b/demos/py_simple/rotate90.py
@@ -16,7 +16,7 @@ def main():
# Load Image
src = loaders.Load(sys.argv[1])
# Rotate by 90 degrees
- res = filters.FilterRotate90Alloc(src, None)
+ res = src.filters.Rotate90Alloc(None)
# Save Image
res.loaders.Save(sys.argv[2])
diff --git a/pylib/gfxprim/filters/__init__.py b/pylib/gfxprim/filters/__init__.py
index f847331..4ce1880 100644
--- a/pylib/gfxprim/filters/__init__.py
+++ b/pylib/gfxprim/filters/__init__.py
@@ -1,16 +1,50 @@
+"""
+Module extending the Context class with .filter submodule.
+
+Use as in "import gfxprim.filters; context_foo.filter.Resize(...)"
+"""
+
+# Import the SWIG wrapper
from . import c_filters
def _init(module):
"Extend Context with filters submodule"
+ from ..utils import extend_submodule
+ from ..core import Context as _context
+
+ # New Context submodule
+ class FiltersSubmodule(object):
+ def __init__(self, ctx):
+ self.ctx = ctx
+
+ _context._submodules['filters'] = FiltersSubmodule
+
+ for name in ['Resize', 'ResizeAlloc',
+ 'Rotate90', 'Rotate90Alloc',
+ 'Rotate180', 'Rotate180Alloc',
+ 'Rotate270', 'Rotate270Alloc',
+ 'MirrorH', 'MirrorHAlloc',
+ 'MirrorV', 'MirrorVAlloc',
+ 'Addition', 'Multiply', 'Difference', 'Max', 'Min',
+ 'GaussianBlur', 'GaussianBlurAlloc',
+ 'GaussianBlurEx', 'GaussianBlurExAlloc',
+ 'GaussianNoiseAdd', 'GaussianNoiseAddAlloc',
+ 'GaussianNoiseAddEx', 'GaussianNoiseAddExAlloc',
+ 'Laplace', 'LaplaceAlloc',
+ 'EdgeSharpening', 'EdgeSharpeningAlloc',
+ 'Median', 'MedianAlloc', 'MedianEx', 'MedianExAlloc',
+ 'Sigma', 'SigmaAlloc', 'SigmaEx', 'SigmaExAlloc']:
+ extend_submodule(FiltersSubmodule, name, c_filters.__getattribute__('GP_Filter' + name))
+
# Imports from the SWIG module
import re
- def strip_GP(s):
- return re.sub('^GP_', '', s)
+ def strip_GP_Filter(s):
+ return re.sub('^GP_Filter', '', s)
# Import functions from the SWIG module
from ..utils import import_members
- import_members(c_filters, module, sub=strip_GP,
+ import_members(c_filters, module, sub=strip_GP_Filter,
include=[
'^GP_Filter.*Alloc',
'^GP_Filter[A-Za-z0-9]*$',
diff --git a/pylib/gfxprim/filters/filters.i b/pylib/gfxprim/filters/filters.i
index d803993..9610342 100644
--- a/pylib/gfxprim/filters/filters.i
+++ b/pylib/gfxprim/filters/filters.i
@@ -6,31 +6,18 @@
#include "core/GP_Debug.h"
%}
-/* Listed in GP_Filters.h: */
-%include "GP_Point.h"
-%ignore GP_Histogram::hist;
-%include "GP_Stats.h"
-%include "GP_Linear.h"
-
-/* Resize filters */
-ERROR_ON_NONZERO(GP_FilterResize);
-%newobject GP_FilterResizeAlloc;
-ERROR_ON_NULL(GP_FilterResizeAlloc);
-%include "GP_Resize.h"
+%import ../core/core.i
-ERROR_ON_NONZERO(GP_FilterResizeNN);
-%newobject GP_FilterResizeNNAlloc;
-ERROR_ON_NULL(GP_FilterResizeNNAlloc);
-%include "GP_ResizeNN.h"
-
-ERROR_ON_NONZERO(GP_FilterResizeLinearInt);
-%newobject GP_FilterResizeLinearIntAlloc;
-ERROR_ON_NULL(GP_FilterResizeLinearIntAlloc);
-ERROR_ON_NONZERO(GP_FilterResizeLinearLFInt);
-%newobject GP_FilterResizeLinearLFIntAlloc;
-ERROR_ON_NULL(GP_FilterResizeLinearLFIntAlloc);
-%include "GP_ResizeLinear.h"
+/*
+ * Creates allocating and non-allocating filter definitions
+ */
+%define FILTER_FUNC(funcname)
+%newobject GP_Filter ## funcname ## Alloc;
+ERROR_ON_NULL(GP_Filter ## funcname ## Alloc);
+ERROR_ON_NONZERO(GP_Filter ## funcname);
+%enddef
+/* Listed in GP_Filters.h: */
%extend GP_FilterParam {
~GP_FilterParam() {
GP_DEBUG(2, "[wrapper] GP_FilterParamFree");
@@ -41,40 +28,79 @@ ERROR_ON_NULL(GP_FilterResizeLinearLFIntAlloc);
%newobject GP_FilterParamCreate;
%include "GP_FilterParam.h"
-/* Functions returning new allocated context */
-%immutable GP_FilterSymmetryNames;
+/* TODO: Point filters, once fixed */
-%newobject GP_FilterMirrorH_Alloc;
-%newobject GP_FilterMirrorV_Alloc;
-%newobject GP_FilterRotate90_Alloc;
-%newobject GP_FilterRotate180_Alloc;
-%newobject GP_FilterRotate270_Alloc;
-%newobject GP_FilterSymmetry_Alloc;
-%include "GP_Rotate.h"
+/* Arithmetic filters */
+FILTER_FUNC(Addition);
+FILTER_FUNC(Multiply);
+FILTER_FUNC(Difference);
+FILTER_FUNC(Max);
+FILTER_FUNC(Min);
+%include "GP_Arithmetic.h"
-%newobject GP_FilterFloydSteinberg_RGB888_Alloc;
-%newobject GP_FilterHilbertPeano_RGB888_Alloc;
-%include "GP_Dither.h"
+/* TODO: Stats filters */
-%newobject GP_FilterAdditionAlloc;
-%newobject GP_FilterMultiplyAlloc;
-%newobject GP_FilterDifferenceAlloc;
-%newobject GP_FilterMaxAlloc;
-%newobject GP_FilterMinAlloc;
-%include "GP_Arithmetic.h"
+/* Rotations filters */
+FILTER_FUNC(MirrorH);
+FILTER_FUNC(MirrorV);
+FILTER_FUNC(Rotate90);
+FILTER_FUNC(Rotate180);
+FILTER_FUNC(Rotate270);
+FILTER_FUNC(Symmetry);
+%immutable GP_FilterSymmetryNames;
+%include "GP_Rotate.h"
-%newobject GP_FilterConvolutionAlloc;
-%newobject GP_FilterConvolutionExAlloc;
+/* Convolutions */
+FILTER_FUNC(Convolution);
+FILTER_FUNC(ConvolutionEx);
%include "GP_Convolution.h"
-%newobject GP_FilterBlurAlloc;
-%newobject GP_FilterBlurExAlloc;
+/* Blur */
+FILTER_FUNC(GaussianBlurEx);
+FILTER_FUNC(GaussianBlur);
%include "GP_Blur.h"
-%newobject GP_FilterMedianAlloc;
-%newobject GP_FilterMedianExAlloc;
+/* Resize filters */
+FILTER_FUNC(Resize);
+%include "GP_Resize.h"
+
+FILTER_FUNC(ResizeNN);
+%include "GP_ResizeNN.h"
+
+FILTER_FUNC(ResizeLinearInt);
+FILTER_FUNC(ResizeLinearLFInt);
+%include "GP_ResizeLinear.h"
+
+/* TODO: Ditherings */
+%newobject GP_FilterFloydSteinberg_RGB888_Alloc;
+ERROR_ON_NULL(GP_FilterFloydSteinberg_RGB888_Alloc);
+%newobject GP_FilterHilbertPeano_RGB888_Alloc;
+ERROR_ON_NULL(GP_FilterHilbertPeano_RGB888_Alloc);
+ERROR_ON_NONZERO(GP_FilterFloydSteinberg_RGB888);
+ERROR_ON_NONZERO(GP_FilterHilbertPeano_RGB888);
+%include "GP_Dither.h"
+
+/* Laplace and Laplace Edge Sharpening */
+FILTER_FUNC(Laplace);
+FILTER_FUNC(EdgeSharpening);
+%include "GP_Laplace.h"
+
+/* Median */
+FILTER_FUNC(MedianEx);
+FILTER_FUNC(Median);
%include "GP_Median.h"
-%newobject GP_FilterSigmaAlloc;
-%newobject GP_FilterSigmaExAlloc;
+/* Weighted Median */
+FILTER_FUNC(WeightedMedianEx);
+FILTER_FUNC(WeightedMedian);
+%include "GP_WeightedMedian.h"
+
+/* Sigma filter */
+FILTER_FUNC(GP_FilterSigmaEx);
+FILTER_FUNC(GP_FilterSigma);
%include "GP_Sigma.h"
+
+/* Gaussian Noise */
+FILTER_FUNC(GaussianNoiseAddEx);
+FILTER_FUNC(GaussianNoiseAdd);
+%include "GP_GaussianNoise.h"
http://repo.or.cz/w/gfxprim.git/commit/4094a3e9d20c3bb436c89af9ca80a2d3d232…
commit 4094a3e9d20c3bb436c89af9ca80a2d3d232e335
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Aug 25 15:41:16 2013 +0200
spiv: Skip number of images in dir if not in dir
This fixes spiv to skip info line with current dir position and number
of images if the current argument is not directory.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/spiv/image_list.c b/demos/spiv/image_list.c
index cef9c8e..9d7a3ff 100644
--- a/demos/spiv/image_list.c
+++ b/demos/spiv/image_list.c
@@ -366,7 +366,7 @@ unsigned int image_list_pos(struct image_list *self)
unsigned int image_list_dir_count(struct image_list *self)
{
if (!self->in_dir)
- return 1;
+ return 0;
return self->max_file;
}
@@ -374,7 +374,7 @@ unsigned int image_list_dir_count(struct image_list *self)
unsigned int image_list_dir_pos(struct image_list *self)
{
if (!self->in_dir)
- return 1;
+ return 0;
return self->cur_file;
}
diff --git a/demos/spiv/image_list.h b/demos/spiv/image_list.h
index e2263d0..7835526 100644
--- a/demos/spiv/image_list.h
+++ b/demos/spiv/image_list.h
@@ -80,12 +80,12 @@ unsigned int image_list_count(struct image_list *self);
unsigned int image_list_pos(struct image_list *self);
/*
- * Returns numbe of images in current dir or 1 if current arg is file.
+ * Returns numbe of images in current dir or 0 if current arg is file.
*/
unsigned int image_list_dir_count(struct image_list *self);
/*
- * Returns current position in current dir or 1 if current arg is file.
+ * Returns current position in current dir or 0 if current arg is file.
*/
unsigned int image_list_dir_pos(struct image_list *self);
http://repo.or.cz/w/gfxprim.git/commit/fbeb1a090772e74c6b8fefa7d46a80be0391…
commit fbeb1a090772e74c6b8fefa7d46a80be03914aab
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Thu Aug 22 17:52:57 2013 +0200
filters: Resize: Two fixes.
Two fixes for the resize cleanup:
* Remove now nonexistent GP_FilterResize_Raw from the header
* Fix the order or paramters in demos
(it's w, h, interp_type now not the other way)
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/grinder/grinder.c b/demos/grinder/grinder.c
index d81cf9f..c406ef5 100644
--- a/demos/grinder/grinder.c
+++ b/demos/grinder/grinder.c
@@ -124,7 +124,7 @@ static int resize(GP_Context **c, const char *params)
GP_Size h = ratio * (*c)->h;
GP_Context *res = NULL;
- res = GP_FilterResizeAlloc(*c, alg, w, h, progress_callback);
+ res = GP_FilterResizeAlloc(*c, w, h, alg, progress_callback);
if (res == NULL)
return EINVAL;
@@ -187,7 +187,7 @@ static int scale(GP_Context **c, const char *params)
GP_Context *res = NULL;
- res = GP_FilterResizeAlloc(*c, alg, w, h, progress_callback);
+ res = GP_FilterResizeAlloc(*c, w, h, alg, progress_callback);
if (res == NULL)
return EINVAL;
diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c
index 1736b4d..2d4e4ef 100644
--- a/demos/spiv/spiv.c
+++ b/demos/spiv/spiv.c
@@ -452,9 +452,9 @@ GP_Context *load_resized_image(struct loader_params *params, GP_Size w, GP_Size
cpu_timer_start(&timer, "Resampling");
callback.priv = "Resampling Image";
- GP_Context *i1 = GP_FilterResizeAlloc(img, params->resampling_method, w, h, &callback);
+ GP_Context *i1 = GP_FilterResizeAlloc(img, w, h, params->resampling_method, &callback);
// img->gamma = NULL;
-// GP_Context *i2 = GP_FilterResizeAlloc(img, params->resampling_method, w, h, &callback);
+// GP_Context *i2 = GP_FilterResizeAlloc(img, w, h, params->resampling_method, &callback);
// img = GP_FilterDifferenceAlloc(i2, i1, NULL);
// img = GP_FilterInvert(img, NULL, NULL);
img = i1;
diff --git a/include/filters/GP_Resize.h b/include/filters/GP_Resize.h
index 179d88c..18f4958 100644
--- a/include/filters/GP_Resize.h
+++ b/include/filters/GP_Resize.h
@@ -68,13 +68,6 @@ typedef enum GP_InterpolationType {
const char *GP_InterpolationTypeName(enum GP_InterpolationType interp_type);
/*
- * Just interpolate the source context into destination context.
- */
-int GP_FilterResize_Raw(const GP_Context *src, GP_Context *dst,
- GP_InterpolationType type,
- GP_ProgressCallback *callback);
-
-/*
* Resize src to fit the dst, both src and dst must have the same pixel_type.
*
* Returns non-zero on error (interrupted from callback), zero on success.
-----------------------------------------------------------------------
Summary of changes:
demos/grinder/grinder.c | 4 +-
demos/py_simple/blur.py | 2 +-
demos/py_simple/dither.py | 2 +-
demos/py_simple/progress_callback.py | 2 +-
demos/py_simple/{rotate90.py => resize.py} | 4 +-
demos/py_simple/rotate90.py | 2 +-
demos/spiv/image_list.c | 4 +-
demos/spiv/image_list.h | 4 +-
demos/spiv/spiv.c | 4 +-
include/filters/GP_Resize.h | 7 --
libs/filters/GP_ResizeCubicFloat.c | 5 +-
libs/loaders/GP_JPG.c | 16 +++-
pylib/gfxprim/filters/__init__.py | 40 ++++++++-
pylib/gfxprim/filters/filters.i | 124 +++++++++++++++++-----------
14 files changed, 144 insertions(+), 76 deletions(-)
copy demos/py_simple/{rotate90.py => resize.py} (80%)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
20 Aug '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 59508f340d3fd1d02e11371c913d4e7656f8ce4f (commit)
via c99c44f51072de292b49f4d0ba38d0e9caa82def (commit)
from 947b2af03a9283240687cdfb2ecc4e855893ad9a (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/59508f340d3fd1d02e11371c913d4e7656f8…
commit 59508f340d3fd1d02e11371c913d4e7656f8ce4f
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Tue Aug 20 00:58:57 2013 +0200
filters: Cleanup Resize filters + docs.
This is a major cleanup in resize filters implementation.
The only visible change is that the GP_FilterResize() is split into
allocating and non-allocating filter (as rest of the API was quite a
time ago). The rest of the changes mostly shuffles code and headers.
This commit also fixes the python wrappings for resize filters.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/build/syms/Filters_symbols.txt b/build/syms/Filters_symbols.txt
index f523674..839c437 100644
--- a/build/syms/Filters_symbols.txt
+++ b/build/syms/Filters_symbols.txt
@@ -75,8 +75,6 @@ GP_FilterHistogram
GP_FilterHistogramAlloc
GP_FilterHistogram_Raw
-GP_FilterInterpolate_Cubic
-
GP_FilterInvert
GP_FilterInvert_Raw
@@ -137,23 +135,13 @@ GP_FilterPoint
GP_FilterPoint_Raw
GP_FilterResize
-GP_FilterResize_Raw
+GP_FilterResizeAlloc
GP_FilterResizeLinearInt
-GP_FilterResizeLinearIntAlloc
-GP_FilterResizeLinearInt_Raw
-
GP_FilterResizeLinearLFInt
-GP_FilterResizeLinearLFIntAlloc
-GP_FilterResizeLinearLFInt_Raw
-
-GP_FilterResizeCubicInt
-GP_FilterResizeCubicIntAlloc
-GP_FilterResizeCubicInt_Raw
-
GP_FilterResizeNN
-GP_FilterResizeNNAlloc
-GP_FilterResizeNN_Raw
+GP_FilterResizeCubicInt
+GP_FilterResizeCubic
GP_FilterRotate180
GP_FilterRotate180Alloc
diff --git a/demos/grinder/grinder.c b/demos/grinder/grinder.c
index 6bdf006..d81cf9f 100644
--- a/demos/grinder/grinder.c
+++ b/demos/grinder/grinder.c
@@ -124,7 +124,7 @@ static int resize(GP_Context **c, const char *params)
GP_Size h = ratio * (*c)->h;
GP_Context *res = NULL;
- res = GP_FilterResize(*c, NULL, alg, w, h, progress_callback);
+ res = GP_FilterResizeAlloc(*c, alg, w, h, progress_callback);
if (res == NULL)
return EINVAL;
@@ -187,7 +187,7 @@ static int scale(GP_Context **c, const char *params)
GP_Context *res = NULL;
- res = GP_FilterResize(*c, NULL, alg, w, h, progress_callback);
+ res = GP_FilterResizeAlloc(*c, alg, w, h, progress_callback);
if (res == NULL)
return EINVAL;
@@ -986,6 +986,10 @@ static void save_by_fmt(struct GP_Context *bitmap, const char *name, const char
ret = GP_SaveJPG(bitmap, name, progress_callback);
else if (!strcmp(fmt, "png"))
ret = GP_SavePNG(bitmap, name, progress_callback);
+ else {
+ printf("Invalid format %sn", fmt);
+ exit(1);
+ }
if (ret) {
fprintf(stderr, "Failed to save bitmap: %sn",
diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c
index 66284ba..1736b4d 100644
--- a/demos/spiv/spiv.c
+++ b/demos/spiv/spiv.c
@@ -437,8 +437,8 @@ GP_Context *load_resized_image(struct loader_params *params, GP_Size w, GP_Size
cpu_timer_start(&timer, "Blur");
callback.priv = "Blurring Image";
- res = GP_FilterGaussianBlurAlloc(img, 0.3/params->rat,
- 0.3/params->rat, &callback);
+ res = GP_FilterGaussianBlurAlloc(img, 0.4/params->rat,
+ 0.4/params->rat, &callback);
if (res == NULL)
return NULL;
@@ -452,9 +452,9 @@ GP_Context *load_resized_image(struct loader_params *params, GP_Size w, GP_Size
cpu_timer_start(&timer, "Resampling");
callback.priv = "Resampling Image";
- GP_Context *i1 = GP_FilterResize(img, NULL, params->resampling_method, w, h, &callback);
+ GP_Context *i1 = GP_FilterResizeAlloc(img, params->resampling_method, w, h, &callback);
// img->gamma = NULL;
-// GP_Context *i2 = GP_FilterResize(img, NULL, params->resampling_method, w, h, &callback);
+// GP_Context *i2 = GP_FilterResizeAlloc(img, params->resampling_method, w, h, &callback);
// img = GP_FilterDifferenceAlloc(i2, i1, NULL);
// img = GP_FilterInvert(img, NULL, NULL);
img = i1;
@@ -844,7 +844,8 @@ int main(int argc, char *argv[])
if (params.resampling_method > GP_INTERP_MAX)
params.resampling_method = 0;
-
+ if (params.resampling_method == GP_INTERP_CUBIC)
+ params.resampling_method++;
if (params.resampling_method == GP_INTERP_LINEAR_LF_INT) {
params.use_low_pass = 0;
params.show_nn_first = 0;
@@ -861,7 +862,8 @@ int main(int argc, char *argv[])
params.resampling_method = GP_INTERP_MAX;
else
params.resampling_method--;
-
+ if (params.resampling_method == GP_INTERP_CUBIC)
+ params.resampling_method--;
if (params.resampling_method == GP_INTERP_LINEAR_LF_INT) {
params.use_low_pass = 0;
params.show_nn_first = 0;
diff --git a/doc/Makefile b/doc/Makefile
index cf80c1c..9ec16a1 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -3,7 +3,7 @@ SOURCES=general.txt context.txt loaders.txt filters.txt basic_types.txt environment_variables.txt debug.txt core.txt api.txt input.txt gen.txt pixels.txt coordinate_system.txt coding_style.txt get_put_pixel.txt blits.txt progress_callback.txt text_api.txt - event_queue.txt compilation.txt
+ event_queue.txt compilation.txt filters_resize.txt
SOURCES+=core_python.txt gfx_python.txt loaders_python.txt backends_python.txt
diff --git a/doc/filters.txt b/doc/filters.txt
index 106be48..c456bf5 100644
--- a/doc/filters.txt
+++ b/doc/filters.txt
@@ -874,35 +874,7 @@ filter before image is resampled non proportionally.
Interpolation filters
~~~~~~~~~~~~~~~~~~~~~
-[source,c]
--------------------------------------------------------------------------------
-#include <GP_Filters.h>
-
-typedef enum GP_InterpolationType {
- GP_INTERP_NN, /* Nearest Neighbour */
- GP_INTERP_LINEAR_INT, /* Bilinear - fixed point arithmetics */
- GP_INTERP_LINEAR_LF_INT, /* Bilinear + low pass filter on downscaling */
- GP_INTERP_CUBIC, /* Bicubic */
- GP_INTERP_CUBIC_INT, /* Bicubic - fixed point arithmetics */
- GP_INTERP_MAX = GP_INTERP_CUBIC_INT,
-} GP_InterpolationType;
-
-GP_Context *GP_FilterResize(const GP_Context *src, GP_Context *dst,
- GP_InterpolationType type,
- GP_Size w, GP_Size h,
- GP_ProgressCallback *callback);
--------------------------------------------------------------------------------
-
-Interpolate (resize) the context.
-
-Doesn't work 'in-place' (this is quite impossible as the size of the bitmap is
-changed by the filter).
-
-If the filter destination is non 'NULL' and the 'w' and 'h' is smaller than the
-destination size the source image is interpolated into sub-context of
-destination defined by 'w' and 'h'.
-
-'TODO:' this filter is implemented for RGB888 only.
+Filters to link:filters_resize.html[resize image].
Nearest Neighbour Interpolation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/filters_resize.txt b/doc/filters_resize.txt
new file mode 100644
index 0000000..0331077
--- /dev/null
+++ b/doc/filters_resize.txt
@@ -0,0 +1,139 @@
+Resize filters
+--------------
+
+Common API
+~~~~~~~~~~
+
+[source,c]
+-------------------------------------------------------------------------------
+#include <GP.h>
+/* or */
+#include <filters/GP_Resize.h>
+
+typedef enum GP_InterpolationType {
+ GP_INTERP_NN, /* Nearest Neighbour */
+ GP_INTERP_LINEAR_INT, /* Bilinear - fixed point arithmetics */
+ GP_INTERP_LINEAR_LF_INT, /* Bilinear + low pass filter on downscaling */
+ GP_INTERP_CUBIC, /* Bicubic */
+ GP_INTERP_CUBIC_INT, /* Bicubic - fixed point arithmetics */
+ GP_INTERP_MAX = GP_INTERP_CUBIC_INT,
+} GP_InterpolationType;
+
+const char *GP_InterpolationTypeName(enum GP_InterpolationType interp_type);
+
+int GP_FilterResize(const GP_Context *src, GP_Context *dst,
+ GP_InterpolationType type,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterResizeAlloc(const GP_Context *src,
+ GP_Size w, GP_Size h,
+ GP_InterpolationType type,
+ GP_ProgressCallback *callback);
+-------------------------------------------------------------------------------
+
+Interpolate (resize) the context.
+
+Resize image given size and interpolation type.
+
+GP_FilterResize
+^^^^^^^^^^^^^^^
+
+The +GP_FilterReize()+ function resizes 'src' to fit 'dst' exactly.
+
+Both 'src' and 'dst' must have the same pixel type.
+
+Returns zero on success, non-zero on failure and sets 'errno'.
+
+GP_FilterResizeAlloc
+^^^^^^^^^^^^^^^^^^^^
+
+The +GP_FilterResizeAlloc()+ allocates the destination give it's size.
+
+Returns pointer to newly allocated context or 'NULL' in case of failure and
+'errno' is set.
+
+Nearest Neighbour Interpolation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+[source,c]
+-------------------------------------------------------------------------------
+#include <GP.h>
+/* or */
+#include <filters/GP_ResizeNN.h>
+
+int GP_FilterResizeNN(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback);
+
+static inline GP_Context *GP_FilterResizeNNAlloc(const GP_Context *src,
+ GP_Size w, GP_Size h,
+ GP_ProgressCallback *callback);
+-------------------------------------------------------------------------------
+
+Pixel value is choosen as value of the closest pixel in the source bitmap
+(after destination coodinates are mapped to the source coordinates).
+
+Fast, but produces "pixelated" images. May however work better for images with
+sharp edges mostly consisting of big one color regions (it doesn't blur the
+result on upscaling).
+
+Is commonly used to show preview before you resample the image correctly.
+
+Bilinear Interpolation
+~~~~~~~~~~~~~~~~~~~~~~
+
+[source,c]
+-------------------------------------------------------------------------------
+#include <GP.h>
+/* or */
+#include <filters/GP_ResizeLinear.h>
+
+int GP_FilterResizeLinearInt(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback);
+
+int GP_FilterResizeLinearLFInt(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterResizeLinearIntAlloc(const GP_Context *src,
+ GP_Size w, GP_Size h,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterResizeLinearLFIntAlloc(const GP_Context *src,
+ GP_Size w, GP_Size h,
+ GP_ProgressCallback *callback);
+-------------------------------------------------------------------------------
+
+Bilinear is faster than bicubic interpolation and produces quite good results
+especially the low pass (LF) variant doesn't need additional low-pass filter
+on down-sampling.
+
+Bicubic Interpolation
+~~~~~~~~~~~~~~~~~~~~~
+
+[source,c]
+-------------------------------------------------------------------------------
+#include <GP.h>
+/* or */
+#include <filters/GP_ResizeCubic.h>
+
+int GP_FilterResizeCubicInt(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback);
+
+int GP_FilterResizeCubic(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterResizeCubicIntAlloc(const GP_Context *src,
+ GP_Size w, GP_Size h,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterResizeCubicAlloc(const GP_Context *src,
+ GP_Size w, GP_Size h,
+ GP_ProgressCallback *callback);
+-------------------------------------------------------------------------------
+
+Works well as is on image upscaling. To get decent result on downscaling
+low-pass filter (Gaussian blur) must be used on original image before actual
+downscaling.
+
+To do this reasonably fast we could cheat a little: first resize big images a
+little without the low-pass filter, then apply low-pass filter and finally
+downscale it to desired size.
diff --git a/include/filters/GP_Filters.h b/include/filters/GP_Filters.h
index f79c2d2..621d232 100644
--- a/include/filters/GP_Filters.h
+++ b/include/filters/GP_Filters.h
@@ -58,6 +58,9 @@
/* Image scaling (resampling) */
#include "filters/GP_Resize.h"
+#include "filters/GP_ResizeNN.h"
+#include "filters/GP_ResizeLinear.h"
+#include "filters/GP_ResizeCubic.h"
/* Bitmap dithering */
#include "filters/GP_Dither.h"
diff --git a/include/filters/GP_Resize.h b/include/filters/GP_Resize.h
index 31b96a0..179d88c 100644
--- a/include/filters/GP_Resize.h
+++ b/include/filters/GP_Resize.h
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -56,15 +56,6 @@
#include "GP_Filter.h"
-/* Nearest Neighbour */
-int GP_FilterResizeNN(const GP_Context *src, GP_Context *dst,
- GP_ProgressCallback *callback);
-
-GP_Context *GP_FilterResizeNNAlloc(const GP_Context *src,
- GP_Size w, GP_Size h,
- GP_ProgressCallback *callback);
-
-
typedef enum GP_InterpolationType {
GP_INTERP_NN, /* Nearest Neighbour */
GP_INTERP_LINEAR_INT, /* Bilinear - fixed point arithmetics */
@@ -84,18 +75,24 @@ int GP_FilterResize_Raw(const GP_Context *src, GP_Context *dst,
GP_ProgressCallback *callback);
/*
- * If destination is non NULL, the w and h are used to create subcontext from
- * destination which is then used to interpolate the image to.
+ * Resize src to fit the dst, both src and dst must have the same pixel_type.
+ *
+ * Returns non-zero on error (interrupted from callback), zero on success.
+ */
+int GP_FilterResize(const GP_Context *src, GP_Context *dst,
+ GP_InterpolationType type,
+ GP_ProgressCallback *callback);
+
+/*
+ * Resize src to wxh, the result is allocated.
*
- * Otherwise if destination is NULL, the context of size w and h is allocated
- * and returned.
+ * Returns pointer to newly created context.
*
- * In both cases the pointer to destination or NULL in case of failure is
- * returned.
+ * Returns NULL in case of failure and errno is set correspondinlgy.
*/
-GP_Context *GP_FilterResize(const GP_Context *src, GP_Context *dst,
- GP_InterpolationType type,
- GP_Size w, GP_Size h,
- GP_ProgressCallback *callback);
+GP_Context *GP_FilterResizeAlloc(const GP_Context *src,
+ GP_Size w, GP_Size h,
+ GP_InterpolationType type,
+ GP_ProgressCallback *callback);
#endif /* FILTERS_GP_RESIZE_H */
diff --git a/include/filters/GP_Filters.h b/include/filters/GP_ResizeCubic.h
similarity index 53%
copy from include/filters/GP_Filters.h
copy to include/filters/GP_ResizeCubic.h
index f79c2d2..ebbab41 100644
--- a/include/filters/GP_Filters.h
+++ b/include/filters/GP_ResizeCubic.h
@@ -16,65 +16,40 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
- * <jiri.bluebear.dluhos(a)gmail.com> *
- * *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
/*
- GP_Context filters.
+ Bicubic interpolation.
*/
-#ifndef FILTERS_GP_FILTERS_H
-#define FILTERS_GP_FILTERS_H
-
-/* Filter per channel parameter passing interface */
-#include "filters/GP_FilterParam.h"
-
-/* Point filters, brightness, contrast ... */
-#include "filters/GP_Point.h"
-
-/* Addition, difference, min, max ... */
-#include "filters/GP_Arithmetic.h"
-
-/* Histograms, ... */
-#include "filters/GP_Stats.h"
-
-/* Image rotations (90 180 270 grads) and mirroring */
-#include "filters/GP_Rotate.h"
-
-/* Linear convolution Raw API */
-#include "filters/GP_Linear.h"
-
-/* Convolution filters */
-#include "filters/GP_Convolution.h"
-
-/* Blur filters */
-#include "filters/GP_Blur.h"
-
-/* Image scaling (resampling) */
-#include "filters/GP_Resize.h"
-
-/* Bitmap dithering */
-#include "filters/GP_Dither.h"
+#ifndef FILTERS_GP_RESIZE_CUBIC_H
+#define FILTERS_GP_RESIZE_CUBIC_H
-/* Laplace based filters */
-#include "filters/GP_Laplace.h"
+#include "GP_Filter.h"
+#include "GP_Resize.h"
-/* Median filter */
-#include "filters/GP_Median.h"
+int GP_FilterResizeCubicInt(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback);
-/* Weighted Median filter */
-#include "filters/GP_WeightedMedian.h"
+int GP_FilterResizeCubic(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback);
-/* Sigma Mean filter */
-#include "filters/GP_Sigma.h"
+static inline GP_Context *GP_FilterResizeCubicIntAlloc(const GP_Context *src,
+ GP_Size w, GP_Size h,
+ GP_ProgressCallback *callback)
+{
+ return GP_FilterResizeAlloc(src, w, h, GP_INTERP_CUBIC_INT, callback);
+}
-/* Gaussian noise filter */
-#include "filters/GP_GaussianNoise.h"
+static inline GP_Context *GP_FilterResizeCubicAlloc(const GP_Context *src,
+ GP_Size w, GP_Size h,
+ GP_ProgressCallback *callback)
+{
+ return GP_FilterResizeAlloc(src, w, h, GP_INTERP_CUBIC, callback);
+}
-#endif /* FILTERS_GP_FILTERS_H */
+#endif /* FILTERS_GP_RESIZE_CUBIC_H */
diff --git a/include/filters/GP_Filters.h b/include/filters/GP_ResizeLinear.h
similarity index 53%
copy from include/filters/GP_Filters.h
copy to include/filters/GP_ResizeLinear.h
index f79c2d2..5506751 100644
--- a/include/filters/GP_Filters.h
+++ b/include/filters/GP_ResizeLinear.h
@@ -16,65 +16,40 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
- * <jiri.bluebear.dluhos(a)gmail.com> *
- * *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
/*
- GP_Context filters.
+ Bilinear interpolation.
*/
-#ifndef FILTERS_GP_FILTERS_H
-#define FILTERS_GP_FILTERS_H
-
-/* Filter per channel parameter passing interface */
-#include "filters/GP_FilterParam.h"
-
-/* Point filters, brightness, contrast ... */
-#include "filters/GP_Point.h"
-
-/* Addition, difference, min, max ... */
-#include "filters/GP_Arithmetic.h"
-
-/* Histograms, ... */
-#include "filters/GP_Stats.h"
-
-/* Image rotations (90 180 270 grads) and mirroring */
-#include "filters/GP_Rotate.h"
-
-/* Linear convolution Raw API */
-#include "filters/GP_Linear.h"
-
-/* Convolution filters */
-#include "filters/GP_Convolution.h"
-
-/* Blur filters */
-#include "filters/GP_Blur.h"
-
-/* Image scaling (resampling) */
-#include "filters/GP_Resize.h"
-
-/* Bitmap dithering */
-#include "filters/GP_Dither.h"
+#ifndef FILTERS_GP_RESIZE_LINEAR_H
+#define FILTERS_GP_RESIZE_LINEAR_H
-/* Laplace based filters */
-#include "filters/GP_Laplace.h"
+#include "GP_Filter.h"
+#include "GP_Resize.h"
-/* Median filter */
-#include "filters/GP_Median.h"
+int GP_FilterResizeLinearInt(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback);
-/* Weighted Median filter */
-#include "filters/GP_WeightedMedian.h"
+int GP_FilterResizeLinearLFInt(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback);
-/* Sigma Mean filter */
-#include "filters/GP_Sigma.h"
+static inline GP_Context *GP_FilterResizeLinearIntAlloc(const GP_Context *src,
+ GP_Size w, GP_Size h,
+ GP_ProgressCallback *callback)
+{
+ return GP_FilterResizeAlloc(src, w, h, GP_INTERP_LINEAR_INT, callback);
+}
-/* Gaussian noise filter */
-#include "filters/GP_GaussianNoise.h"
+static inline GP_Context *GP_FilterResizeLinearLFIntAlloc(const GP_Context *src,
+ GP_Size w, GP_Size h,
+ GP_ProgressCallback *callback)
+{
+ return GP_FilterResizeAlloc(src, w, h, GP_INTERP_LINEAR_LF_INT, callback);
+}
-#endif /* FILTERS_GP_FILTERS_H */
+#endif /* FILTERS_GP_RESIZE_LINEAR_H */
diff --git a/include/filters/GP_Filters.h b/include/filters/GP_ResizeNN.h
similarity index 53%
copy from include/filters/GP_Filters.h
copy to include/filters/GP_ResizeNN.h
index f79c2d2..d511702 100644
--- a/include/filters/GP_Filters.h
+++ b/include/filters/GP_ResizeNN.h
@@ -16,65 +16,30 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
- * <jiri.bluebear.dluhos(a)gmail.com> *
- * *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
/*
- GP_Context filters.
+ Nearest neighbour interpolation.
*/
-#ifndef FILTERS_GP_FILTERS_H
-#define FILTERS_GP_FILTERS_H
-
-/* Filter per channel parameter passing interface */
-#include "filters/GP_FilterParam.h"
-
-/* Point filters, brightness, contrast ... */
-#include "filters/GP_Point.h"
-
-/* Addition, difference, min, max ... */
-#include "filters/GP_Arithmetic.h"
-
-/* Histograms, ... */
-#include "filters/GP_Stats.h"
-
-/* Image rotations (90 180 270 grads) and mirroring */
-#include "filters/GP_Rotate.h"
-
-/* Linear convolution Raw API */
-#include "filters/GP_Linear.h"
-
-/* Convolution filters */
-#include "filters/GP_Convolution.h"
-
-/* Blur filters */
-#include "filters/GP_Blur.h"
-
-/* Image scaling (resampling) */
-#include "filters/GP_Resize.h"
-
-/* Bitmap dithering */
-#include "filters/GP_Dither.h"
-
-/* Laplace based filters */
-#include "filters/GP_Laplace.h"
-
-/* Median filter */
-#include "filters/GP_Median.h"
+#ifndef FILTERS_GP_RESIZE_NN_H
+#define FILTERS_GP_RESIZE_NN_H
-/* Weighted Median filter */
-#include "filters/GP_WeightedMedian.h"
+#include "GP_Filter.h"
+#include "GP_Resize.h"
-/* Sigma Mean filter */
-#include "filters/GP_Sigma.h"
+int GP_FilterResizeNN(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback);
-/* Gaussian noise filter */
-#include "filters/GP_GaussianNoise.h"
+static inline GP_Context *GP_FilterResizeNNAlloc(const GP_Context *src,
+ GP_Size w, GP_Size h,
+ GP_ProgressCallback *callback)
+{
+ return GP_FilterResizeAlloc(src, w, h, GP_INTERP_NN, callback);
+}
-#endif /* FILTERS_GP_FILTERS_H */
+#endif /* FILTERS_GP_RESIZE_NN_H */
diff --git a/libs/filters/GP_Resize.c b/libs/filters/GP_Resize.c
index 24d58a2..fa0da01 100644
--- a/libs/filters/GP_Resize.c
+++ b/libs/filters/GP_Resize.c
@@ -20,131 +20,16 @@
* *
*****************************************************************************/
-#include <math.h>
+#include <errno.h>
#include "core/GP_Context.h"
-#include "core/GP_GetPutPixel.h"
-#include "core/GP_Gamma.h"
-
#include "core/GP_Debug.h"
+#include "GP_ResizeNN.h"
+#include "GP_ResizeLinear.h"
+#include "GP_ResizeCubic.h"
#include "GP_Resize.h"
-/* See GP_ResizeNN.gen.c */
-int GP_FilterResizeNN_Raw(const GP_Context *src, GP_Context *dst,
- GP_ProgressCallback *callback);
-
-int GP_FilterResizeNN(const GP_Context *src, GP_Context *dst,
- GP_ProgressCallback *callback)
-{
- GP_ASSERT(src->pixel_type == dst->pixel_type);
-
- return GP_FilterResizeNN_Raw(src, dst, callback);
-}
-
-GP_Context *GP_FilterResizeNNAlloc(const GP_Context *src,
- GP_Size w, GP_Size h,
- GP_ProgressCallback *callback)
-{
- GP_Context *res = GP_ContextAlloc(w, h, src->pixel_type);
-
- if (res == NULL)
- return NULL;
-
- if (GP_FilterResizeNN_Raw(src, res, callback)) {
- GP_ContextFree(res);
- return NULL;
- }
-
- return res;
-}
-
-/* See GP_ResizeCubic.gen.c */
-int GP_FilterResizeCubicInt_Raw(const GP_Context *src, GP_Context *dst,
- GP_ProgressCallback *callback);
-
-int GP_FilterResizeCubicInt(const GP_Context *src, GP_Context *dst,
- GP_ProgressCallback *callback)
-{
- GP_ASSERT(src->pixel_type == dst->pixel_type);
-
- return GP_FilterResizeCubicInt_Raw(src, dst, callback);
-}
-
-GP_Context *GP_FilterResizeCubicIntAlloc(const GP_Context *src,
- GP_Size w, GP_Size h,
- GP_ProgressCallback *callback)
-{
- GP_Context *res = GP_ContextAlloc(w, h, src->pixel_type);
-
- if (res == NULL)
- return NULL;
-
- if (GP_FilterResizeCubicInt_Raw(src, res, callback)) {
- GP_ContextFree(res);
- return NULL;
- }
-
- return res;
-}
-
-/* See GP_ResizeLinear.gen.c */
-int GP_FilterResizeLinearInt_Raw(const GP_Context *src, GP_Context *dst,
- GP_ProgressCallback *callback);
-
-int GP_FilterResizeLinearLFInt_Raw(const GP_Context *src, GP_Context *dst,
- GP_ProgressCallback *callback);
-
-int GP_FilterResizeLinearInt(const GP_Context *src, GP_Context *dst,
- GP_ProgressCallback *callback)
-{
- GP_ASSERT(src->pixel_type == dst->pixel_type);
-
- return GP_FilterResizeLinearInt_Raw(src, dst, callback);
-}
-
-int GP_FilterResizeLinearLFInt(const GP_Context *src, GP_Context *dst,
- GP_ProgressCallback *callback)
-{
- GP_ASSERT(src->pixel_type == dst->pixel_type);
-
- return GP_FilterResizeLinearInt_Raw(src, dst, callback);
-}
-
-GP_Context *GP_FilterResizeLinearIntAlloc(const GP_Context *src,
- GP_Size w, GP_Size h,
- GP_ProgressCallback *callback)
-{
- GP_Context *res = GP_ContextAlloc(w, h, src->pixel_type);
-
- if (res == NULL)
- return NULL;
-
- if (GP_FilterResizeCubicInt_Raw(src, res, callback)) {
- GP_ContextFree(res);
- return NULL;
- }
-
- return res;
-}
-
-GP_Context *GP_FilterResizeLinearLFIntAlloc(const GP_Context *src,
- GP_Size w, GP_Size h,
- GP_ProgressCallback *callback)
-{
- GP_Context *res = GP_ContextAlloc(w, h, src->pixel_type);
-
- if (res == NULL)
- return NULL;
-
- if (GP_FilterResizeLinearLFInt_Raw(src, res, callback)) {
- GP_ContextFree(res);
- return NULL;
- }
-
- return res;
-}
-
static const char *interp_types[] = {
"Nearest Neighbour",
"Linear (Int)",
@@ -161,241 +46,56 @@ const char *GP_InterpolationTypeName(enum GP_InterpolationType interp_type)
return interp_types[interp_type];
}
-#define A 0.5
-
-static float cubic(float x)
-{
- if (x < 0)
- x = -x;
-
- if (x < 1)
- return (2 - A)*x*x*x + (A - 3)*x*x + 1;
-
- if (x < 2)
- return -A*x*x*x + 5*A*x*x - 8*A*x + 4*A;
-
- return 0;
-}
-
-typedef float v4sf __attribute__ ((vector_size (sizeof(float) * 4)));
-
-typedef union v4f {
- v4sf v;
- float f[4];
-} v4f;
-
-#define GP_USE_GCC_VECTOR
-
-#ifdef GP_USE_GCC_VECTOR
-#define MUL_V4SF(a, b) ({v4f ret; ret.v = (a).v * (b).v; ret;})
-#else
-#define MUL_V4SF(a, b) ({v4f ret; - ret.f[0] = (a).f[0] * (b).f[0]; - ret.f[1] = (a).f[1] * (b).f[1]; - ret.f[2] = (a).f[2] * (b).f[2]; - ret.f[3] = (a).f[3] * (b).f[3]; - ret;})
-#endif /* GP_USE_GCC_VECTOR */
-
-#define SUM_V4SF(a) ((a).f[0] + (a).f[1] + (a).f[2] + (a).f[3])
-
-#define CLAMP(val) do { - if (val < 0) - val = 0; - if (val > 255) - val = 255; -} while (0)
-
-int GP_FilterInterpolate_Cubic(const GP_Context *src, GP_Context *dst,
- GP_ProgressCallback *callback)
-{
- float col_r[src->h], col_g[src->h], col_b[src->h];
- uint32_t i, j;
-
- if (src->pixel_type != GP_PIXEL_RGB888)
- return 1;
-
- GP_DEBUG(1, "Scaling image %ux%u -> %ux%u %2.2f %2.2f",
- src->w, src->h, dst->w, dst->h,
- 1.00 * dst->w / src->w, 1.00 * dst->h / src->h);
-
- for (i = 0; i < dst->w; i++) {
- float x = (1.00 * i / (dst->w - 1)) * (src->w - 1);
- v4f cvx;
- int xi[4];
-
- xi[0] = floor(x - 1);
- xi[1] = x;
- xi[2] = x + 1;
- xi[3] = x + 2;
-
- cvx.f[0] = cubic(xi[0] - x);
- cvx.f[1] = cubic(xi[1] - x);
- cvx.f[2] = cubic(xi[2] - x);
- cvx.f[3] = cubic(xi[3] - x);
-
- if (xi[0] < 0)
- xi[0] = 0;
-
- if (xi[2] >= (int)src->w)
- xi[2] = src->w - 1;
-
- if (xi[3] >= (int)src->w)
- xi[3] = src->w - 1;
-
- /* Generate interpolated column */
- for (j = 0; j < src->h; j++) {
- v4f rv, gv, bv;
- GP_Pixel pix[4];
-
- pix[0] = GP_GetPixel_Raw_24BPP(src, xi[0], j);
- pix[1] = GP_GetPixel_Raw_24BPP(src, xi[1], j);
- pix[2] = GP_GetPixel_Raw_24BPP(src, xi[2], j);
- pix[3] = GP_GetPixel_Raw_24BPP(src, xi[3], j);
-
- rv.f[0] = GP_Pixel_GET_R_RGB888(pix[0]);
- rv.f[1] = GP_Pixel_GET_R_RGB888(pix[1]);
- rv.f[2] = GP_Pixel_GET_R_RGB888(pix[2]);
- rv.f[3] = GP_Pixel_GET_R_RGB888(pix[3]);
-
- gv.f[0] = GP_Pixel_GET_G_RGB888(pix[0]);
- gv.f[1] = GP_Pixel_GET_G_RGB888(pix[1]);
- gv.f[2] = GP_Pixel_GET_G_RGB888(pix[2]);
- gv.f[3] = GP_Pixel_GET_G_RGB888(pix[3]);
-
- bv.f[0] = GP_Pixel_GET_B_RGB888(pix[0]);
- bv.f[1] = GP_Pixel_GET_B_RGB888(pix[1]);
- bv.f[2] = GP_Pixel_GET_B_RGB888(pix[2]);
- bv.f[3] = GP_Pixel_GET_B_RGB888(pix[3]);
-
- rv = MUL_V4SF(rv, cvx);
- gv = MUL_V4SF(gv, cvx);
- bv = MUL_V4SF(bv, cvx);
-
- col_r[j] = SUM_V4SF(rv);
- col_g[j] = SUM_V4SF(gv);
- col_b[j] = SUM_V4SF(bv);
- }
-
- /* now interpolate column for new image */
- for (j = 0; j < dst->h; j++) {
- float y = (1.00 * j / (dst->h - 1)) * (src->h - 1);
- v4f cvy, rv, gv, bv;
- float r, g, b;
- int yi[4];
-
- yi[0] = floor(y - 1);
- yi[1] = y;
- yi[2] = y + 1;
- yi[3] = y + 2;
-
- cvy.f[0] = cubic(yi[0] - y);
- cvy.f[1] = cubic(yi[1] - y);
- cvy.f[2] = cubic(yi[2] - y);
- cvy.f[3] = cubic(yi[3] - y);
-
- if (yi[0] < 0)
- yi[0] = 0;
-
- if (yi[2] >= (int)src->h)
- yi[2] = src->h - 1;
-
- if (yi[3] >= (int)src->h)
- yi[3] = src->h - 1;
-
- rv.f[0] = col_r[yi[0]];
- rv.f[1] = col_r[yi[1]];
- rv.f[2] = col_r[yi[2]];
- rv.f[3] = col_r[yi[3]];
-
- gv.f[0] = col_g[yi[0]];
- gv.f[1] = col_g[yi[1]];
- gv.f[2] = col_g[yi[2]];
- gv.f[3] = col_g[yi[3]];
-
- bv.f[0] = col_b[yi[0]];
- bv.f[1] = col_b[yi[1]];
- bv.f[2] = col_b[yi[2]];
- bv.f[3] = col_b[yi[3]];
-
- rv = MUL_V4SF(rv, cvy);
- gv = MUL_V4SF(gv, cvy);
- bv = MUL_V4SF(bv, cvy);
-
- r = SUM_V4SF(rv);
- g = SUM_V4SF(gv);
- b = SUM_V4SF(bv);
-
- CLAMP(r);
- CLAMP(g);
- CLAMP(b);
-
- GP_Pixel pix = GP_Pixel_CREATE_RGB888((uint8_t)r, (uint8_t)g, (uint8_t)b);
- GP_PutPixel_Raw_24BPP(dst, i, j, pix);
- }
-
- if (GP_ProgressCallbackReport(callback, i, dst->w, dst->h))
- return 1;
- }
-
- GP_ProgressCallbackDone(callback);
- return 0;
-}
-
-int GP_FilterResize_Raw(const GP_Context *src, GP_Context *dst,
- GP_InterpolationType type,
- GP_ProgressCallback *callback)
+static int resize(const GP_Context *src, GP_Context *dst,
+ GP_InterpolationType type,
+ GP_ProgressCallback *callback)
{
switch (type) {
case GP_INTERP_NN:
- return GP_FilterResizeNN_Raw(src, dst, callback);
+ return GP_FilterResizeNN(src, dst, callback);
case GP_INTERP_LINEAR_INT:
- return GP_FilterResizeLinearInt_Raw(src, dst, callback);
+ return GP_FilterResizeLinearInt(src, dst, callback);
case GP_INTERP_LINEAR_LF_INT:
- return GP_FilterResizeLinearLFInt_Raw(src, dst, callback);
+ return GP_FilterResizeLinearLFInt(src, dst, callback);
case GP_INTERP_CUBIC:
- return GP_FilterInterpolate_Cubic(src, dst, callback);
+ return GP_FilterResizeCubic(src, dst, callback);
case GP_INTERP_CUBIC_INT:
- return GP_FilterResizeCubicInt_Raw(src, dst, callback);
+ return GP_FilterResizeCubicInt(src, dst, callback);
}
+ GP_WARN("Invalid interpolation type %u", (unsigned int)type);
+
+ errno = EINVAL;
return 1;
}
-GP_Context *GP_FilterResize(const GP_Context *src, GP_Context *dst,
- GP_InterpolationType type,
- GP_Size w, GP_Size h,
- GP_ProgressCallback *callback)
+int GP_FilterResize(const GP_Context *src, GP_Context *dst,
+ GP_InterpolationType type,
+ GP_ProgressCallback *callback)
{
- GP_Context sub, *res;
-
- if (dst == NULL) {
- res = GP_ContextAlloc(w, h, src->pixel_type);
-
- if (res == NULL)
- return NULL;
- } else {
- GP_ASSERT(src->pixel_type == dst->pixel_type,
- "The src and dst pixel types must match");
- /*
- * The size of w and h is asserted in subcontext initalization
- */
- res = GP_SubContext(dst, &sub, 0, 0, w, h);
+ if (src->pixel_type != dst->pixel_type) {
+ GP_WARN("The src and dst pixel types must match");
+ errno = EINVAL;
+ return 1;
}
- /*
- * Operation was aborted by progress callback.
- *
- * Free any alloacted data and exit.
- */
- if (GP_FilterResize_Raw(src, res, type, callback)) {
- GP_DEBUG(1, "Operation aborted");
+ return resize(src, dst, type, callback);
+}
+
+GP_Context *GP_FilterResizeAlloc(const GP_Context *src,
+ GP_Size w, GP_Size h,
+ GP_InterpolationType type,
+ GP_ProgressCallback *callback)
+{
+ GP_Context *res = GP_ContextAlloc(w, h, src->pixel_type);
- if (dst == NULL)
- GP_ContextFree(dst);
+ if (!res)
+ return NULL;
+ if (resize(src, res, type, callback)) {
+ GP_ContextFree(res);
return NULL;
}
- return dst == NULL ? res : dst;
+ return res;
}
diff --git a/libs/filters/GP_ResizeCubic.gen.c.t b/libs/filters/GP_ResizeCubic.gen.c.t
index a273d14..9120fa7 100644
--- a/libs/filters/GP_ResizeCubic.gen.c.t
+++ b/libs/filters/GP_ResizeCubic.gen.c.t
@@ -26,6 +26,7 @@
%% block body
+#include <errno.h>
#include <math.h>
#include "core/GP_Context.h"
@@ -51,9 +52,9 @@
((a)[0] + (a)[1] + (a)[2] + (a)[3])
%% for pt in pixeltypes
-%% if not pt.is_unknown() and not pt.is_palette()
+%% if not pt.is_unknown() and not pt.is_palette()
-static int GP_FilterResizeCubicInt_{{ pt.name }}_Raw(const GP_Context *src,
+static int resize_cubic_{{ pt.name }}(const GP_Context *src,
GP_Context *dst, GP_ProgressCallback *callback)
{
%% for c in pt.chanslist
@@ -194,23 +195,35 @@ static int GP_FilterResizeCubicInt_{{ pt.name }}_Raw(const GP_Context *src,
return 0;
}
-%% endif
+%% endif
%% endfor
-int GP_FilterResizeCubicInt_Raw(const GP_Context *src, GP_Context *dst,
- GP_ProgressCallback *callback)
+static int resize_cubic(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback)
{
switch (src->pixel_type) {
%% for pt in pixeltypes
- %% if not pt.is_unknown() and not pt.is_palette()
+ %% if not pt.is_unknown() and not pt.is_palette()
case GP_PIXEL_{{ pt.name }}:
- return GP_FilterResizeCubicInt_{{ pt.name }}_Raw(src, dst, callback);
+ return resize_cubic_{{ pt.name }}(src, dst, callback);
break;
- %% endif
+ %% endif
%% endfor
default:
return -1;
}
}
+int GP_FilterResizeCubicInt(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback)
+{
+ if (src->pixel_type != dst->pixel_type) {
+ GP_WARN("The src and dst pixel types must match");
+ errno = EINVAL;
+ return 1;
+ }
+
+ return resize_cubic(src, dst, callback);
+}
+
%% endblock body
diff --git a/libs/filters/GP_ResizeCubicFloat.c b/libs/filters/GP_ResizeCubicFloat.c
new file mode 100644
index 0000000..f16ab7a
--- /dev/null
+++ b/libs/filters/GP_ResizeCubicFloat.c
@@ -0,0 +1,212 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#include <math.h>
+
+#include "core/GP_Context.h"
+#include "core/GP_GetPutPixel.h"
+#include "core/GP_Gamma.h"
+
+#include "core/GP_Debug.h"
+
+#include "GP_ResizeCubic.h"
+
+#define A 0.5
+
+static float cubic(float x)
+{
+ if (x < 0)
+ x = -x;
+
+ if (x < 1)
+ return (2 - A)*x*x*x + (A - 3)*x*x + 1;
+
+ if (x < 2)
+ return -A*x*x*x + 5*A*x*x - 8*A*x + 4*A;
+
+ return 0;
+}
+
+typedef float v4sf __attribute__ ((vector_size (sizeof(float) * 4)));
+
+typedef union v4f {
+ v4sf v;
+ float f[4];
+} v4f;
+
+#define GP_USE_GCC_VECTOR
+
+#ifdef GP_USE_GCC_VECTOR
+#define MUL_V4SF(a, b) ({v4f ret; ret.v = (a).v * (b).v; ret;})
+#else
+#define MUL_V4SF(a, b) ({v4f ret; + ret.f[0] = (a).f[0] * (b).f[0]; + ret.f[1] = (a).f[1] * (b).f[1]; + ret.f[2] = (a).f[2] * (b).f[2]; + ret.f[3] = (a).f[3] * (b).f[3]; + ret;})
+#endif /* GP_USE_GCC_VECTOR */
+
+#define SUM_V4SF(a) ((a).f[0] + (a).f[1] + (a).f[2] + (a).f[3])
+
+#define CLAMP(val) do { + if (val < 0) + val = 0; + if (val > 255) + val = 255; +} while (0)
+
+int GP_FilterResizeCubic(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback)
+{
+ float col_r[src->h], col_g[src->h], col_b[src->h];
+ uint32_t i, j;
+
+ if (src->pixel_type != GP_PIXEL_RGB888 || dst->pixel_type != GP_PIXEL_RGB888)
+ return 1;
+
+ GP_DEBUG(1, "Scaling image %ux%u -> %ux%u %2.2f %2.2f",
+ src->w, src->h, dst->w, dst->h,
+ 1.00 * dst->w / src->w, 1.00 * dst->h / src->h);
+
+ for (i = 0; i < dst->w; i++) {
+ float x = (1.00 * i / (dst->w - 1)) * (src->w - 1);
+ v4f cvx;
+ int xi[4];
+
+ xi[0] = floor(x - 1);
+ xi[1] = x;
+ xi[2] = x + 1;
+ xi[3] = x + 2;
+
+ cvx.f[0] = cubic(xi[0] - x);
+ cvx.f[1] = cubic(xi[1] - x);
+ cvx.f[2] = cubic(xi[2] - x);
+ cvx.f[3] = cubic(xi[3] - x);
+
+ if (xi[0] < 0)
+ xi[0] = 0;
+
+ if (xi[2] >= (int)src->w)
+ xi[2] = src->w - 1;
+
+ if (xi[3] >= (int)src->w)
+ xi[3] = src->w - 1;
+
+ /* Generate interpolated column */
+ for (j = 0; j < src->h; j++) {
+ v4f rv, gv, bv;
+ GP_Pixel pix[4];
+
+ pix[0] = GP_GetPixel_Raw_24BPP(src, xi[0], j);
+ pix[1] = GP_GetPixel_Raw_24BPP(src, xi[1], j);
+ pix[2] = GP_GetPixel_Raw_24BPP(src, xi[2], j);
+ pix[3] = GP_GetPixel_Raw_24BPP(src, xi[3], j);
+
+ rv.f[0] = GP_Pixel_GET_R_RGB888(pix[0]);
+ rv.f[1] = GP_Pixel_GET_R_RGB888(pix[1]);
+ rv.f[2] = GP_Pixel_GET_R_RGB888(pix[2]);
+ rv.f[3] = GP_Pixel_GET_R_RGB888(pix[3]);
+
+ gv.f[0] = GP_Pixel_GET_G_RGB888(pix[0]);
+ gv.f[1] = GP_Pixel_GET_G_RGB888(pix[1]);
+ gv.f[2] = GP_Pixel_GET_G_RGB888(pix[2]);
+ gv.f[3] = GP_Pixel_GET_G_RGB888(pix[3]);
+
+ bv.f[0] = GP_Pixel_GET_B_RGB888(pix[0]);
+ bv.f[1] = GP_Pixel_GET_B_RGB888(pix[1]);
+ bv.f[2] = GP_Pixel_GET_B_RGB888(pix[2]);
+ bv.f[3] = GP_Pixel_GET_B_RGB888(pix[3]);
+
+ rv = MUL_V4SF(rv, cvx);
+ gv = MUL_V4SF(gv, cvx);
+ bv = MUL_V4SF(bv, cvx);
+
+ col_r[j] = SUM_V4SF(rv);
+ col_g[j] = SUM_V4SF(gv);
+ col_b[j] = SUM_V4SF(bv);
+ }
+
+ /* now interpolate column for new image */
+ for (j = 0; j < dst->h; j++) {
+ float y = (1.00 * j / (dst->h - 1)) * (src->h - 1);
+ v4f cvy, rv, gv, bv;
+ float r, g, b;
+ int yi[4];
+
+ yi[0] = floor(y - 1);
+ yi[1] = y;
+ yi[2] = y + 1;
+ yi[3] = y + 2;
+
+ cvy.f[0] = cubic(yi[0] - y);
+ cvy.f[1] = cubic(yi[1] - y);
+ cvy.f[2] = cubic(yi[2] - y);
+ cvy.f[3] = cubic(yi[3] - y);
+
+ if (yi[0] < 0)
+ yi[0] = 0;
+
+ if (yi[2] >= (int)src->h)
+ yi[2] = src->h - 1;
+
+ if (yi[3] >= (int)src->h)
+ yi[3] = src->h - 1;
+
+ rv.f[0] = col_r[yi[0]];
+ rv.f[1] = col_r[yi[1]];
+ rv.f[2] = col_r[yi[2]];
+ rv.f[3] = col_r[yi[3]];
+
+ gv.f[0] = col_g[yi[0]];
+ gv.f[1] = col_g[yi[1]];
+ gv.f[2] = col_g[yi[2]];
+ gv.f[3] = col_g[yi[3]];
+
+ bv.f[0] = col_b[yi[0]];
+ bv.f[1] = col_b[yi[1]];
+ bv.f[2] = col_b[yi[2]];
+ bv.f[3] = col_b[yi[3]];
+
+ rv = MUL_V4SF(rv, cvy);
+ gv = MUL_V4SF(gv, cvy);
+ bv = MUL_V4SF(bv, cvy);
+
+ r = SUM_V4SF(rv);
+ g = SUM_V4SF(gv);
+ b = SUM_V4SF(bv);
+
+ CLAMP(r);
+ CLAMP(g);
+ CLAMP(b);
+
+ GP_Pixel pix = GP_Pixel_CREATE_RGB888((uint8_t)r, (uint8_t)g, (uint8_t)b);
+ GP_PutPixel_Raw_24BPP(dst, i, j, pix);
+ }
+
+ if (GP_ProgressCallbackReport(callback, i, dst->w, dst->h))
+ return 1;
+ }
+
+ GP_ProgressCallbackDone(callback);
+ return 0;
+}
diff --git a/libs/filters/GP_ResizeLinear.gen.c.t b/libs/filters/GP_ResizeLinear.gen.c.t
index b2bfc68..958c01c 100644
--- a/libs/filters/GP_ResizeLinear.gen.c.t
+++ b/libs/filters/GP_ResizeLinear.gen.c.t
@@ -26,6 +26,8 @@
%% block body
+#include <errno.h>
+
#include "core/GP_Context.h"
#include "core/GP_GetPutPixel.h"
#include "core/GP_Gamma.h"
@@ -103,8 +105,8 @@
*
* The implementation is inspired by imlib2 downscaling algorithm.
*/
-static int GP_FilterResizeLinearLFInt_{{ pt.name }}_Raw(const GP_Context *src, GP_Context *dst,
- GP_ProgressCallback *callback)
+static int resize_lin_lf_{{ pt.name }}(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback)
{
uint32_t xmap[dst->w + 1];
uint32_t ymap[dst->h + 1];
@@ -199,7 +201,7 @@ static int GP_FilterResizeLinearLFInt_{{ pt.name }}_Raw(const GP_Context *src, G
%% for pt in pixeltypes
%% if not pt.is_unknown() and not pt.is_palette()
-static int GP_FilterResizeLinearInt_{{ pt.name }}_Raw(const GP_Context *src, GP_Context *dst,
+static int resize_lin{{ pt.name }}(const GP_Context *src, GP_Context *dst,
GP_ProgressCallback *callback)
{
uint32_t xmap[dst->w + 1];
@@ -290,24 +292,39 @@ static int GP_FilterResizeLinearInt_{{ pt.name }}_Raw(const GP_Context *src, GP_
%% endif
%% endfor
-int GP_FilterResizeLinearInt_Raw(const GP_Context *src, GP_Context *dst,
- GP_ProgressCallback *callback)
+static int resize_lin(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback)
{
switch (src->pixel_type) {
%% for pt in pixeltypes
- %% if not pt.is_unknown() and not pt.is_palette()
+ %% if not pt.is_unknown() and not pt.is_palette()
case GP_PIXEL_{{ pt.name }}:
- return GP_FilterResizeLinearInt_{{ pt.name }}_Raw(src, dst, callback);
+ return resize_lin{{ pt.name }}(src, dst, callback);
break;
- %% endif
+ %% endif
%% endfor
default:
+ GP_WARN("Invalid pixel type %s",
+ GP_PixelTypeName(src->pixel_type));
+ errno = EINVAL;
return -1;
}
}
-int GP_FilterResizeLinearLFInt_Raw(const GP_Context *src, GP_Context *dst,
- GP_ProgressCallback *callback)
+int GP_FilterResizeLinearInt(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback)
+{
+ if (src->pixel_type != dst->pixel_type) {
+ GP_WARN("The src and dst pixel types must match");
+ errno = EINVAL;
+ return 1;
+ }
+
+ return resize_lin(src, dst, callback);
+}
+
+static int resize_lin_lf2(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback)
{
float x_rat = 1.00 * dst->w / src->w;
float y_rat = 1.00 * dst->h / src->h;
@@ -321,7 +338,7 @@ int GP_FilterResizeLinearLFInt_Raw(const GP_Context *src, GP_Context *dst,
%% for pt in pixeltypes
%% if not pt.is_unknown() and not pt.is_palette()
case GP_PIXEL_{{ pt.name }}:
- return GP_FilterResizeLinearLFInt_{{ pt.name }}_Raw(src, dst, callback);
+ return resize_lin_lf_{{ pt.name }}(src, dst, callback);
break;
%% endif
%% endfor
@@ -333,7 +350,19 @@ int GP_FilterResizeLinearLFInt_Raw(const GP_Context *src, GP_Context *dst,
//TODO: x_rat > 1.00 && y_rat < 1.00
//TODO: x_rat < 1.00 && y_rat > 1.00
- return GP_FilterResizeLinearInt_Raw(src, dst, callback);
+ return resize_lin(src, dst, callback);
+}
+
+int GP_FilterResizeLinearLFInt(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback)
+{
+ if (src->pixel_type != dst->pixel_type) {
+ GP_WARN("The src and dst pixel types must match");
+ errno = EINVAL;
+ return 1;
+ }
+
+ return resize_lin_lf2(src, dst, callback);
}
%% endblock body
diff --git a/libs/filters/GP_ResizeNN.gen.c.t b/libs/filters/GP_ResizeNN.gen.c.t
index 55eb34d..4874288 100644
--- a/libs/filters/GP_ResizeNN.gen.c.t
+++ b/libs/filters/GP_ResizeNN.gen.c.t
@@ -26,18 +26,20 @@
%% block body
+#include <errno.h>
+
#include "core/GP_Context.h"
#include "core/GP_GetPutPixel.h"
#include "core/GP_Debug.h"
-#include "GP_Resize.h"
+#include "GP_ResizeNN.h"
%% for pt in pixeltypes
-%% if not pt.is_unknown()
+%% if not pt.is_unknown()
-static int GP_FilterResizeNN_{{ pt.name }}_Raw(const GP_Context *src,
- GP_Context *dst, GP_ProgressCallback *callback)
+static int resize_nn{{ pt.name }}(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback)
{
uint32_t xmap[dst->w];
uint32_t ymap[dst->h];
@@ -50,7 +52,7 @@ static int GP_FilterResizeNN_{{ pt.name }}_Raw(const GP_Context *src,
/* Pre-compute mapping for interpolation */
for (i = 0; i < dst->w; i++)
- xmap[i] = ((((i * (src->w - 1))<<8) + (dst->w - 1)/2) / (dst->w - 1) + (1<<7))>>8;
+ xmap[i] = ((((i * (src->w - 1))<<8)) / (dst->w - 1) + (1<<7))>>8;
for (i = 0; i < dst->h; i++)
ymap[i] = ((((i * (src->h - 1))<<8) + (dst->h - 1)/2) / (dst->h - 1) + (1<<7))>>8;
@@ -63,31 +65,45 @@ static int GP_FilterResizeNN_{{ pt.name }}_Raw(const GP_Context *src,
GP_PutPixel_Raw_{{ pt.pixelsize.suffix }}(dst, x, y, pix);
}
- if (GP_ProgressCallbackReport(callback, y, dst->h, dst->w))
+ if (GP_ProgressCallbackReport(callback, y, dst->h, dst->w)) {
+ errno = ECANCELED;
return 1;
+ }
}
GP_ProgressCallbackDone(callback);
return 0;
}
-%% endif
+%% endif
%% endfor
-int GP_FilterResizeNN_Raw(const GP_Context *src, GP_Context *dst,
- GP_ProgressCallback *callback)
+static int resize_nn(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback)
{
switch (src->pixel_type) {
%% for pt in pixeltypes
- %% if not pt.is_unknown()
+ %% if not pt.is_unknown()
case GP_PIXEL_{{ pt.name }}:
- return GP_FilterResizeNN_{{ pt.name }}_Raw(src, dst, callback);
+ return resize_nn{{ pt.name }}(src, dst, callback);
break;
- %% endif
+ %% endif
%% endfor
default:
return -1;
}
}
+int GP_FilterResizeNN(const GP_Context *src, GP_Context *dst,
+ GP_ProgressCallback *callback)
+{
+ if (src->pixel_type != dst->pixel_type) {
+ GP_WARN("The src and dst pixel types must match");
+ errno = EINVAL;
+ return 1;
+ }
+
+ return resize_nn(src, dst, callback);
+}
+
%% endblock body
diff --git a/pylib/gfxprim/filters/filters.i b/pylib/gfxprim/filters/filters.i
index 6adf8a7..d803993 100644
--- a/pylib/gfxprim/filters/filters.i
+++ b/pylib/gfxprim/filters/filters.i
@@ -6,17 +6,31 @@
#include "core/GP_Debug.h"
%}
-%import ../core/core.i
-
-%include "GP_Filters.h"
-
/* Listed in GP_Filters.h: */
%include "GP_Point.h"
%ignore GP_Histogram::hist;
%include "GP_Stats.h"
%include "GP_Linear.h"
+
+/* Resize filters */
+ERROR_ON_NONZERO(GP_FilterResize);
+%newobject GP_FilterResizeAlloc;
+ERROR_ON_NULL(GP_FilterResizeAlloc);
%include "GP_Resize.h"
+ERROR_ON_NONZERO(GP_FilterResizeNN);
+%newobject GP_FilterResizeNNAlloc;
+ERROR_ON_NULL(GP_FilterResizeNNAlloc);
+%include "GP_ResizeNN.h"
+
+ERROR_ON_NONZERO(GP_FilterResizeLinearInt);
+%newobject GP_FilterResizeLinearIntAlloc;
+ERROR_ON_NULL(GP_FilterResizeLinearIntAlloc);
+ERROR_ON_NONZERO(GP_FilterResizeLinearLFInt);
+%newobject GP_FilterResizeLinearLFIntAlloc;
+ERROR_ON_NULL(GP_FilterResizeLinearLFIntAlloc);
+%include "GP_ResizeLinear.h"
+
%extend GP_FilterParam {
~GP_FilterParam() {
GP_DEBUG(2, "[wrapper] GP_FilterParamFree");
http://repo.or.cz/w/gfxprim.git/commit/c99c44f51072de292b49f4d0ba38d0e9caa8…
commit c99c44f51072de292b49f4d0ba38d0e9caa82def
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Aug 19 20:25:23 2013 +0200
build: Update Loaders symbols (Add JP2 funcs)
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/build/syms/Loaders_symbols.txt b/build/syms/Loaders_symbols.txt
index 1814807..9a933e7 100644
--- a/build/syms/Loaders_symbols.txt
+++ b/build/syms/Loaders_symbols.txt
@@ -55,6 +55,11 @@ GP_LoadPNM
GP_SavePNM
GP_MatchPNM
+GP_ReadJP2
+GP_OpenJP2
+GP_LoadJP2
+GP_MatchJP2
+
GP_SaveTmpFile
GP_LoadTmpFile
-----------------------------------------------------------------------
Summary of changes:
build/syms/Filters_symbols.txt | 18 +-
build/syms/Loaders_symbols.txt | 5 +
demos/grinder/grinder.c | 8 +-
demos/spiv/spiv.c | 14 +-
doc/Makefile | 2 +-
doc/filters.txt | 30 +--
doc/filters_resize.txt | 139 ++++++++
include/filters/GP_Filters.h | 3 +
include/filters/GP_Resize.h | 37 +-
.../filters/GP_ResizeCubic.h | 61 ++--
.../filters/GP_ResizeLinear.h | 61 ++--
.../filters/GP_ResizeNN.h | 26 +-
libs/filters/GP_Resize.c | 372 ++------------------
libs/filters/GP_ResizeCubic.gen.c.t | 29 ++-
libs/filters/GP_ResizeCubicFloat.c | 212 +++++++++++
libs/filters/GP_ResizeLinear.gen.c.t | 53 +++-
libs/filters/GP_ResizeNN.gen.c.t | 40 ++-
pylib/gfxprim/filters/filters.i | 22 +-
18 files changed, 595 insertions(+), 537 deletions(-)
create mode 100644 doc/filters_resize.txt
copy demos/c_simple/debug_handler.c => include/filters/GP_ResizeCubic.h (61%)
copy demos/c_simple/debug_handler.c => include/filters/GP_ResizeLinear.h (60%)
copy demos/c_simple/pretty_print.c => include/filters/GP_ResizeNN.h (75%)
create mode 100644 libs/filters/GP_ResizeCubicFloat.c
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
19 Aug '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 947b2af03a9283240687cdfb2ecc4e855893ad9a (commit)
from daafd38370880ea9d6ab72cc60735a1613c8820f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/947b2af03a9283240687cdfb2ecc4e855893…
commit 947b2af03a9283240687cdfb2ecc4e855893ad9a
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Aug 19 11:50:31 2013 +0200
loaders: JP2: Add missing stub.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_JP2.c b/libs/loaders/GP_JP2.c
index 7c7070b..2a8d11d 100644
--- a/libs/loaders/GP_JP2.c
+++ b/libs/loaders/GP_JP2.c
@@ -272,4 +272,11 @@ GP_Context *GP_ReadJP2(FILE GP_UNUSED(*f),
return NULL;
}
+GP_Context *GP_LoadJP2(const char GP_UNUSED(*src_path),
+ GP_ProgressCallback GP_UNUSED(*callback))
+{
+ errno = ENOSYS;
+ return NULL;
+}
+
#endif /* HAVE_OPENJPEG */
-----------------------------------------------------------------------
Summary of changes:
libs/loaders/GP_JP2.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
18 Aug '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via daafd38370880ea9d6ab72cc60735a1613c8820f (commit)
from bc90b8ca4857bb02db99601f3022907a08d7719d (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/daafd38370880ea9d6ab72cc60735a1613c8…
commit daafd38370880ea9d6ab72cc60735a1613c8820f
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Aug 18 23:33:33 2013 +0200
filters: Templatize linear convolutions.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/filters/GP_LinearConvolution.c b/libs/filters/GP_LinearConvolution.c
new file mode 100644
index 0000000..8709407
--- /dev/null
+++ b/libs/filters/GP_LinearConvolution.c
@@ -0,0 +1,97 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#include "core/GP_Context.h"
+#include "core/GP_Debug.h"
+
+#include "GP_Linear.h"
+
+static int h_callback(GP_ProgressCallback *self)
+{
+ GP_ProgressCallback *callback = self->priv;
+
+ callback->percentage = self->percentage / 2;
+ return callback->callback(callback);
+}
+
+static int v_callback(GP_ProgressCallback *self)
+{
+ GP_ProgressCallback *callback = self->priv;
+
+ callback->percentage = self->percentage / 2 + 50;
+ return callback->callback(callback);
+}
+
+int GP_FilterVHLinearConvolution_Raw(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ GP_Context *dst,
+ GP_Coord x_dst, GP_Coord y_dst,
+ float hkernel[], uint32_t kw, float hkern_div,
+ float vkernel[], uint32_t kh, float vkern_div,
+ GP_ProgressCallback *callback)
+{
+ GP_ProgressCallback *new_callback;
+
+ GP_ProgressCallback conv_callback = {
+ .callback = h_callback,
+ .priv = callback,
+ };
+
+ return 0;
+ new_callback = callback ? &conv_callback : NULL;
+
+ if (GP_FilterVLinearConvolution_Raw(src, x_src, y_src, w_src, h_src,
+ dst, x_dst, y_dst,
+ hkernel, kw, hkern_div,
+ new_callback))
+ return 1;
+
+ conv_callback.callback = v_callback;
+
+ if (GP_FilterHLinearConvolution_Raw(dst, x_src, y_src, w_src, h_src,
+ dst, x_dst, y_dst,
+ vkernel, kh, vkern_div,
+ new_callback))
+ return 1;
+
+ GP_ProgressCallbackDone(callback);
+ return 0;
+}
+
+void GP_FilterKernelPrint_Raw(float kernel[], int kw, int kh, float kern_div)
+{
+ int i, j;
+
+ for (i = 0; i < kw; i++) {
+
+ if (i == kw/2)
+ printf("% 8.2f * | ", 1/kern_div);
+ else
+ printf(" | ");
+
+ for (j = 0; j < kh; j++)
+ printf("% 8.2f ", kernel[j + i * kw]);
+
+ printf("|n");
+ }
+}
diff --git a/libs/filters/GP_Linear.c b/libs/filters/GP_LinearConvolution.gen.c.t
similarity index 52%
rename from libs/filters/GP_Linear.c
rename to libs/filters/GP_LinearConvolution.gen.c.t
index 5956b09..2a7337c 100644
--- a/libs/filters/GP_Linear.c
+++ b/libs/filters/GP_LinearConvolution.gen.c.t
@@ -16,24 +16,32 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
+%% extends "filter.c.t"
+
+{% block descr %}Linear Convolution{% endblock %}
+
+%% block body
+
#include <errno.h>
#include "core/GP_Context.h"
#include "core/GP_GetPutPixel.h"
#include "core/GP_TempAlloc.h"
#include "core/GP_Clamp.h"
-
#include "core/GP_Debug.h"
#include "GP_Linear.h"
#define MUL 1024
-int GP_FilterHLinearConvolution_Raw(const GP_Context *src,
+%% for pt in pixeltypes
+%% if not pt.is_unknown() and not pt.is_palette()
+
+static int h_lin_conv_{{ pt.name }}(const GP_Context *src,
GP_Coord x_src, GP_Coord y_src,
GP_Size w_src, GP_Size h_src,
GP_Context *dst,
@@ -50,51 +58,44 @@ int GP_FilterHLinearConvolution_Raw(const GP_Context *src,
"offset %ix%i rectangle %ux%u",
kw, x_src, y_src, w_src, h_src);
- /* Not yet implemented */
- if (src->pixel_type != GP_PIXEL_RGB888) {
- errno = ENOSYS;
- return 1;
- }
-
for (i = 0; i < kw; i++)
ikernel[i] = kernel[i] * MUL + 0.5;
ikern_div = kern_div * MUL + 0.5;
/* Create temporary buffers */
- GP_TempAllocCreate(temp, 3 * size * sizeof(int));
+ GP_TempAllocCreate(temp, {{ len(pt.chanslist) }} * size * sizeof(int));
- int *R = GP_TempAllocGet(temp, size * sizeof(int));
- int *G = GP_TempAllocGet(temp, size * sizeof(int));
- int *B = GP_TempAllocGet(temp, size * sizeof(int));
+ %% for c in pt.chanslist
+ int *{{ c.name }} = GP_TempAllocGet(temp, size * sizeof(int));
+ %% endfor
/* Do horizontal linear convolution */
for (y = 0; y < (GP_Coord)h_src; y++) {
int yi = GP_MIN(y_src + y, (int)src->h - 1);
/* Fetch the whole row */
- GP_Pixel pix = GP_GetPixel_Raw_24BPP(src, 0, yi);
+ GP_Pixel pix = GP_GetPixel_Raw_{{ pt.pixelsize.suffix }}(src, 0, yi);
int xi = x_src - kw/2;
i = 0;
/* Copy border pixel until the source image starts */
while (xi <= 0 && i < size) {
- R[i] = GP_Pixel_GET_R_RGB888(pix);
- G[i] = GP_Pixel_GET_G_RGB888(pix);
- B[i] = GP_Pixel_GET_B_RGB888(pix);
-
+ %% for c in pt.chanslist
+ {{ c.name }}[i] = GP_Pixel_GET_{{ c.name }}_{{ pt.name }}(pix);
+ %% endfor
i++;
xi++;
}
/* Use as much source image pixels as possible */
while (xi < (int)src->w && i < size) {
- pix = GP_GetPixel_Raw_24BPP(src, xi, yi);
+ pix = GP_GetPixel_Raw_{{ pt.pixelsize.suffix }}(src, xi, yi);
- R[i] = GP_Pixel_GET_R_RGB888(pix);
- G[i] = GP_Pixel_GET_G_RGB888(pix);
- B[i] = GP_Pixel_GET_B_RGB888(pix);
+ %% for c in pt.chanslist
+ {{ c.name }}[i] = GP_Pixel_GET_{{ c.name }}_{{ pt.name }}(pix);
+ %% endfor
i++;
xi++;
@@ -102,36 +103,40 @@ int GP_FilterHLinearConvolution_Raw(const GP_Context *src,
/* Copy the rest the border pixel when we are out again */
while (i < size) {
- R[i] = GP_Pixel_GET_R_RGB888(pix);
- G[i] = GP_Pixel_GET_G_RGB888(pix);
- B[i] = GP_Pixel_GET_B_RGB888(pix);
+ %% for c in pt.chanslist
+ {{ c.name }}[i] = GP_Pixel_GET_{{ c.name }}_{{ pt.name }}(pix);
+ %% endfor
i++;
}
for (x = 0; x < (GP_Coord)w_src; x++) {
- int32_t r = MUL/2, g = MUL/2, b = MUL/2;
- int *pR = R + x, *pG = G + x, *pB = B + x;
+ %% for c in pt.chanslist
+ int32_t {{ c.name }}_sum = MUL/2;
+ int *p{{ c.name }} = {{ c.name }} + x;
+ %% endfor
/* count the pixel value from neighbours weighted by kernel */
for (i = 0; i < kw; i++) {
- r += (*pR++) * ikernel[i];
- g += (*pG++) * ikernel[i];
- b += (*pB++) * ikernel[i];
+ %% for c in pt.chanslist
+ {{ c.name }}_sum += (*p{{ c.name }}++) * ikernel[i];
+ %% endfor
}
/* divide the result */
- r /= ikern_div;
- g /= ikern_div;
- b /= ikern_div;
+ %% for c in pt.chanslist
+ {{ c.name }}_sum /= ikern_div;
+ %% endfor
/* and clamp just to be extra sure */
- r = GP_CLAMP(r, 0, 255);
- g = GP_CLAMP(g, 0, 255);
- b = GP_CLAMP(b, 0, 255);
-
- GP_PutPixel_Raw_24BPP(dst, x_dst + x, y_dst + y,
- GP_Pixel_CREATE_RGB888(r, g, b));
+ %% for c in pt.chanslist
+ {{ c.name }}_sum = GP_CLAMP({{ c.name }}_sum, 0, {{ c.max }});
+ %% endfor
+
+ GP_PutPixel_Raw_{{ pt.pixelsize.suffix }}(dst, x_dst + x, y_dst + y,
+ GP_Pixel_CREATE_{{ pt.name }}(
+ {{ expand_chanslist(pt, "", "_sum") }}
+ ));
}
if (GP_ProgressCallbackReport(callback, y, h_src, w_src)) {
@@ -146,7 +151,38 @@ int GP_FilterHLinearConvolution_Raw(const GP_Context *src,
return 0;
}
-int GP_FilterVLinearConvolution_Raw(const GP_Context *src,
+%% endif
+%% endfor
+
+
+int GP_FilterHLinearConvolution_Raw(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ GP_Context *dst,
+ GP_Coord x_dst, GP_Coord y_dst,
+ float kernel[], uint32_t kw, float kern_div,
+ GP_ProgressCallback *callback)
+{
+ switch (src->pixel_type) {
+ %% for pt in pixeltypes
+ %% if not pt.is_unknown() and not pt.is_palette()
+ case GP_PIXEL_{{ pt.name }}:
+ return h_lin_conv_{{ pt.name }}(src, x_src, y_src, w_src, h_src,
+ dst, x_dst, y_dst,
+ kernel, kw, kern_div, callback);
+ break;
+ %% endif
+ %% endfor
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+}
+
+%% for pt in pixeltypes
+%% if not pt.is_unknown() and not pt.is_palette()
+
+static int v_lin_conv_{{ pt.name }}(const GP_Context *src,
GP_Coord x_src, GP_Coord y_src,
GP_Size w_src, GP_Size h_src,
GP_Context *dst,
@@ -162,40 +198,30 @@ int GP_FilterVLinearConvolution_Raw(const GP_Context *src,
for (i = 0; i < kh; i++)
ikernel[i] = kernel[i] * MUL + 0.5;
- GP_DEBUG(1, "Vertical linear convolution kernel width %u "
- "offset %ix%i rectangle %ux%u",
- kh, x_src, y_src, w_src, h_src);
-
- /* Not yet implemented */
- if (src->pixel_type != GP_PIXEL_RGB888) {
- errno = ENOSYS;
- return 1;
- }
-
ikern_div = kern_div * MUL + 0.5;
/* Create temporary buffers */
- GP_TempAllocCreate(temp, 3 * size * sizeof(int));
+ GP_TempAllocCreate(temp, {{ len(pt.chanslist) }} * size * sizeof(int));
- int *R = GP_TempAllocGet(temp, size * sizeof(int));
- int *G = GP_TempAllocGet(temp, size * sizeof(int));
- int *B = GP_TempAllocGet(temp, size * sizeof(int));
+ %% for c in pt.chanslist
+ int *{{ c.name }} = GP_TempAllocGet(temp, size * sizeof(int));
+ %% endfor
/* Do vertical linear convolution */
for (x = 0; x < (GP_Coord)w_src; x++) {
int xi = GP_MIN(x_src + x, (int)src->w - 1);
/* Fetch the whole row */
- GP_Pixel pix = GP_GetPixel_Raw_24BPP(src, xi, 0);
+ GP_Pixel pix = GP_GetPixel_Raw_{{ pt.pixelsize.suffix }}(src, xi, 0);
int yi = y_src - kh/2;
i = 0;
/* Copy border pixel until the source image starts */
while (yi <= 0 && i < size) {
- R[i] = GP_Pixel_GET_R_RGB888(pix);
- G[i] = GP_Pixel_GET_G_RGB888(pix);
- B[i] = GP_Pixel_GET_B_RGB888(pix);
+ %% for c in pt.chanslist
+ {{ c.name }}[i] = GP_Pixel_GET_{{ c.name }}_{{ pt.name }}(pix);
+ %% endfor
i++;
yi++;
@@ -203,11 +229,11 @@ int GP_FilterVLinearConvolution_Raw(const GP_Context *src,
/* Use as much source image pixels as possible */
while (yi < (int)src->h && i < size) {
- pix = GP_GetPixel_Raw_24BPP(src, xi, yi);
+ pix = GP_GetPixel_Raw_{{ pt.pixelsize.suffix }}(src, xi, yi);
- R[i] = GP_Pixel_GET_R_RGB888(pix);
- G[i] = GP_Pixel_GET_G_RGB888(pix);
- B[i] = GP_Pixel_GET_B_RGB888(pix);
+ %% for c in pt.chanslist
+ {{ c.name }}[i] = GP_Pixel_GET_{{ c.name }}_{{ pt.name }}(pix);
+ %% endfor
i++;
yi++;
@@ -215,36 +241,40 @@ int GP_FilterVLinearConvolution_Raw(const GP_Context *src,
/* Copy the rest the border pixel when we are out again */
while (i < size) {
- R[i] = GP_Pixel_GET_R_RGB888(pix);
- G[i] = GP_Pixel_GET_G_RGB888(pix);
- B[i] = GP_Pixel_GET_B_RGB888(pix);
+ %% for c in pt.chanslist
+ {{ c.name }}[i] = GP_Pixel_GET_{{ c.name }}_{{ pt.name }}(pix);
+ %% endfor
i++;
}
for (y = 0; y < (GP_Coord)h_src; y++) {
- int32_t r = MUL/2, g = MUL/2, b = MUL/2;
- int *pR = R + y, *pG = G + y, *pB = B + y;
+ %% for c in pt.chanslist
+ int32_t {{ c.name }}_sum = MUL/2;
+ int *p{{ c.name }} = {{ c.name }} + y;
+ %% endfor
/* count the pixel value from neighbours weighted by kernel */
for (i = 0; i < kh; i++) {
- r += (*pR++) * ikernel[i];
- g += (*pG++) * ikernel[i];
- b += (*pB++) * ikernel[i];
+ %% for c in pt.chanslist
+ {{ c.name }}_sum += (*p{{ c.name }}++) * ikernel[i];
+ %% endfor
}
/* divide the result */
- r /= ikern_div;
- g /= ikern_div;
- b /= ikern_div;
+ %% for c in pt.chanslist
+ {{ c.name }}_sum /= ikern_div;
+ %% endfor
/* and clamp just to be extra sure */
- r = GP_CLAMP(r, 0, 255);
- g = GP_CLAMP(g, 0, 255);
- b = GP_CLAMP(b, 0, 255);
-
- GP_PutPixel_Raw_24BPP(dst, x_dst + x, y_dst + y,
- GP_Pixel_CREATE_RGB888(r, g, b));
+ %% for c in pt.chanslist
+ {{ c.name }}_sum = GP_CLAMP({{ c.name }}_sum, 0, {{ c.max }});
+ %% endfor
+
+ GP_PutPixel_Raw_{{ pt.pixelsize.suffix }}(dst, x_dst + x, y_dst + y,
+ GP_Pixel_CREATE_{{ pt.name }}(
+ {{ expand_chanslist(pt, "", "_sum") }}
+ ));
}
if (GP_ProgressCallbackReport(callback, x, w_src, h_src)) {
@@ -259,81 +289,56 @@ int GP_FilterVLinearConvolution_Raw(const GP_Context *src,
return 0;
}
-static int h_callback(GP_ProgressCallback *self)
-{
- GP_ProgressCallback *callback = self->priv;
+%% endif
+%% endfor
- callback->percentage = self->percentage / 2;
- return callback->callback(callback);
-}
-
-static int v_callback(GP_ProgressCallback *self)
+int GP_FilterVLinearConvolution_Raw(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ GP_Context *dst,
+ GP_Coord x_dst, GP_Coord y_dst,
+ float kernel[], uint32_t kh, float kern_div,
+ GP_ProgressCallback *callback)
{
- GP_ProgressCallback *callback = self->priv;
+ GP_DEBUG(1, "Vertical linear convolution kernel width %u "
+ "offset %ix%i rectangle %ux%u",
+ kh, x_src, y_src, w_src, h_src);
- callback->percentage = self->percentage / 2 + 50;
- return callback->callback(callback);
+ switch (src->pixel_type) {
+ %% for pt in pixeltypes
+ %% if not pt.is_unknown() and not pt.is_palette()
+ case GP_PIXEL_{{ pt.name }}:
+ return v_lin_conv_{{ pt.name }}(src, x_src, y_src, w_src, h_src,
+ dst, x_dst, y_dst,
+ kernel, kh, kern_div, callback);
+ break;
+ %% endif
+ %% endfor
+ default:
+ errno = EINVAL;
+ return -1;
+ }
}
-int GP_FilterVHLinearConvolution_Raw(const GP_Context *src,
- GP_Coord x_src, GP_Coord y_src,
- GP_Size w_src, GP_Size h_src,
- GP_Context *dst,
- GP_Coord x_dst, GP_Coord y_dst,
- float hkernel[], uint32_t kw, float hkern_div,
- float vkernel[], uint32_t kh, float vkern_div,
- GP_ProgressCallback *callback)
-{
- GP_ProgressCallback *new_callback;
-
- GP_ProgressCallback conv_callback = {
- .callback = h_callback,
- .priv = callback,
- };
-
- new_callback = callback ? &conv_callback : NULL;
-
- if (GP_FilterVLinearConvolution_Raw(src, x_src, y_src, w_src, h_src,
- dst, x_dst, y_dst,
- hkernel, kw, hkern_div,
- new_callback))
- return 1;
-
- conv_callback.callback = v_callback;
-
- if (GP_FilterHLinearConvolution_Raw(dst, x_src, y_src, w_src, h_src,
- dst, x_dst, y_dst,
- vkernel, kh, vkern_div,
- new_callback))
- return 1;
+%% for pt in pixeltypes
+%% if not pt.is_unknown() and not pt.is_palette()
- GP_ProgressCallbackDone(callback);
- return 0;
-}
-
-int GP_FilterLinearConvolution_Raw(const GP_Context *src,
- GP_Coord x_src, GP_Coord y_src,
- GP_Size w_src, GP_Size h_src,
- GP_Context *dst,
- GP_Coord x_dst, GP_Coord y_dst,
- float kernel[], uint32_t kw, uint32_t kh,
- float kern_div, GP_ProgressCallback *callback)
+static int lin_conv_{{ pt.name }}(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ GP_Context *dst,
+ GP_Coord x_dst, GP_Coord y_dst,
+ float kernel[], uint32_t kw, uint32_t kh,
+ float kern_div, GP_ProgressCallback *callback)
{
GP_Coord x, y;
unsigned int i, j;
- GP_DEBUG(1, "Linear convolution kernel %ix%i rectangle %ux%u",
- kw, kh, w_src, h_src);
-
- /* Not yet implemented */
- if (src->pixel_type != GP_PIXEL_RGB888) {
- errno = ENOSYS;
- return 1;
- }
-
/* Do linear convolution */
for (y = 0; y < (GP_Coord)h_src; y++) {
- uint32_t R[kw][kh], G[kw][kh], B[kw][kh];
+ %% for c in pt.chanslist
+ uint32_t {{ c.name }}[kw][kh];
+ %% endfor
GP_Pixel pix;
/* Prefill the buffer on the start */
@@ -345,18 +350,20 @@ int GP_FilterLinearConvolution_Raw(const GP_Context *src,
xi = GP_CLAMP(xi, 0, (int)src->w - 1);
yi = GP_CLAMP(yi, 0, (int)src->h - 1);
- pix = GP_GetPixel_Raw_24BPP(src, xi, yi);
+ pix = GP_GetPixel_Raw_{{ pt.pixelsize.suffix }}(src, xi, yi);
- R[i][j] = GP_Pixel_GET_R_RGB888(pix);
- G[i][j] = GP_Pixel_GET_G_RGB888(pix);
- B[i][j] = GP_Pixel_GET_B_RGB888(pix);
+ %% for c in pt.chanslist
+ {{ c.name }}[i][j] = GP_Pixel_GET_{{ c.name }}_{{ pt.name }}(pix);
+ %% endfor
}
}
int idx = kw - 1;
for (x = 0; x < (GP_Coord)w_src; x++) {
- float r = 0, g = 0, b = 0;
+ %% for c in pt.chanslist
+ float {{ c.name }}_sum = 0;
+ %% endfor
for (j = 0; j < kh; j++) {
int xi = x_src + x + kw/2;
@@ -365,11 +372,11 @@ int GP_FilterLinearConvolution_Raw(const GP_Context *src,
xi = GP_CLAMP(xi, 0, (int)src->w - 1);
yi = GP_CLAMP(yi, 0, (int)src->h - 1);
- pix = GP_GetPixel_Raw_24BPP(src, xi, yi);
+ pix = GP_GetPixel_Raw_{{ pt.pixelsize.suffix }}(src, xi, yi);
- R[idx][j] = GP_Pixel_GET_R_RGB888(pix);
- G[idx][j] = GP_Pixel_GET_G_RGB888(pix);
- B[idx][j] = GP_Pixel_GET_B_RGB888(pix);
+ %% for c in pt.chanslist
+ {{ c.name }}[idx][j] = GP_Pixel_GET_{{ c.name }}_{{ pt.name }}(pix);
+ %% endfor
}
/* Count the pixel value from neighbours weighted by kernel */
@@ -382,25 +389,25 @@ int GP_FilterLinearConvolution_Raw(const GP_Context *src,
k = i - idx - 1;
for (j = 0; j < kh; j++) {
- r += R[i][j] * kernel[k + j * kw];
- g += G[i][j] * kernel[k + j * kw];
- b += B[i][j] * kernel[k + j * kw];
+ %% for c in pt.chanslist
+ {{ c.name }}_sum += {{ c.name }}[i][j] * kernel[k + j * kw];
+ %% endfor
}
}
/* divide the result */
- r /= kern_div;
- g /= kern_div;
- b /= kern_div;
+ %% for c in pt.chanslist
+ {{ c.name }}_sum /= kern_div;
+ %% endfor
/* and clamp just to be extra sure */
- r = GP_CLAMP((int)r, 0, 255);
- g = GP_CLAMP((int)g, 0, 255);
- b = GP_CLAMP((int)b, 0, 255);
+ %% for c in pt.chanslist
+ int {{ c.name }}_res = GP_CLAMP((int){{ c.name }}_sum, 0, {{ c.max }});
+ %% endfor
- pix = GP_Pixel_CREATE_RGB888((uint32_t)r, (uint32_t)g, (uint32_t)b);
+ pix = GP_Pixel_CREATE_{{ pt.name }}({{ expand_chanslist(pt, "", "_res") }});
- GP_PutPixel_Raw_24BPP(dst, x_dst + x, y_dst + y, pix);
+ GP_PutPixel_Raw_{{ pt.pixelsize.suffix }}(dst, x_dst + x, y_dst + y, pix);
idx++;
@@ -416,20 +423,34 @@ int GP_FilterLinearConvolution_Raw(const GP_Context *src,
return 0;
}
-void GP_FilterKernelPrint_Raw(float kernel[], int kw, int kh, float kern_div)
-{
- int i, j;
-
- for (i = 0; i < kw; i++) {
+%% endif
+%% endfor
- if (i == kw/2)
- printf("% 8.2f * | ", 1/kern_div);
- else
- printf(" | ");
-
- for (j = 0; j < kh; j++)
- printf("% 8.2f ", kernel[j + i * kw]);
+int GP_FilterLinearConvolution_Raw(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ GP_Context *dst,
+ GP_Coord x_dst, GP_Coord y_dst,
+ float kernel[], uint32_t kw, uint32_t kh,
+ float kern_div, GP_ProgressCallback *callback)
+{
+ GP_DEBUG(1, "Linear convolution kernel %ix%i rectangle %ux%u",
+ kw, kh, w_src, h_src);
- printf("|n");
+ switch (src->pixel_type) {
+ %% for pt in pixeltypes
+ %% if not pt.is_unknown() and not pt.is_palette()
+ case GP_PIXEL_{{ pt.name }}:
+ return lin_conv_{{ pt.name }}(src, x_src, y_src, w_src, h_src,
+ dst, x_dst, y_dst,
+ kernel, kw, kh, kern_div, callback);
+ break;
+ %% endif
+ %% endfor
+ default:
+ errno = EINVAL;
+ return -1;
}
}
+
+%% endblock body
diff --git a/libs/filters/Makefile b/libs/filters/Makefile
index e331b59..05a310e 100644
--- a/libs/filters/Makefile
+++ b/libs/filters/Makefile
@@ -13,7 +13,8 @@ RESAMPLING_FILTERS=GP_ResizeNN.gen.c GP_Cubic.gen.c GP_ResizeCubic.gen.c GP_ResizeLinear.gen.c
GENSOURCES=GP_MirrorV.gen.c GP_Rotate.gen.c GP_FloydSteinberg.gen.c GP_HilbertPeano.gen.c- $(POINT_FILTERS) $(ARITHMETIC_FILTERS) $(STATS_FILTERS) $(RESAMPLING_FILTERS)
+ $(POINT_FILTERS) $(ARITHMETIC_FILTERS) $(STATS_FILTERS) $(RESAMPLING_FILTERS)+ GP_LinearConvolution.gen.c
CSOURCES=$(filter-out $(wildcard *.gen.c),$(wildcard *.c))
LIBNAME=filters
-----------------------------------------------------------------------
Summary of changes:
libs/filters/GP_LinearConvolution.c | 97 +++++
.../{GP_Linear.c => GP_LinearConvolution.gen.c.t} | 371 +++++++++++---------
libs/filters/Makefile | 3 +-
3 files changed, 295 insertions(+), 176 deletions(-)
create mode 100644 libs/filters/GP_LinearConvolution.c
rename libs/filters/{GP_Linear.c => GP_LinearConvolution.gen.c.t} (52%)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
16 Aug '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via bc90b8ca4857bb02db99601f3022907a08d7719d (commit)
via 32c6c88ff682abfd417823b937b31dcca2c61ec0 (commit)
from e0c2b6aa02d3f2341c971399623c5b69cb409c88 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/bc90b8ca4857bb02db99601f3022907a08d7…
commit bc90b8ca4857bb02db99601f3022907a08d7719d
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Aug 16 16:48:56 2013 +0200
doc: Add LoadJP2() docs.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/doc/general.txt b/doc/general.txt
index 4179408..00dd795 100644
--- a/doc/general.txt
+++ b/doc/general.txt
@@ -103,6 +103,11 @@ images into various standard formats (PNG, JPEG, GIF, TIFF, BMP, PNM, etc...).
[green]#All but < 8bit binary grayscale# |
[green]#All ASCII formats#
+| JP2 |
+ JPEG 2000 |
+ [green]#Experimental support for RGB images# |
+ [black]*No*
+
| CBZ |
Comic book archive |
[green]#Experimental support via ZIP Container# |
diff --git a/doc/loaders.txt b/doc/loaders.txt
index fd10817..1702470 100644
--- a/doc/loaders.txt
+++ b/doc/loaders.txt
@@ -338,6 +338,23 @@ int GP_MatchJPG(const void *buf);
Matches a JPG signature.
+JPEG 2000 Loader
+~~~~~~~~~~~~~~~~
+The 'JPEG 2000' image support is implemented using the openjpeg library.
+
+[source,c]
+-------------------------------------------------------------------------------
+#include <loaders/GP_JP2.h>
+/* or */
+#include <GP.h>
+
+GP_Context *GP_LoadJP2(const char *src_path, GP_ProgressCallback *callback);
+-------------------------------------------------------------------------------
+
+Loads 'JPEG 2000' image.
+
+Due to limitations of the openjpeg library progress callback does not work.
+
GIF Loader
~~~~~~~~~~
diff --git a/doc/loaders_python.txt b/doc/loaders_python.txt
index 42dff04..00c5cef 100644
--- a/doc/loaders_python.txt
+++ b/doc/loaders_python.txt
@@ -15,6 +15,7 @@ import gfxprim.loaders as loaders
img = loaders.LoadBMP(path, callback=None)
img = loaders.LoadGIF(path, callback=None)
img = loaders.LoadJPG(path, callback=None)
+ img = loaders.LoadJP2(path, callback=None)
img = loaders.LoadPBM(path, callback=None)
img = loaders.LoadPGM(path, callback=None)
img = loaders.LoadPNG(path, callback=None)
http://repo.or.cz/w/gfxprim.git/commit/32c6c88ff682abfd417823b937b31dcca2c6…
commit 32c6c88ff682abfd417823b937b31dcca2c61ec0
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Aug 16 16:47:41 2013 +0200
pywrap: loaders: Add LoadJP2()
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/pylib/gfxprim/loaders/__init__.py b/pylib/gfxprim/loaders/__init__.py
index d1a63a6..7a1bd83 100644
--- a/pylib/gfxprim/loaders/__init__.py
+++ b/pylib/gfxprim/loaders/__init__.py
@@ -98,8 +98,8 @@ def _init(module):
from ..utils import import_members
import_members(c_loaders, module, sub=strip_GP,
include=[
- '^GP_Load[A-Z]{3}.*',
- '^GP_Save[A-Z]{3}.*',
+ '^GP_Load[A-Z,0-9]{3}.*',
+ '^GP_Save[A-Z,0-9]{3}.*',
'^GP_ListLoaders$',
'^GP_LoadMetaData$',
])
diff --git a/pylib/gfxprim/loaders/loaders.i b/pylib/gfxprim/loaders/loaders.i
index 66bd1e8..f310e74 100644
--- a/pylib/gfxprim/loaders/loaders.i
+++ b/pylib/gfxprim/loaders/loaders.i
@@ -80,7 +80,11 @@ ERROR_ON_NONZERO(GP_SaveTIFF);
%include "GP_TIFF.h"
ERROR_ON_NULL(GP_LoadPSP);
-
%newobject GP_LoadPSP;
%include "GP_PSP.h"
+
+ERROR_ON_NULL(GP_LoadJP2);
+%newobject GP_LoadJP2;
+
+%include "GP_JP2.h"
-----------------------------------------------------------------------
Summary of changes:
doc/general.txt | 5 +++++
doc/loaders.txt | 17 +++++++++++++++++
doc/loaders_python.txt | 1 +
pylib/gfxprim/loaders/__init__.py | 4 ++--
pylib/gfxprim/loaders/loaders.i | 6 +++++-
5 files changed, 30 insertions(+), 3 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
16 Aug '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via e0c2b6aa02d3f2341c971399623c5b69cb409c88 (commit)
via 40ae90ef29c62be007c9fc936fc470cc5db4f20d (commit)
via d59d05961f56e9ef30a5cc60083dcbb32017a2ae (commit)
via 147509697f74c62af9d861653379d474783b5f3d (commit)
from 130a8dec38dc497519345e822c1ff20a31844868 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/e0c2b6aa02d3f2341c971399623c5b69cb40…
commit e0c2b6aa02d3f2341c971399623c5b69cb409c88
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Wed Aug 14 22:32:42 2013 +0200
core: Pixel: Fix the double const warning.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/include/core/GP_Pixel.h b/include/core/GP_Pixel.h
index 8c060f0..bfe7d7f 100644
--- a/include/core/GP_Pixel.h
+++ b/include/core/GP_Pixel.h
@@ -122,7 +122,7 @@ typedef struct GP_PixelTypeDescription {
/*
* Array of size GP_PIXEL_MAX describing known pixel types
*/
-extern const GP_PixelTypeDescription const GP_PixelTypes[GP_PIXEL_MAX];
+extern const GP_PixelTypeDescription GP_PixelTypes[GP_PIXEL_MAX];
#define GP_VALID_PIXELTYPE(type) (((type) > 0) && ((type) < GP_PIXEL_MAX))
diff --git a/libs/core/GP_Pixel.gen.c.t b/libs/core/GP_Pixel.gen.c.t
index 96ba421..302655f 100644
--- a/libs/core/GP_Pixel.gen.c.t
+++ b/libs/core/GP_Pixel.gen.c.t
@@ -43,7 +43,7 @@ Pixel type definitions and functions
/*
* Description of all known pixel types
*/
-const GP_PixelTypeDescription const GP_PixelTypes [GP_PIXEL_MAX] = {
+const GP_PixelTypeDescription GP_PixelTypes [GP_PIXEL_MAX] = {
%% for pt in pixeltypes
/* GP_PIXEL_{{ pt.name }} */ {
.type = GP_PIXEL_{{ pt.name }},
http://repo.or.cz/w/gfxprim.git/commit/40ae90ef29c62be007c9fc936fc470cc5db4…
commit 40ae90ef29c62be007c9fc936fc470cc5db4f20d
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Wed Aug 14 22:23:40 2013 +0200
loaders: TmpFile: Fix potentionaly unitialized err
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_TmpFile.c b/libs/loaders/GP_TmpFile.c
index 3704946..0dbb5ad 100644
--- a/libs/loaders/GP_TmpFile.c
+++ b/libs/loaders/GP_TmpFile.c
@@ -166,8 +166,10 @@ int GP_SaveTmpFile(const GP_Context *src, const char *dst_path,
GP_ProgressCallbackReport(callback, y, src->h, src->w);
}
- if (fclose(f))
+ if (fclose(f)) {
+ err = errno;
goto err0;
+ }
GP_ProgressCallbackDone(callback);
http://repo.or.cz/w/gfxprim.git/commit/d59d05961f56e9ef30a5cc60083dcbb32017…
commit d59d05961f56e9ef30a5cc60083dcbb32017a2ae
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Wed Aug 14 21:09:38 2013 +0200
loaders: Experimental JPEG 2000 support.
Add experimental JPEG 2000 support using openjpeg library.
You need at least openjpeg 2.0.0, previous APIs are not usable
and even 2.0.0 doesn't seem to be finished...
But here it is, enjoy!
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/configure b/configure
index 2d41ff4..c7b7409 100755
--- a/configure
+++ b/configure
@@ -315,6 +315,9 @@ if __name__ == '__main__':
["jpeg",
"Library to load, handle and manipulate images in the JPEG format",
[header_exists, "jpeglib.h"], "", "-ljpeg", ["loaders"]],
+ ["openjpeg",
+ "An open-source JPEG 2000 library",
+ [header_exists, "openjpeg-2.0/openjpeg.h"], "", "-lopenjp2", ["loaders"]],
["giflib",
"Library to handle, display and manipulate GIF images",
[header_exists, "gif_lib.h"], "", "-lgif", ["loaders"]],
diff --git a/include/loaders/GP_Loaders.h b/include/loaders/GP_JP2.h
similarity index 70%
copy from include/loaders/GP_Loaders.h
copy to include/loaders/GP_JP2.h
index c9e9c49..7068a46 100644
--- a/include/loaders/GP_Loaders.h
+++ b/include/loaders/GP_JP2.h
@@ -16,40 +16,40 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
- * <jiri.bluebear.dluhos(a)gmail.com> *
- * *
* Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
/*
- Core include file for loaders API.
+ JPEG 2000 support using openjpeg library.
*/
-#ifndef LOADERS_GP_LOADERS_H
-#define LOADERS_GP_LOADERS_H
+#ifndef LOADERS_GP_JP2_H
+#define LOADERS_GP_JP2_H
#include "core/GP_Context.h"
#include "core/GP_ProgressCallback.h"
-#include "loaders/GP_PNM.h"
-#include "loaders/GP_BMP.h"
-#include "loaders/GP_PNG.h"
-#include "loaders/GP_JPG.h"
-#include "loaders/GP_GIF.h"
-#include "loaders/GP_TIFF.h"
-#include "loaders/GP_PSP.h"
-
-#include "loaders/GP_TmpFile.h"
+/*
+ * Opens up file and checks signature.
+ */
+int GP_OpenJP2(const char *src_path, FILE **f);
-#include "loaders/GP_MetaData.h"
+/*
+ * Reads JP2 from an open FILE.
+ */
+GP_Context *GP_ReadJP2(FILE *f, GP_ProgressCallback *callback);
-#include "loaders/GP_Loader.h"
+/*
+ * Loads a JP2 file into GP_Context. The Context is newly allocated.
+ */
+GP_Context *GP_LoadJP2(const char *src_path, GP_ProgressCallback *callback);
-#include "loaders/GP_Container.h"
-#include "loaders/GP_ZIP.h"
+/*
+ * Match JP2 signature.
+ */
+int GP_MatchJP2(const void *buf);
-#endif /* LOADERS_GP_LOADERS_H */
+#endif /* LOADERS_GP_JP2_H */
diff --git a/include/loaders/GP_Loaders.h b/include/loaders/GP_Loaders.h
index c9e9c49..0ed72af 100644
--- a/include/loaders/GP_Loaders.h
+++ b/include/loaders/GP_Loaders.h
@@ -39,6 +39,7 @@
#include "loaders/GP_BMP.h"
#include "loaders/GP_PNG.h"
#include "loaders/GP_JPG.h"
+#include "loaders/GP_JP2.h"
#include "loaders/GP_GIF.h"
#include "loaders/GP_TIFF.h"
#include "loaders/GP_PSP.h"
diff --git a/libs/loaders/GP_JP2.c b/libs/loaders/GP_JP2.c
new file mode 100644
index 0000000..7c7070b
--- /dev/null
+++ b/libs/loaders/GP_JP2.c
@@ -0,0 +1,275 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+/*
+
+ JPEG 2000 image support using openjpeg library.
+
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "../../config.h"
+#include "core/GP_Debug.h"
+#include "core/GP_GetPutPixel.h"
+
+#include "GP_JP2.h"
+
+#ifdef HAVE_OPENJPEG
+
+#include <openjpeg-2.0/openjpeg.h>
+
+#define JP2_SIG "x00x00x00x0cjPx20x20x0dx0ax87x0a"
+#define JP2_SIG_LEN 12
+
+int GP_MatchJP2(const void *buf)
+{
+ return !memcmp(buf, JP2_SIG, JP2_SIG_LEN);
+}
+
+int GP_OpenJP2(const char *src_path, FILE **f)
+{
+ int err;
+
+ *f = fopen(src_path, "rb");
+
+ if (*f == NULL) {
+ err = errno;
+ GP_DEBUG(1, "Failed to open '%s' : %s",
+ src_path, strerror(errno));
+ errno = err;
+ return 1;
+ }
+
+ //TODO: check signature and rewind the stream
+
+ return 0;
+}
+
+static void jp2_err_callback(const char *msg, void *priv)
+{
+ (void) priv;
+ GP_WARN("openjpeg: %s", msg);
+}
+
+static void jp2_warn_callback(const char *msg, void *priv)
+{
+ (void) priv;
+ GP_WARN("openjpeg: %s", msg);
+}
+
+static void jp2_info_callback(const char *msg, void *priv)
+{
+ GP_ProgressCallback *callback = priv;
+
+ GP_DEBUG(1, "openjpeg: %s", msg);
+
+ GP_ProgressCallbackReport(callback, 100, 100, 100);
+}
+
+static const char *color_space_name(OPJ_COLOR_SPACE color_space)
+{
+ switch (color_space) {
+ case OPJ_CLRSPC_UNKNOWN:
+ return "Unknown";
+ case OPJ_CLRSPC_UNSPECIFIED:
+ return "Unspecified";
+ case OPJ_CLRSPC_SRGB:
+ return "sRGB";
+ case OPJ_CLRSPC_GRAY:
+ return "Grayscale";
+ case OPJ_CLRSPC_SYCC:
+ return "YUV";
+ default:
+ return "Invalid";
+ }
+}
+
+GP_Context *GP_ReadJP2(FILE *f, GP_ProgressCallback *callback)
+{
+ opj_dparameters_t params;
+ opj_codec_t *codec;
+ opj_stream_t *stream;
+ opj_image_t *img;
+
+ GP_Context *res = NULL;
+ GP_PixelType pixel_type;
+ unsigned int i, x, y;
+ int err = 0;
+
+ opj_set_default_decoder_parameters(¶ms);
+
+ codec = opj_create_decompress(OPJ_CODEC_JP2);
+
+ if (!codec) {
+ GP_DEBUG(1, "opj_create_decompress failed");
+ err = ENOMEM;
+ goto err0;
+ }
+
+ opj_set_error_handler(codec, jp2_err_callback, NULL);
+ opj_set_warning_handler(codec, jp2_warn_callback, NULL);
+ opj_set_info_handler(codec, jp2_info_callback, callback);
+
+ if (!opj_setup_decoder(codec, ¶ms)) {
+ GP_DEBUG(1, "opj_setup_decoder failed");
+ err = ENOMEM;
+ goto err1;
+ }
+
+ stream = opj_stream_create_default_file_stream(f, OPJ_TRUE);
+
+ if (!stream) {
+ GP_DEBUG(1, "opj_stream_create_default_file_stream faled");
+ err = ENOMEM;
+ goto err1;
+ }
+
+ if (!opj_read_header(stream, codec, &img)) {
+ GP_DEBUG(1, "opj_read_header failed");
+ err = EINVAL;
+ goto err2;
+ }
+
+ GP_DEBUG(1, "Have image %ux%u-%ux%u colorspace=%s numcomps=%u",
+ img->x0, img->y0, img->x1, img->y1,
+ color_space_name(img->color_space), img->numcomps);
+
+ /*
+ * Try to match the image information into pixel type.
+ *
+ * Unfortunately the images I had have color_space set
+ * to unspecified yet they were RGB888.
+ */
+ for (i = 0; i < img->numcomps; i++) {
+ opj_image_comp_t *comp = &img->comps[i];
+
+ GP_DEBUG(2, "Component %u %ux%u bpp=%u",
+ i, comp->w, comp->h, comp->prec);
+
+ if (comp->w != img->comps[0].w ||
+ comp->h != img->comps[0].h) {
+ GP_DEBUG(1, "Component %u has different size", 1);
+ err = ENOSYS;
+ goto err3;
+ }
+
+ if (comp->prec != 8) {
+ GP_DEBUG(1, "Component %u has different bpp", 1);
+ err = ENOSYS;
+ goto err3;
+ }
+ }
+
+ switch (img->color_space) {
+ case OPJ_CLRSPC_UNSPECIFIED:
+ if (img->numcomps != 3) {
+ GP_DEBUG(1, "Unexpected number of components");
+ err = ENOSYS;
+ goto err3;
+ }
+ pixel_type = GP_PIXEL_RGB888;
+ break;
+ default:
+ GP_DEBUG(1, "Unsupported colorspace");
+ err = ENOSYS;
+ goto err3;
+ }
+
+ if (!opj_decode(codec, stream, img)) {
+ GP_DEBUG(1, "opj_decode failed");
+ err = EINVAL;
+ goto err3;
+ }
+
+ res = GP_ContextAlloc(img->comps[0].w, img->comps[0].h, pixel_type);
+
+ if (!res) {
+ GP_DEBUG(1, "Malloc failed :(");
+ err = ENOMEM;
+ goto err3;
+ }
+
+ for (y = 0; y < res->h; y++) {
+ for (x = 0; x < res->w; x++) {
+ i = y * res->w + x;
+
+ GP_Pixel p = img->comps[0].data[i] << 16|
+ img->comps[1].data[i] << 8 |
+ img->comps[2].data[i];
+
+ GP_PutPixel_Raw_24BPP(res, x, y, p);
+ }
+ }
+
+ GP_ProgressCallbackDone(callback);
+err3:
+ opj_image_destroy(img);
+err2:
+ opj_stream_destroy(stream);
+err1:
+ opj_destroy_codec(codec);
+err0:
+ if (err)
+ errno = err;
+ return res;
+}
+
+GP_Context *GP_LoadJP2(const char *src_path, GP_ProgressCallback *callback)
+{
+ FILE *f;
+ GP_Context *res;
+
+ if (GP_OpenJP2(src_path, &f))
+ return NULL;
+
+ res = GP_ReadJP2(f, callback);
+
+ fclose(f);
+
+ return res;
+}
+
+#else
+
+int GP_MatchJP2(const void GP_UNUSED(*buf))
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+int GP_OpenJP2(const char GP_UNUSED(*src_path), FILE GP_UNUSED(**f))
+{
+ errno = ENOSYS;
+ return 1;
+}
+
+GP_Context *GP_ReadJP2(FILE GP_UNUSED(*f),
+ GP_ProgressCallback GP_UNUSED(*callback))
+{
+ errno = ENOSYS;
+ return NULL;
+}
+
+#endif /* HAVE_OPENJPEG */
diff --git a/libs/loaders/GP_Loader.c b/libs/loaders/GP_Loader.c
index 4f93c3e..0abd6d5 100644
--- a/libs/loaders/GP_Loader.c
+++ b/libs/loaders/GP_Loader.c
@@ -88,12 +88,21 @@ static GP_Loader pnm_loader = {
.extensions = {"pnm", NULL},
};
+static GP_Loader jp2_loader = {
+ .Load = GP_LoadJP2,
+ .Save = NULL,
+ .Match = GP_MatchJP2,
+ .fmt_name = "JPEG 2000",
+ .next = &pnm_loader,
+ .extensions = {"jp2", "jpx", NULL},
+};
+
static GP_Loader bmp_loader = {
.Load = GP_LoadBMP,
.Save = GP_SaveBMP,
.Match = GP_MatchBMP,
.fmt_name = "BMP",
- .next = &pnm_loader,
+ .next = &jp2_loader,
.extensions = {"bmp", "dib", NULL},
};
http://repo.or.cz/w/gfxprim.git/commit/147509697f74c62af9d861653379d474783b…
commit 147509697f74c62af9d861653379d474783b5f3d
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Tue Aug 13 22:37:59 2013 +0200
loaders: ZIP: Fix errno vs err typo.
This fixes segfault on corrupted zip files.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_ZIP.c b/libs/loaders/GP_ZIP.c
index c9064b8..42d08d5 100644
--- a/libs/loaders/GP_ZIP.c
+++ b/libs/loaders/GP_ZIP.c
@@ -242,7 +242,7 @@ static int read_deflate(FILE *f, struct zip_local_header *header, FILE **res_f)
if (ret != Z_STREAM_END) {
GP_DEBUG(1, "Failed to inflate stream %i", ret);
- errno = EINVAL;
+ err = EINVAL;
goto err2;
}
-----------------------------------------------------------------------
Summary of changes:
configure | 3 +
include/core/GP_Pixel.h | 2 +-
include/loaders/{GP_ZIP.h => GP_JP2.h} | 28 +++-
include/loaders/GP_Loaders.h | 1 +
libs/core/GP_Pixel.gen.c.t | 2 +-
libs/loaders/GP_JP2.c | 275 ++++++++++++++++++++++++++++++++
libs/loaders/GP_Loader.c | 11 ++-
libs/loaders/GP_TmpFile.c | 4 +-
libs/loaders/GP_ZIP.c | 2 +-
9 files changed, 316 insertions(+), 12 deletions(-)
copy include/loaders/{GP_ZIP.h => GP_JP2.h} (76%)
create mode 100644 libs/loaders/GP_JP2.c
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
11 Aug '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 130a8dec38dc497519345e822c1ff20a31844868 (commit)
via 30f8839e5cb0abf4f3f3ba80a3e4e2f548f485a5 (commit)
via cec1288490c39f429c72a4ccd82b261434a5c18f (commit)
via 7eb65dcf3a902658aab5ca04bbf801bd77ff9379 (commit)
via 94f18b7b1f75a971cea5cdf9ea57f8c23d4f1522 (commit)
via e1c9bd3da48fa7a992e807c44cb897a3e22f26bd (commit)
from 5d493cb045b66ed27d9136ea524b1e3184732451 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/130a8dec38dc497519345e822c1ff20a3184…
commit 130a8dec38dc497519345e822c1ff20a31844868
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Aug 11 20:06:26 2013 +0200
backends: BackendInit: Add SDL bpp param.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/backends/GP_BackendInit.c b/libs/backends/GP_BackendInit.c
index 5a601a0..a9c887f 100644
--- a/libs/backends/GP_BackendInit.c
+++ b/libs/backends/GP_BackendInit.c
@@ -38,19 +38,43 @@ static void backend_sdl_help(FILE *help, const char *err)
fprintf(help, "libSDL backendn"
"--------------n"
- "SDL:[FS]:[WxH]n"
+ "SDL:[FS]:[8]:[16]:[24]:[32]:[WxH]n"
" FS - Full Screen moden"
+ " 8 - Sets 8bppn"
+ " 16 - Sets 16bppn"
+ " 24 - Sets 24bppn"
+ " 32 - Sets 32bppn"
" WxH - Display Sizen");
}
static int sdl_params_to_flags(const char *param, GP_Size *w, GP_Size *h,
- uint8_t *flags, FILE *help)
+ GP_Size *bpp, uint8_t *flags, FILE *help)
{
if (!strcasecmp(param, "FS")) {
*flags |= GP_SDL_FULLSCREEN;
return 0;
}
+ if (!strcmp(param, "8")) {
+ *bpp = 8;
+ return 0;
+ }
+
+ if (!strcmp(param, "16")) {
+ *bpp = 16;
+ return 0;
+ }
+
+ if (!strcmp(param, "24")) {
+ *bpp = 24;
+ return 0;
+ }
+
+ if (!strcmp(param, "32")) {
+ *bpp = 32;
+ return 0;
+ }
+
/*
* Accepts only string with format "intxint" or "intXint"
*/
@@ -74,7 +98,7 @@ static GP_Backend *backend_sdl_init(char *params, const char *caption,
if (params == NULL)
return GP_BackendSDLInit(0, 0, 0, 0, caption);
- GP_Size w = 0, h = 0;
+ GP_Size w = 0, h = 0, bpp = 0;
uint8_t flags = GP_SDL_RESIZABLE;
char *s = params;
@@ -83,16 +107,16 @@ static GP_Backend *backend_sdl_init(char *params, const char *caption,
switch (*s) {
case ':':
(*s) = '0';
- if (sdl_params_to_flags(params, &w, &h, &flags, help))
+ if (sdl_params_to_flags(params, &w, &h, &bpp, &flags, help))
return NULL;
s++;
params = s;
break;
case '0':
- if (sdl_params_to_flags(params, &w, &h, &flags, help))
+ if (sdl_params_to_flags(params, &w, &h, &bpp, &flags, help))
return NULL;
- return GP_BackendSDLInit(w, h, 0, flags, caption);
+ return GP_BackendSDLInit(w, h, bpp, flags, caption);
break;
}
s++;
http://repo.or.cz/w/gfxprim.git/commit/30f8839e5cb0abf4f3f3ba80a3e4e2f548f4…
commit 30f8839e5cb0abf4f3f3ba80a3e4e2f548f485a5
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Aug 11 19:51:25 2013 +0200
loaders: JPG: Don't convert RGB to BGR by default.
The loader was swapping the RGB and BGR in order
return context in standard format.
Now this is not needed as the library handles both RGB and BGR well.
And it also slows things down when the conversion is unnecessary, i.e.
Load image, Resize, Save.
Or when the conversion could be done on resized image, i.e. Load image,
Resize, Blit on the screen (this was about 15% slower on photos from
digital camera).
In order to get this work loaders must be converted to automatic
conversions between RGB888 and BGR888. I was trying to avoid doing any
conversions in loaders but I'm fine with this particular one.
The JPEG loader is already modified to handle both. More to come.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_JPG.c b/libs/loaders/GP_JPG.c
index d7d3bf7..097308b 100644
--- a/libs/loaders/GP_JPG.c
+++ b/libs/loaders/GP_JPG.c
@@ -106,6 +106,54 @@ static const char *get_colorspace(J_COLOR_SPACE color_space)
};
}
+static int load(struct jpeg_decompress_struct *cinfo, GP_Context *ret,
+ GP_ProgressCallback *callback)
+{
+ while (cinfo->output_scanline < cinfo->output_height) {
+ uint32_t y = cinfo->output_scanline;
+ JSAMPROW addr = (void*)GP_PIXEL_ADDR(ret, 0, y);
+
+ jpeg_read_scanlines(cinfo, &addr, 1);
+
+ if (GP_ProgressCallbackReport(callback, y, ret->h, ret->w)) {
+ GP_DEBUG(1, "Operation aborted");
+ return ECANCELED;
+ }
+ }
+
+ return 0;
+}
+
+static int load_cmyk(struct jpeg_decompress_struct *cinfo, GP_Context *ret,
+ GP_ProgressCallback *callback)
+{
+ while (cinfo->output_scanline < cinfo->output_height) {
+ uint32_t y = cinfo->output_scanline;
+
+ JSAMPROW addr = (void*)GP_PIXEL_ADDR(ret, 0, y);
+ jpeg_read_scanlines(cinfo, &addr, 4);
+
+ unsigned int i;
+ uint8_t *buf = GP_PIXEL_ADDR(ret, 0, y);
+
+ for (i = 0; i < ret->w; i++) {
+ unsigned int j = 4 * i;
+
+ buf[j] = 0xff - buf[j];
+ buf[j+1] = 0xff - buf[j+1];
+ buf[j+2] = 0xff - buf[j+2];
+ buf[j+3] = 0xff - buf[j+3];
+ }
+
+ if (GP_ProgressCallbackReport(callback, y, ret->h, ret->w)) {
+ GP_DEBUG(1, "Operation aborted");
+ return ECANCELED;
+ }
+ }
+
+ return 0;
+}
+
GP_Context *GP_ReadJPG(FILE *f, GP_ProgressCallback *callback)
{
struct jpeg_decompress_struct cinfo;
@@ -138,7 +186,7 @@ GP_Context *GP_ReadJPG(FILE *f, GP_ProgressCallback *callback)
pixel_type = GP_PIXEL_G8;
break;
case JCS_RGB:
- pixel_type = GP_PIXEL_RGB888;
+ pixel_type = GP_PIXEL_BGR888;
break;
case JCS_CMYK:
pixel_type = GP_PIXEL_CMYK8888;
@@ -165,44 +213,21 @@ GP_Context *GP_ReadJPG(FILE *f, GP_ProgressCallback *callback)
jpeg_start_decompress(&cinfo);
- while (cinfo.output_scanline < cinfo.output_height) {
- uint32_t y = cinfo.output_scanline;
-
- JSAMPROW addr = (void*)GP_PIXEL_ADDR(ret, 0, y);
- jpeg_read_scanlines(&cinfo, &addr, 1);
-
- if (pixel_type == GP_PIXEL_RGB888) {
- //TODO: fixme bigendian?
- /* fix the pixel, as we want in fact BGR */
- unsigned int i;
-
- for (i = 0; i < ret->w; i++) {
- uint8_t *pix = GP_PIXEL_ADDR(ret, i, y);
- GP_SWAP(pix[0], pix[2]);
- }
-
- if (GP_ProgressCallbackReport(callback, y, ret->h, ret->w)) {
- GP_DEBUG(1, "Operation aborted");
- err = ECANCELED;
- goto err2;
- }
- }
-
- if (pixel_type == GP_PIXEL_CMYK8888) {
- unsigned int i;
- uint8_t *buf = GP_PIXEL_ADDR(ret, 0, y);
-
- for (i = 0; i < ret->w; i++) {
- unsigned int j = 4 * i;
-
- buf[j] = 0xff - buf[j];
- buf[j+1] = 0xff - buf[j+1];
- buf[j+2] = 0xff - buf[j+2];
- buf[j+3] = 0xff - buf[j+3];
- }
- }
+ switch (pixel_type) {
+ case GP_PIXEL_BGR888:
+ case GP_PIXEL_G8:
+ err = load(&cinfo, ret, callback);
+ break;
+ case GP_PIXEL_CMYK8888:
+ err = load_cmyk(&cinfo, ret, callback);
+ break;
+ default:
+ err = EINVAL;
}
+ if (err)
+ goto err2;
+
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
@@ -320,6 +345,54 @@ int GP_LoadJPGMetaData(const char *src_path, GP_MetaData *data)
return ret;
}
+static int save_rgb888(struct jpeg_compress_struct *cinfo,
+ const GP_Context *src,
+ GP_ProgressCallback *callback)
+{
+ unsigned int x;
+ uint8_t tmp[3 * src->w];
+
+ while (cinfo->next_scanline < cinfo->image_height) {
+ uint32_t y = cinfo->next_scanline;
+
+ memcpy(tmp, GP_PIXEL_ADDR(src, 0, y), 3 * src->w);
+
+ for (x = 0; x < src->w; x++) {
+ uint8_t *pix = tmp + 3 * x;
+ GP_SWAP(pix[0], pix[2]);
+ }
+
+ JSAMPROW row = (void*)tmp;
+ jpeg_write_scanlines(cinfo, &row, 1);
+
+ if (GP_ProgressCallbackReport(callback, y, src->h, src->w)) {
+ GP_DEBUG(1, "Operation aborted");
+ return ECANCELED;
+ }
+ }
+
+ return 0;
+}
+
+static int save(struct jpeg_compress_struct *cinfo,
+ const GP_Context *src,
+ GP_ProgressCallback *callback)
+{
+ while (cinfo->next_scanline < cinfo->image_height) {
+ uint32_t y = cinfo->next_scanline;
+
+ JSAMPROW row = (void*)GP_PIXEL_ADDR(src, 0, y);
+ jpeg_write_scanlines(cinfo, &row, 1);
+
+ if (GP_ProgressCallbackReport(callback, y, src->h, src->w)) {
+ GP_DEBUG(1, "Operation aborted");
+ return ECANCELED;
+ }
+ }
+
+ return 0;
+}
+
int GP_SaveJPG(const GP_Context *src, const char *dst_path,
GP_ProgressCallback *callback)
{
@@ -330,9 +403,13 @@ int GP_SaveJPG(const GP_Context *src, const char *dst_path,
GP_DEBUG(1, "Saving JPG Image '%s'", dst_path);
- if (src->pixel_type != GP_PIXEL_RGB888 &&
- src->pixel_type != GP_PIXEL_G8) {
- GP_DEBUG(1, "Can't save png with pixel type %s",
+ switch (src->pixel_type) {
+ case GP_PIXEL_RGB888:
+ case GP_PIXEL_BGR888:
+ case GP_PIXEL_G8:
+ break;
+ default:
+ GP_DEBUG(1, "Unsupported pixel type %s",
GP_PixelTypeName(src->pixel_type));
errno = ENOSYS;
return 1;
@@ -369,35 +446,17 @@ int GP_SaveJPG(const GP_Context *src, const char *dst_path,
jpeg_start_compress(&cinfo, TRUE);
- while (cinfo.next_scanline < cinfo.image_height) {
- uint32_t y = cinfo.next_scanline;
-
- if (src->pixel_type == GP_PIXEL_RGB888) {
- uint32_t i;
- uint8_t tmp[3 * src->w];
-
- memcpy(tmp, GP_PIXEL_ADDR(src, 0, y), 3 * src->w);
-
- /* fix the pixels as we want in fact BGR */
- for (i = 0; i < src->w; i++) {
- uint8_t *pix = tmp + 3 * i;
- GP_SWAP(pix[0], pix[2]);
- }
-
- JSAMPROW row = (void*)tmp;
- jpeg_write_scanlines(&cinfo, &row, 1);
- } else {
- JSAMPROW row = (void*)GP_PIXEL_ADDR(src, 0, y);
- jpeg_write_scanlines(&cinfo, &row, 1);
- }
-
- if (GP_ProgressCallbackReport(callback, y, src->h, src->w)) {
- GP_DEBUG(1, "Operation aborted");
- err = ECANCELED;
- goto err3;
- }
+ switch (src->pixel_type) {
+ case GP_PIXEL_RGB888:
+ err = save_rgb888(&cinfo, src, callback);
+ break;
+ default:
+ err = save(&cinfo, src, callback);
}
+ if (err)
+ goto err3;
+
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
http://repo.or.cz/w/gfxprim.git/commit/cec1288490c39f429c72a4ccd82b261434a5…
commit cec1288490c39f429c72a4ccd82b261434a5c18f
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Aug 11 19:31:22 2013 +0200
Blit: Debug print now logs src and dst pixel type.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/core/GP_Blit.gen.c.t b/libs/core/GP_Blit.gen.c.t
index 2046350..b702e88 100644
--- a/libs/core/GP_Blit.gen.c.t
+++ b/libs/core/GP_Blit.gen.c.t
@@ -268,6 +268,10 @@ void GP_BlitXYXY_Fast(const GP_Context *src,
GP_Coord x0, GP_Coord y0, GP_Coord x1, GP_Coord y1,
GP_Context *dst, GP_Coord x2, GP_Coord y2)
{
+ GP_DEBUG(2, "Blitting %s -> %s",
+ GP_PixelTypeName(src->pixel_type),
+ GP_PixelTypeName(dst->pixel_type));
+
/* Same pixel type */
if (src->pixel_type == dst->pixel_type) {
GP_FN_PER_BPP(blitXYXY, src->bpp, src->bit_endian,
http://repo.or.cz/w/gfxprim.git/commit/7eb65dcf3a902658aab5ca04bbf801bd77ff…
commit 7eb65dcf3a902658aab5ca04bbf801bd77ff9379
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Aug 11 12:44:44 2013 +0200
doc: Update backends docs.
Add Linux frame-buffer parameters.
Add AA-lib backend docs.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/doc/backends.txt b/doc/backends.txt
index 6cbbf09..7509d56 100644
--- a/doc/backends.txt
+++ b/doc/backends.txt
@@ -1,17 +1,22 @@
Drawing Backends
================
-Drawing backends provide means to draw into computer screen or into a window
-inside of running operating system. Instead of having one unified
-initialization interface each backend has it's specific function and semantics
-but once backend is initialized the backend structure provides unified API for
-controlling the drawing.
-
-So far there are backends for Linux mmaped 'frame-buffer', 'libSDL' and
-'X Window System'.
+Drawing backends provide means to draw on computer screen or into a window.
+Instead of having one unified initialization interface each backend has it's
+specific function and semantics but once backend is initialized the backend
+structure provides unified API for controlling the drawing.
TIP: For example usage see backend link:example_backend.html[example].
+Supported backends
+------------------
+
+* Linux mmaped 'frame-buffer'
+* link:http://www.libsdl.org/[SDL]
+* 'X Window System'
+* link:http://aa-project.sourceforge.net/aalib/[AA-lib]
+
+
Initialization functions
------------------------
@@ -20,17 +25,28 @@ Linux Framebuffer
[source,c]
-------------------------------------------------------------------------------
-GP_Backend *GP_BackendLinuxFBInit(const char *path, int flag);
+enum GP_LinuxFBFlags {
+ GP_FB_INPUT_KBD = 0x01,
+ GP_FB_SHADOW = 0x02,
+ GP_FB_ALLOC_CON = 0x04,
+};
+
+GP_Backend *GP_BackendLinuxFBInit(const char *path, int flags);
-------------------------------------------------------------------------------
Initializes mmaped frame-buffer backend. The path is path to the frame-buffer
-device i.e. '/dev/fbX'. This backend is not buffered, everything you draw
-appears on the screen right away (an switch may be added for that purpose).
+device i.e. '/dev/fbX'.
+
+If 'GP_FB_INPUT_KBD' flag is set console KBD driver is used to feed keystrokes
+into the event queue, otherwise no events are generated and you are expected to
+initialize input event driver yourself.
-If flag is set console KBD driver is used to feed keystrokes into the event
-queue, otherwise no events are generated and you are expected to initialize
-input event driver in order to get keystrokes and/or pointer events.
+If 'GP_FB_SHADOW' flag is set shadow frame-buffer is allocated and used for
+drawing, the memory is blitted to mmaped frame-buffer on Blit() or UpdateRect()
+operation. Otherwise the frame-buffer mapped memory is used directly.
+If 'GP_FB_ALLOC_CON' flag is set new console is allocated, otherwise current
+console is used.
SDL
~~~
@@ -59,10 +75,9 @@ for w and h though.
The caption is window caption.
-And finally flags may change the SDL to go to full-screen mode or make the
+And finally flags may change the 'SDL' to go to full-screen mode or make the
window resizable.
-
[source,c]
-------------------------------------------------------------------------------
#include <backends/GP_SDL_Context.h>
@@ -163,6 +178,22 @@ The 'GP_BackendX11RequestFullscreen' can toggle fullscreen mode at runtime.
It will most likely generate resize event. See the 'GP_BackendResizeAck()' bellow.
+AA-lib
+~~~~~~
+
+[source,c]
+-------------------------------------------------------------------------------
+#include <GP.h>
+/* or */
+#include <backends/AALib.h>
+
+GP_Backend *GP_BackendAALibInit(void);
+-------------------------------------------------------------------------------
+
+Currently the 'AA-lib' backend uses default initialization parameters.
+
+Way how to pass 'AA-lib' specific parameters will be added. This interface
+will likely change.
Overall init function
~~~~~~~~~~~~~~~~~~~~~
@@ -180,7 +211,7 @@ GP_Backend *GP_BackendInit(const char *params, const char *caption, FILE *help);
This function takes a params string as an parameter which is used for
determining backend-dependent parameters. The format is
'backend_name:backend_parameters' where backend parameters may be window size
-(either 'WxH' or 'FS' in case of SDL backend). The caption is window caption
+(either 'WxH' or 'FS' in case of 'SDL' backend). The caption is window caption
(which is ignored in some of the cases) and the 'FILE' is file, where an error
is printed in case of failure, you should mostly use 'stderr' for that
purpose. If params is set to 'NULL' the the call only prints help into the
@@ -195,8 +226,9 @@ General Backend API
The backend API consist of a structure with callbacks. Every backend
initialization yields this structure. Although is possible to call these
pointers directly it's not recommended and everybody should rather use backend
-inline functions instead as they provide more convenient API and do additional
-sanity checks on parameters.
+(inline) functions instead as they provide more convenient API and do
+additional sanity checks on parameters. Also functionality such as timers
+will not work if you decide to call raw callbacks.
[source,c]
-------------------------------------------------------------------------------
@@ -220,9 +252,9 @@ typdef struct GP_Backend {
};
-------------------------------------------------------------------------------
-The file descriptor 'fd' is either set to -1 (in case of SDL that does not
-export it) or to a backend connection file descriptor usable for 'select()' or
-'poll()'.
+The file descriptor 'fd' is either set to -1 (in case of 'SDL' or 'AA-lib' as
+they does not export it) or to a backend connection file descriptor usable for
+'select()' or 'poll()'.
GP_BackendExit
^^^^^^^^^^^^^^
diff --git a/doc/loaders_python.txt b/doc/loaders_python.txt
index de37a29..42dff04 100644
--- a/doc/loaders_python.txt
+++ b/doc/loaders_python.txt
@@ -26,11 +26,9 @@ import gfxprim.loaders as loaders
Loads an image from a file.
-This is a general purpose loader function that automatically detects the file
-format.
-
-The format is detected from file extension first and if this fails signature
-base method is used.
+First one is general purpose loader function that automatically detects the
+file format. The format is detected from file extension first and if this
+fails files signature is used.
May raise 'OSError' with errno set to 'EPERM', 'EISDIR', 'ENOENT' or any other
'errno' set by 'open(2)', 'read(2)', 'seek(2)'.
http://repo.or.cz/w/gfxprim.git/commit/94f18b7b1f75a971cea5cdf9ea57f8c23d4f…
commit 94f18b7b1f75a971cea5cdf9ea57f8c23d4f1522
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Aug 9 14:17:01 2013 +0200
backends: Rename GP_ContextFromSurface()
Rename GP_ContextFromSurface() to GP_ContextFromSDLSurface()
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/build/syms/Backend_symbols.txt b/build/syms/Backend_symbols.txt
index de8f248..1824e2d 100644
--- a/build/syms/Backend_symbols.txt
+++ b/build/syms/Backend_symbols.txt
@@ -9,7 +9,7 @@ GP_BackendIsX11
GP_BackendX11RequestFullscreen
GP_BackendSDLInit
-GP_ContextFromSurface
+GP_ContextFromSDLSurface
GP_BackendAALibInit
diff --git a/demos/c_simple/SDL_glue.c b/demos/c_simple/SDL_glue.c
index d5b5cb7..2260c22 100644
--- a/demos/c_simple/SDL_glue.c
+++ b/demos/c_simple/SDL_glue.c
@@ -96,7 +96,7 @@ int main(void)
goto fail;
}
- GP_ContextFromSurface(&context, display);
+ GP_ContextFromSDLSurface(&context, display);
black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, &context);
darkgray_pixel = GP_ColorToContextPixel(GP_COL_GRAY_DARK, &context);
diff --git a/doc/backends.txt b/doc/backends.txt
index a57a7ad..6cbbf09 100644
--- a/doc/backends.txt
+++ b/doc/backends.txt
@@ -67,7 +67,7 @@ window resizable.
-------------------------------------------------------------------------------
#include <backends/GP_SDL_Context.h>
-int GP_ContextFromSurface(GP_Context *c, const SDL_Surface *surf);
+int GP_ContextFromSDLSurface(GP_Context *c, const SDL_Surface *surf);
-------------------------------------------------------------------------------
This function allows you to mix 'SDL' and 'GFXprim' code.
diff --git a/doc/example_SDL_glue.txt b/doc/example_SDL_glue.txt
index 04ca2f9..aab453f 100644
--- a/doc/example_SDL_glue.txt
+++ b/doc/example_SDL_glue.txt
@@ -1,7 +1,7 @@
SDL Glue Example
----------------
-You can easily mix SDL and GFXprim code using 'GP_ContextFromSurface()'
+You can easily mix SDL and GFXprim code using 'GP_ContextFromSDLSurface()'
function.
[source,c]
diff --git a/include/backends/GP_SDL_Context.h b/include/backends/GP_SDL_Context.h
index 4ed5aad..011273f 100644
--- a/include/backends/GP_SDL_Context.h
+++ b/include/backends/GP_SDL_Context.h
@@ -34,7 +34,7 @@
*
* GP_Context c;
*
- * if (GP_ContextFromSurface(&c, surface)) {
+ * if (GP_ContextFromSDLSurface(&c, surface)) {
* error("Failed to match PIXEL_TYPE for given surface");
* exit(1);
* }
@@ -44,6 +44,6 @@
* Now you have initialized context that shares the pixel buffer with
* the SDL surface.
*/
-int GP_ContextFromSurface(GP_Context *c, const SDL_Surface *surf);
+int GP_ContextFromSDLSurface(GP_Context *c, const SDL_Surface *surf);
#endif /* BACKENDS_GP_SDL_CONTEXT_H */
diff --git a/libs/backends/GP_SDL.c b/libs/backends/GP_SDL.c
index 7fde309..47a7f94 100644
--- a/libs/backends/GP_SDL.c
+++ b/libs/backends/GP_SDL.c
@@ -154,7 +154,7 @@ static int context_from_surface(GP_Context *context, const SDL_Surface *surf)
return 0;
}
-int GP_ContextFromSurface(GP_Context *c, const SDL_Surface *surf)
+int GP_ContextFromSDLSurface(GP_Context *c, const SDL_Surface *surf)
{
return context_from_surface(c, surf);
}
http://repo.or.cz/w/gfxprim.git/commit/e1c9bd3da48fa7a992e807c44cb897a3e22f…
commit e1c9bd3da48fa7a992e807c44cb897a3e22f26bd
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Aug 5 23:42:14 2013 +0200
build: Update list of backend symbols.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/build/check_symbols.sh b/build/check_symbols.sh
index a26b92c..7f8ff8d 100755
--- a/build/check_symbols.sh
+++ b/build/check_symbols.sh
@@ -15,7 +15,7 @@ function grep_sym
function find_symbol
{
echo "SYM $1:"
-
+
find ../libs/ -name '*.o' | while read obj; do grep_sym "$obj" "$1"; done
}
diff --git a/build/syms/Backend_symbols.txt b/build/syms/Backend_symbols.txt
index 7d5128e..de8f248 100644
--- a/build/syms/Backend_symbols.txt
+++ b/build/syms/Backend_symbols.txt
@@ -9,9 +9,10 @@ GP_BackendIsX11
GP_BackendX11RequestFullscreen
GP_BackendSDLInit
-
GP_ContextFromSurface
+GP_BackendAALibInit
+
GP_BackendResize
GP_BackendResizeAck
GP_BackendUpdateRectXYXY
-----------------------------------------------------------------------
Summary of changes:
build/check_symbols.sh | 2 +-
build/syms/Backend_symbols.txt | 3 +-
demos/c_simple/SDL_glue.c | 2 +-
doc/backends.txt | 78 +++++++++++-----
doc/example_SDL_glue.txt | 2 +-
doc/loaders_python.txt | 8 +-
include/backends/GP_SDL_Context.h | 4 +-
libs/backends/GP_BackendInit.c | 36 ++++++-
libs/backends/GP_SDL.c | 2 +-
libs/core/GP_Blit.gen.c.t | 4 +
libs/loaders/GP_JPG.c | 193 ++++++++++++++++++++++++-------------
11 files changed, 226 insertions(+), 108 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
04 Aug '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 5d493cb045b66ed27d9136ea524b1e3184732451 (commit)
via b651425751121eeb3e24b2c1feeb9925eae9a5ed (commit)
via 58f4b69f1ea180d0a9bd2d04da82bb7597f6c714 (commit)
via afe51107773719e6f475eaea52670f279af6fa79 (commit)
via 46023cbd49dc926f7aea8db1916870df152e3bcc (commit)
via 3c7c8c724642a31fae16904368b1b3967f92f347 (commit)
via 60b3c510acc143fef8afbc5e9e583ad9bf19d2b2 (commit)
via 4dea5a3fd0bbbeb2f47b1c4d700f11d46c1c2e61 (commit)
via 651d7642bbdfc7ab54084817f133ec07e793e784 (commit)
via 0a1d349310f6980622e3c1e8c2778aba4eb175bf (commit)
from bcd8f5bd8906312aee47f6cbf16eba26f69ea1c3 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/5d493cb045b66ed27d9136ea524b1e318473…
commit 5d493cb045b66ed27d9136ea524b1e3184732451
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Aug 4 17:25:21 2013 +0200
spiv: Disable timers by default.
Timers are disabled by default and can be enabled with -t.
Timers prints cpu and wall time for certain operation into the stdout.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/spiv/cpu_timer.c b/demos/spiv/cpu_timer.c
index 2071ada..e5b2fbc 100644
--- a/demos/spiv/cpu_timer.c
+++ b/demos/spiv/cpu_timer.c
@@ -35,8 +35,18 @@ static void to_time(int *sec, int *nsec, struct timespec *start,
}
}
+static int timers_disabled = 1;
+
+void cpu_timer_switch(int enable)
+{
+ timers_disabled = !enable;
+}
+
void cpu_timer_start(struct cpu_timer *self, const char *name)
{
+ if (timers_disabled)
+ return;
+
self->name = name;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &self->t_cpu_start);
@@ -45,6 +55,9 @@ void cpu_timer_start(struct cpu_timer *self, const char *name)
void cpu_timer_stop(struct cpu_timer *self)
{
+ if (timers_disabled)
+ return;
+
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &self->t_cpu_stop);
clock_gettime(CLOCK_MONOTONIC, &self->t_real_stop);
diff --git a/demos/spiv/cpu_timer.h b/demos/spiv/cpu_timer.h
index 1d8c8e7..733d27c 100644
--- a/demos/spiv/cpu_timer.h
+++ b/demos/spiv/cpu_timer.h
@@ -22,7 +22,7 @@
/*
- Simple timers to count cpu time.
+ Simple timers to count and print cpu time spend in particular codepath.
*/
@@ -40,6 +40,11 @@ struct cpu_timer {
};
/*
+ * Enable/disable all timers.
+ */
+void cpu_timer_switch(int enable);
+
+/*
* Inialize cpu timer.
*/
void cpu_timer_start(struct cpu_timer *self, const char *name);
diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c
index 514b35c..66284ba 100644
--- a/demos/spiv/spiv.c
+++ b/demos/spiv/spiv.c
@@ -677,7 +677,7 @@ int main(int argc, char *argv[])
GP_TIMER_DECLARE(timer, 0, 0, "Slideshow", timer_callback, ¶ms);
- while ((opt = getopt(argc, argv, "b:ce:fhIPs:r:z:0:1:2:3:4:5:6:7:8:9:")) != -1) {
+ while ((opt = getopt(argc, argv, "b:ce:fhIPr:s:tz:0:1:2:3:4:5:6:7:8:9:")) != -1) {
switch (opt) {
case 'I':
params.show_info = 1;
@@ -720,6 +720,9 @@ int main(int argc, char *argv[])
print_help();
exit(0);
break;
+ case 't':
+ cpu_timer_switch(1);
+ break;
case 'z':
switch (optarg[0]) {
case 'f':
diff --git a/demos/spiv/spiv_help.c b/demos/spiv/spiv_help.c
index 9e2d14b..c45de06 100644
--- a/demos/spiv/spiv_help.c
+++ b/demos/spiv/spiv_help.c
@@ -85,6 +85,9 @@ void print_help(void)
printf(" -zw zoom is fixed to window size (currently default)n");
printf(" -b pass backend init string to backend initn");
printf(" pass -b help for more infon");
+ printf(" -t enable timersn");
+ printf(" if set timers that measure cpu and wall timen");
+ printf(" of certain operations are printed into stdoutn");
puts("n");
printf("Actions:nn");
printf(" -1 'cmd' sets first actionn");
http://repo.or.cz/w/gfxprim.git/commit/b651425751121eeb3e24b2c1feeb9925eae9…
commit b651425751121eeb3e24b2c1feeb9925eae9a5ed
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Aug 4 17:21:29 2013 +0200
filters: GP_ResizeLinear.gen.c.t: Remove debug print
Remove forgotten debug printf.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/filters/GP_ResizeLinear.gen.c.t b/libs/filters/GP_ResizeLinear.gen.c.t
index e01b2c2..b2bfc68 100644
--- a/libs/filters/GP_ResizeLinear.gen.c.t
+++ b/libs/filters/GP_ResizeLinear.gen.c.t
@@ -312,8 +312,6 @@ int GP_FilterResizeLinearLFInt_Raw(const GP_Context *src, GP_Context *dst,
float x_rat = 1.00 * dst->w / src->w;
float y_rat = 1.00 * dst->h / src->h;
- printf("%f %fn", x_rat, y_rat);
-
if (x_rat < 1.00 && y_rat < 1.00) {
GP_DEBUG(1, "Downscaling image %ux%u -> %ux%u %2.2f %2.2f",
http://repo.or.cz/w/gfxprim.git/commit/58f4b69f1ea180d0a9bd2d04da82bb7597f6…
commit 58f4b69f1ea180d0a9bd2d04da82bb7597f6c714
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Jul 28 12:12:33 2013 +0200
input: KBD: Remove newline from debug message.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/input/GP_InputDriverKBD.c b/libs/input/GP_InputDriverKBD.c
index d45a869..1c20fd9 100644
--- a/libs/input/GP_InputDriverKBD.c
+++ b/libs/input/GP_InputDriverKBD.c
@@ -69,7 +69,7 @@ void GP_InputDriverKBDEventPut(struct GP_EventQueue *event_queue,
int press = !(ev & 0x80);
int key;
- GP_DEBUG(2, "Press %i keycode %in", press, keycode);
+ GP_DEBUG(2, "Press %i keycode %i", press, keycode);
if (keycode > 0 && keycode <= GP_ARRAY_SIZE(keycode_table)) {
key = keycode_table[keycode - 1];
http://repo.or.cz/w/gfxprim.git/commit/afe51107773719e6f475eaea52670f279af6…
commit afe51107773719e6f475eaea52670f279af6fa79
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Jul 28 12:09:52 2013 +0200
core: GP_Common.h: Add stddef.h due to offsetof().
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/include/core/GP_Common.h b/include/core/GP_Common.h
index 40b3c09..5de8546 100644
--- a/include/core/GP_Common.h
+++ b/include/core/GP_Common.h
@@ -30,6 +30,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
+#include <stddef.h>
#ifndef __cplusplus
http://repo.or.cz/w/gfxprim.git/commit/46023cbd49dc926f7aea8db1916870df152e…
commit 46023cbd49dc926f7aea8db1916870df152e3bcc
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Jul 28 11:47:08 2013 +0200
backends: SDL: Avoid lockup in Wait.
Same story again. We cannot sleep in Wait while holding the mutex and we
do not have a file descriptor to poll on so we need resort to polling.
We will need a better solution here.
One posibility is to add a init flag to all backends and resort to
polling only if application needs thread safe backend.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/backends/GP_SDL.c b/libs/backends/GP_SDL.c
index ab87c82..7fde309 100644
--- a/libs/backends/GP_SDL.c
+++ b/libs/backends/GP_SDL.c
@@ -103,15 +103,22 @@ static void sdl_wait(struct GP_Backend *self __attribute__((unused)))
{
SDL_Event ev;
- SDL_mutexP(mutex);
+ //SDL_WaitEvent(&ev);
+ //sdl_put_event(&ev);
- SDL_WaitEvent(&ev);
- sdl_put_event(&ev);
+ for (;;) {
+ if (GP_EventQueueEventsQueued(&self->event_queue))
+ return;
- while (SDL_PollEvent(&ev))
- sdl_put_event(&ev);
+ SDL_mutexP(mutex);
- SDL_mutexV(mutex);
+ while (SDL_PollEvent(&ev))
+ sdl_put_event(&ev);
+
+ SDL_mutexV(mutex);
+
+ usleep(10000);
+ }
}
static int context_from_surface(GP_Context *context, const SDL_Surface *surf)
http://repo.or.cz/w/gfxprim.git/commit/3c7c8c724642a31fae16904368b1b3967f92…
commit 3c7c8c724642a31fae16904368b1b3967f92f347
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 27 23:46:54 2013 +0200
input: KBD: Add mapping for few keys.
These are arrows, delete, left meta and sysrq.
Now works on your framebuffer too ;).
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/input/GP_InputDriverKBD.c b/libs/input/GP_InputDriverKBD.c
index 020f45c..d45a869 100644
--- a/libs/input/GP_InputDriverKBD.c
+++ b/libs/input/GP_InputDriverKBD.c
@@ -52,10 +52,14 @@ static uint16_t keycode_table[] = {
0, 0, GP_KEY_F11, GP_KEY_F12,
0, 0, 0, 0,
0, 0, 0, GP_KEY_KP_ENTER,
- GP_KEY_RIGHT_CTRL, GP_KEY_KP_ASTERISK, 0/*PRINT_SCREEN*/, GP_KEY_RIGHT_ALT,
- 0, GP_KEY_HOME, 0, GP_KEY_PAGE_UP,
- 0, 0, GP_KEY_END, 0,
- GP_KEY_PAGE_DOWN, GP_KEY_INSERT,
+ GP_KEY_RIGHT_CTRL, GP_KEY_KP_ASTERISK, GP_KEY_SYSRQ, GP_KEY_RIGHT_ALT,
+ 0, GP_KEY_HOME, GP_KEY_UP, GP_KEY_PAGE_UP,
+ GP_KEY_LEFT, GP_KEY_RIGHT, GP_KEY_END, GP_KEY_DOWN,
+ GP_KEY_PAGE_DOWN, GP_KEY_INSERT, GP_KEY_DELETE, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ GP_KEY_LEFT_META,
};
void GP_InputDriverKBDEventPut(struct GP_EventQueue *event_queue,
http://repo.or.cz/w/gfxprim.git/commit/60b3c510acc143fef8afbc5e9e583ad9bf19…
commit 60b3c510acc143fef8afbc5e9e583ad9bf19d2b2
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 27 20:13:08 2013 +0200
demos: Add backend resize ack to few demos
Add backend resize ack and system exit handling to linetest and
shapetest and particle demo.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/c_simple/linetest.c b/demos/c_simple/linetest.c
index 92aa194..1069a7e 100644
--- a/demos/c_simple/linetest.c
+++ b/demos/c_simple/linetest.c
@@ -96,6 +96,18 @@ void event_loop(void)
pause_flag = !pause_flag;
break;
}
+ break;
+ case GP_EV_SYS:
+ switch(ev.code) {
+ case GP_EV_SYS_QUIT:
+ GP_BackendExit(win);
+ exit(0);
+ break;
+ case GP_EV_SYS_RESIZE:
+ GP_BackendResizeAck(win);
+ break;
+ }
+ break;
}
}
}
diff --git a/demos/c_simple/shapetest.c b/demos/c_simple/shapetest.c
index 048496b..314be26 100644
--- a/demos/c_simple/shapetest.c
+++ b/demos/c_simple/shapetest.c
@@ -443,6 +443,11 @@ void event_loop(void)
GP_BackendExit(backend);
exit(0);
break;
+ case GP_EV_SYS_RESIZE:
+ GP_BackendResizeAck(backend);
+ center_x = backend->context->w / 2;
+ center_y = backend->context->h / 2;
+ break;
}
break;
}
diff --git a/demos/particle/particle_demo.c b/demos/particle/particle_demo.c
index 3f3cf5f..cc9a4a2 100644
--- a/demos/particle/particle_demo.c
+++ b/demos/particle/particle_demo.c
@@ -135,6 +135,22 @@ int main(int argc, char *argv[])
break;
}
break;
+ case GP_EV_SYS:
+ switch(ev.code) {
+ case GP_EV_SYS_QUIT:
+ GP_BackendExit(backend);
+ exit(0);
+ break;
+ case GP_EV_SYS_RESIZE:
+ GP_BackendResizeAck(backend);
+ space_destroy(space);
+ space = space_create(particles,
+ 10<<8, 10<<8,
+ (context->w - 10)<<8,
+ (context->h - 10)<<8);
+ break;
+ }
+ break;
}
}
http://repo.or.cz/w/gfxprim.git/commit/4dea5a3fd0bbbeb2f47b1c4d700f11d46c1c…
commit 4dea5a3fd0bbbeb2f47b1c4d700f11d46c1c2e61
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 27 14:05:01 2013 +0200
backends: Add basic AALib backend.
Unfortunately aalib is not thread safe nor it exposes file descriptor so
we have to stick to polling as we need to be thread safe.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/configure b/configure
index 7a3b93d..2d41ff4 100755
--- a/configure
+++ b/configure
@@ -39,7 +39,7 @@ def c_compiler_exists(cfg):
cfg["CC"][0])
def python_version(cfg):
- sys.stderr.write("Cddhecking for python-config Python version ... ")
+ sys.stderr.write("Checking for python-config Python version ... ")
if (cfg['PYTHON_CONFIG'][0] is ''):
sys.stderr.write('NAn')
@@ -330,6 +330,9 @@ if __name__ == '__main__':
["X_SHM",
"MIT-SHM X Extension",
[header_exists, "X11/extensions/XShm.h"], "", "-lXext", ["backends"]],
+ ["aalib",
+ "Portable ascii art GFX library",
+ [header_exists, "aalib.h"], "", "-laa", ["backends"]],
["freetype",
"A high-quality and portable font engine",
[header_exists, "ft2build.h"], "", "`freetype-config --libs`", ["core"]],
diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c
index 936cb14..514b35c 100644
--- a/demos/spiv/spiv.c
+++ b/demos/spiv/spiv.c
@@ -531,7 +531,7 @@ static void *image_loader(void *ptr)
if (img == NULL)
return NULL;
- image_cache_print(params->img_resized_cache);
+ //image_cache_print(params->img_resized_cache);
update:
update_display(params, img, orig_img);
cpu_timer_stop(&sum_timer);
diff --git a/include/backends/GP_Backends.h b/include/backends/GP_AALib.h
similarity index 76%
copy from include/backends/GP_Backends.h
copy to include/backends/GP_AALib.h
index 9d72fc7..f2849e4 100644
--- a/include/backends/GP_Backends.h
+++ b/include/backends/GP_AALib.h
@@ -16,35 +16,20 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
-/*
-
- Catch all header for backends.
-
- */
-
-#ifndef BACKENDS_GP_BACKENDS_H
-#define BACKENDS_GP_BACKENDS_H
+#ifndef BACKENDS_GP_AALIB_H
+#define BACKENDS_GP_AALIB_H
-/*
- * Base backend definitions.
- */
-#include "backends/GP_Backend.h"
-
-/*
- * Backends.
- */
-#include "backends/GP_LinuxFB.h"
-#include "backends/GP_SDL.h"
-#include "backends/GP_X11.h"
-#include "backends/GP_BackendVirtual.h"
+#include "GP_Backend.h"
/*
- * Simplified backend initalization.
+ * Initalize AALib.
+ *
+ * TODO: add a way to pass aalib params
*/
-#include "backends/GP_BackendInit.h"
+GP_Backend *GP_BackendAALibInit(void);
-#endif /* BACKENDS_GP_BACKENDS_H */
+#endif /* BACKENDS_GP_AALIB_H */
diff --git a/include/backends/GP_Backends.h b/include/backends/GP_Backends.h
index 9d72fc7..db569a1 100644
--- a/include/backends/GP_Backends.h
+++ b/include/backends/GP_Backends.h
@@ -40,6 +40,7 @@
#include "backends/GP_LinuxFB.h"
#include "backends/GP_SDL.h"
#include "backends/GP_X11.h"
+#include "backends/GP_AALib.h"
#include "backends/GP_BackendVirtual.h"
/*
diff --git a/libs/backends/GP_AALib.c b/libs/backends/GP_AALib.c
new file mode 100644
index 0000000..bfcd946
--- /dev/null
+++ b/libs/backends/GP_AALib.c
@@ -0,0 +1,280 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#include <errno.h>
+
+#include "core/GP_Debug.h"
+#include "core/GP_Context.h"
+#include "backends/GP_AALib.h"
+#include "input/GP_Input.h"
+
+#include "../config.h"
+
+#ifdef HAVE_AALIB
+
+#include <aalib.h>
+#include <pthread.h>
+
+/*
+ * Guards AALib library calls.
+ *
+ * In case we run under X the underlying xcb connection is not initialized with
+ * XInitThreads() and thus not multithread safe.
+ */
+static pthread_mutex_t aalib_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+struct aalib_priv {
+ aa_context *c;
+ GP_Context ctx;
+};
+
+/* ascii mapped keys */
+static const uint16_t keymap[] = {
+ 0, 0, 0, 0,
+ 0, 0, 0, GP_KEY_BACKSPACE,
+ GP_KEY_TAB, 0, 0, 0,
+ GP_KEY_ENTER, 0, 0, 0,
+ 0, 0, GP_KEY_PAUSE, 0,
+ 0, 0, 0, 0,
+ 0, 0, GP_KEY_ESC, 0,
+ 0, 0, 0, GP_KEY_SPACE,
+ 0, 0, 0, 0,
+ 0, 0, GP_KEY_APOSTROPHE, 0,
+ 0, 0, 0, GP_KEY_COMMA,
+ GP_KEY_MINUS, GP_KEY_DOT, GP_KEY_SLASH, GP_KEY_0,
+ GP_KEY_1, GP_KEY_2, GP_KEY_3, GP_KEY_4,
+ GP_KEY_5, GP_KEY_6, GP_KEY_7, GP_KEY_8,
+ GP_KEY_9, 0, GP_KEY_SEMICOLON, 0,
+ GP_KEY_EQUAL, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, GP_KEY_LEFT_BRACE, GP_KEY_BACKSLASH,
+ GP_KEY_RIGHT_BRACE, 0, 0, GP_KEY_GRAVE,
+ GP_KEY_A, GP_KEY_B, GP_KEY_C, GP_KEY_D,
+ GP_KEY_E, GP_KEY_F, GP_KEY_G, GP_KEY_H,
+ GP_KEY_I, GP_KEY_J, GP_KEY_K, GP_KEY_L,
+ GP_KEY_M, GP_KEY_N, GP_KEY_O, GP_KEY_P,
+ GP_KEY_Q, GP_KEY_R, GP_KEY_S, GP_KEY_T,
+ GP_KEY_U, GP_KEY_V, GP_KEY_W, GP_KEY_X,
+ GP_KEY_Y, GP_KEY_Z, 0, 0,
+ 0, 0, GP_KEY_DELETE,
+};
+
+/* special keys mapped from 300 to 305 */
+static const uint16_t keymap2[] = {
+ GP_KEY_UP, GP_KEY_DOWN,
+ GP_KEY_LEFT, GP_KEY_RIGHT,
+ GP_KEY_BACKSPACE, GP_KEY_ESC,
+};
+
+static void aalib_exit(GP_Backend *self)
+{
+ struct aalib_priv *aa = GP_BACKEND_PRIV(self);
+
+ GP_DEBUG(1, "Closing AALib");
+ aa_close(aa->c);
+}
+
+static void aalib_flip(GP_Backend *self)
+{
+ struct aalib_priv *aa = GP_BACKEND_PRIV(self);
+
+ GP_DEBUG(4, "Rendering and flipping screen");
+
+ aa_render(aa->c, &aa_defrenderparams,
+ 0, 0, aa_scrwidth(aa->c), aa_scrheight(aa->c));
+
+ pthread_mutex_lock(&aalib_mutex);
+ aa_flush(aa->c);
+ pthread_mutex_unlock(&aalib_mutex);
+}
+
+static void aalib_update_rect(GP_Backend *self, GP_Coord x0, GP_Coord y0,
+ GP_Coord x1, GP_Coord y1)
+{
+ struct aalib_priv *aa = GP_BACKEND_PRIV(self);
+
+ GP_DEBUG(4, "Updating rect %ix%i-%ix%i", x0, y0, x1, y1);
+
+ /*
+ * TODO: Map screen coordinates to bitmap coordinates.
+ */
+ int w = aa_scrwidth(aa->c);
+ int h = aa_scrheight(aa->c);
+
+ aa_render(aa->c, &aa_defrenderparams,
+ 0, 0, w, h);
+
+ pthread_mutex_lock(&aalib_mutex);
+ aa_flush(aa->c);
+ pthread_mutex_unlock(&aalib_mutex);
+}
+
+static int aalib_resize_ack(GP_Backend *self)
+{
+ struct aalib_priv *aa = GP_BACKEND_PRIV(self);
+
+ if (!aa_resize(aa->c)) {
+ GP_WARN("aa_resize() failed");
+ return 1;
+ }
+
+ int w = aa_imgwidth(aa->c);
+ int h = aa_imgheight(aa->c);
+
+ GP_DEBUG(1, "Reinitializing Context %ix%i", w, h);
+
+ GP_ContextInit(&aa->ctx, w, h, GP_PIXEL_G8, aa_image(aa->c));
+
+ return 0;
+}
+
+static void parse_event(GP_Backend *self, int ev)
+{
+ unsigned int key;
+
+ if (ev == 0)
+ return;
+
+ if (ev == AA_RESIZE) {
+ GP_DEBUG(1, "Resize event");
+ //TODO: Can we get the new size somehow?
+ GP_EventQueuePushResize(&self->event_queue, 0, 0, NULL);
+ return;
+ }
+
+ if (ev <= (int)GP_ARRAY_SIZE(keymap)) {
+ key = keymap[ev - 1];
+ } else {
+ if (ev >= 300 && ev <= 305) {
+ key = keymap2[ev - 300];
+ } else {
+ GP_DEBUG(1, "Unhandled event %i", ev);
+ return;
+ }
+ }
+
+ /* emulate keyup events */
+ GP_EventQueuePushKey(&self->event_queue, key, 1, NULL);
+ GP_EventQueuePushKey(&self->event_queue, key, 0, NULL);
+}
+
+static void aalib_poll(GP_Backend *self)
+{
+ struct aalib_priv *aa = GP_BACKEND_PRIV(self);
+ int key;
+
+ pthread_mutex_lock(&aalib_mutex);
+ key = aa_getevent(aa->c, 0);
+ pthread_mutex_unlock(&aalib_mutex);
+
+ parse_event(self, key);
+}
+
+static void aalib_wait(GP_Backend *self)
+{
+ /* We cannot wait due to possible lockup, so we poll */
+ for (;;) {
+ aalib_poll(self);
+
+ if (GP_EventQueueEventsQueued(&self->event_queue))
+ return;
+
+ usleep(10000);
+ }
+}
+
+GP_Backend *GP_BackendAALibInit(void)
+{
+ GP_Backend *backend;
+ struct aalib_priv *aa;
+ int w, h;
+
+ backend = malloc(sizeof(GP_Backend) + sizeof(struct aalib_priv));
+
+ if (backend == NULL)
+ return NULL;
+
+ aa = GP_BACKEND_PRIV(backend);
+
+ GP_DEBUG(1, "Initializing aalib");
+
+ aa->c = aa_autoinit(&aa_defparams);
+
+ if (!aa->c) {
+ GP_DEBUG(1, "Failed to initialize aalib");
+ goto err1;
+ }
+
+ GP_DEBUG(1, "AALib driver %s %s %ix%i", aa->c->driver->name,
+ aa->c->driver->shortname,
+ aa->c->params.width, aa->c->params.height);
+
+ if (!aa_autoinitkbd(aa->c, 0)) {
+ GP_DEBUG(1, "Failed to initialize aalib keyboard");
+ goto err2;
+ }
+
+ w = aa_imgwidth(aa->c);
+ h = aa_imgheight(aa->c);
+
+ GP_DEBUG(1, "Initializing Context %ix%i", w, h);
+
+ GP_ContextInit(&aa->ctx, w, h, GP_PIXEL_G8, aa_image(aa->c));
+
+ /* update API */
+ backend->name = "AALib";
+ backend->context = &aa->ctx;
+ backend->Flip = aalib_flip;
+ backend->UpdateRect = aalib_update_rect;
+ backend->Exit = aalib_exit;
+ backend->SetAttributes = NULL;
+ backend->ResizeAck = aalib_resize_ack;
+ backend->Poll = aalib_poll;
+ backend->Wait = aalib_wait;
+ backend->fd = -1;
+ backend->timers = NULL;
+
+ GP_EventQueueInit(&backend->event_queue, w, h, 0);
+
+ return backend;
+err2:
+ aa_close(aa->c);
+err1:
+ free(backend);
+ return NULL;
+}
+
+#else
+
+GP_Backend *GP_BackendAALibInit(void)
+{
+ GP_FATAL("AALib support not compiled in!");
+ errno = ENOSYS;
+ return NULL;
+}
+
+#endif /* HAVE_AALIB */
diff --git a/libs/backends/GP_BackendInit.c b/libs/backends/GP_BackendInit.c
index 985c528..5a601a0 100644
--- a/libs/backends/GP_BackendInit.c
+++ b/libs/backends/GP_BackendInit.c
@@ -218,10 +218,35 @@ static GP_Backend *backend_x11_init(char *params, const char *caption,
}
}
+static void backend_aa_help(FILE *help, const char *err)
+{
+ if (help == NULL)
+ return;
+
+ if (err != NULL)
+ fprintf(help, "ERROR: %sn", err);
+
+ fprintf(help, "AALib backendn"
+ "--------------n"
+ "AAn");
+}
+
+static GP_Backend *backend_aa_init(char *params, const char *caption,
+ FILE *help)
+{
+ (void) help;
+ (void) caption;
+ (void) params;
+
+ return GP_BackendAALibInit();
+}
+
+
static const char *backend_names[] = {
"SDL", /* libSDL */
"FB", /* Linux Framebuffer */
"X11", /* X11 window system */
+ "AA", /* AALib */
NULL,
};
@@ -229,6 +254,7 @@ static GP_Backend *(*backend_inits[])(char *, const char *, FILE *) = {
backend_sdl_init,
backend_fb_init,
backend_x11_init,
+ backend_aa_init,
NULL,
};
@@ -236,6 +262,7 @@ static void (*backend_helps[])(FILE *help, const char *err) = {
backend_sdl_help,
backend_fb_help,
backend_x11_help,
+ backend_aa_help,
NULL,
};
http://repo.or.cz/w/gfxprim.git/commit/651d7642bbdfc7ab54084817f133ec07e793…
commit 651d7642bbdfc7ab54084817f133ec07e793e784
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 27 13:43:50 2013 +0200
demos: c_simple, particle: Add -b (backend) option
This allows specifying backend init string with -b option.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/c_simple/linetest.c b/demos/c_simple/linetest.c
index 8c91cf5..92aa194 100644
--- a/demos/c_simple/linetest.c
+++ b/demos/c_simple/linetest.c
@@ -100,9 +100,20 @@ void event_loop(void)
}
}
-int main(void)
+int main(int argc, char *argv[])
{
const char *backend_opts = "X11";
+ int opt;
+
+ while ((opt = getopt(argc, argv, "b:")) != -1) {
+ switch (opt) {
+ case 'b':
+ backend_opts = optarg;
+ break;
+ default:
+ fprintf(stderr, "Invalid paramter '%c'n", opt);
+ }
+ }
win = GP_BackendInit(backend_opts, "Line Test", stderr);
diff --git a/demos/c_simple/shapetest.c b/demos/c_simple/shapetest.c
index 6444445..048496b 100644
--- a/demos/c_simple/shapetest.c
+++ b/demos/c_simple/shapetest.c
@@ -340,7 +340,7 @@ void event_loop(void)
for (;;) {
GP_BackendWaitEvent(backend, &ev);
- GP_EventDump(&ev);
+ //GP_EventDump(&ev);
shift_pressed = GP_EventGetKey(&ev, GP_KEY_LEFT_SHIFT) ||
GP_EventGetKey(&ev, GP_KEY_RIGHT_SHIFT);
@@ -471,11 +471,20 @@ void print_instructions(void)
printf(" 1/2/3 ............... choose shape variant (if applicable)n");
}
-int main(void)
+int main(int argc, char *argv[])
{
const char *backend_opts = "X11";
+ int opt;
-// GP_SetDebugLevel(10);
+ while ((opt = getopt(argc, argv, "b:")) != -1) {
+ switch (opt) {
+ case 'b':
+ backend_opts = optarg;
+ break;
+ default:
+ fprintf(stderr, "Invalid paramter '%c'n", opt);
+ }
+ }
backend = GP_BackendInit(backend_opts, "Shapetest", stderr);
diff --git a/demos/c_simple/v4l2_show.c b/demos/c_simple/v4l2_show.c
index a88a891..50ea514 100644
--- a/demos/c_simple/v4l2_show.c
+++ b/demos/c_simple/v4l2_show.c
@@ -40,9 +40,6 @@ int main(int argc, char *argv[])
int mode = 0;
int opt;
- /* Turn on debug messages */
- //GP_SetDebugLevel(10);
-
while ((opt = getopt(argc, argv, "d:hH:W:l:")) != -1) {
switch (opt) {
case 'd':
diff --git a/demos/particle/particle_demo.c b/demos/particle/particle_demo.c
index 6fcc11d..3f3cf5f 100644
--- a/demos/particle/particle_demo.c
+++ b/demos/particle/particle_demo.c
@@ -64,12 +64,16 @@ int main(int argc, char *argv[])
const char *backend_opts = "X11";
int opt;
int pause_flag = 0;
+ int particles = 160;
- while ((opt = getopt(argc, argv, "b:Ii:Ps:r:")) != -1) {
+ while ((opt = getopt(argc, argv, "b:n:")) != -1) {
switch (opt) {
case 'b':
backend_opts = optarg;
break;
+ case 'n':
+ particles = atoi(optarg);
+ break;
default:
fprintf(stderr, "Invalid paramter '%c'n", opt);
}
@@ -93,7 +97,7 @@ int main(int argc, char *argv[])
GP_BackendFlip(backend);
struct space *space;
- space = space_create(160, 10<<8, 10<<8, (context->w - 10)<<8, (context->h - 10)<<8);
+ space = space_create(particles, 10<<8, 10<<8, (context->w - 10)<<8, (context->h - 10)<<8);
for (;;) {
if (backend->Poll)
http://repo.or.cz/w/gfxprim.git/commit/0a1d349310f6980622e3c1e8c2778aba4eb1…
commit 0a1d349310f6980622e3c1e8c2778aba4eb175bf
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 20 19:44:45 2013 +0200
backends: Improve Linux FB backend.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/include/backends/GP_LinuxFB.h b/include/backends/GP_LinuxFB.h
index 2dcc1c9..ee9498c 100644
--- a/include/backends/GP_LinuxFB.h
+++ b/include/backends/GP_LinuxFB.h
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -25,6 +25,21 @@
#include "GP_Backend.h"
+enum GP_LinuxFBFlags {
+ /*
+ * Use KBD to get input events
+ */
+ GP_FB_INPUT_KBD = 0x01,
+ /*
+ * Use shadow framebuffer for drawing.
+ */
+ GP_FB_SHADOW = 0x02,
+ /*
+ * Allocate new console, if not set current is used.
+ */
+ GP_FB_ALLOC_CON = 0x04,
+};
+
/*
* Initalize framebuffer.
*
@@ -38,6 +53,6 @@
*
* If flag is set, the konsole kbd is used to push events into event queue.
*/
-GP_Backend *GP_BackendLinuxFBInit(const char *path, int flag);
+GP_Backend *GP_BackendLinuxFBInit(const char *path, int flags);
#endif /* BACKENDS_GP_FRAMEBUFFER_H */
diff --git a/libs/backends/GP_BackendInit.c b/libs/backends/GP_BackendInit.c
index f0a20f1..985c528 100644
--- a/libs/backends/GP_BackendInit.c
+++ b/libs/backends/GP_BackendInit.c
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -109,7 +109,7 @@ static void backend_fb_help(FILE *help, const char *err)
fprintf(help, "LinuxFB backendn"
"--------------n"
- "FB:[/dev/fbX]n");
+ "FB:NO_SHADOW:USE_CON:[/dev/fbX]n");
}
static GP_Backend *backend_fb_init(char *params, const char *caption,
@@ -123,7 +123,7 @@ static GP_Backend *backend_fb_init(char *params, const char *caption,
if (params != NULL)
fb = params;
- return GP_BackendLinuxFBInit(fb, 1);
+ return GP_BackendLinuxFBInit(fb, 3);
}
static void backend_x11_help(FILE *help, const char *err)
diff --git a/libs/backends/GP_LinuxFB.c b/libs/backends/GP_LinuxFB.c
index 9f5c83c..8e96684 100644
--- a/libs/backends/GP_LinuxFB.c
+++ b/libs/backends/GP_LinuxFB.c
@@ -42,113 +42,147 @@
struct fb_priv {
GP_Context context;
uint32_t bsize;
+ void *fb_mem;
- int flag;
+ int flags;
/* console fd, nr and saved data */
int con_fd;
int con_nr;
int last_con_nr;
int saved_kb_mode;
+ struct termios ts;
+ int restore_termios;
int fb_fd;
char path[];
};
/*
- * Allocates and switches to newly allocated console.
+ * Restore console and keyboard mode to whatever was there before.
*/
-static int allocate_console(struct fb_priv *fb, int flag)
+static void exit_kbd(struct fb_priv *fb)
{
- struct vt_stat vts;
- int fd, nr;
- char buf[255];
-
- /* allocate and switch to new console */
- GP_DEBUG(1, "Allocating new console");
-
- fd = open("/dev/tty1", O_WRONLY);
-
- if (fd < 0) {
- GP_DEBUG(1, "Opening console /dev/tty1 failed: %s",
- strerror(errno));
- return -1;
+ if (ioctl(fb->con_fd, KDSKBMODE, fb->saved_kb_mode) < 0) {
+ GP_DEBUG(1, "Failed to ioctl KDSKBMODE (restore KBMODE)"
+ " /dev/tty%i: %s", fb->con_nr,
+ strerror(errno));
}
- if (ioctl(fd, VT_OPENQRY, &nr) < 0) {
- GP_DEBUG(1, "Failed to ioctl VT_OPENQRY /dev/tty1: %s",
- strerror(errno));
- close(fd);
- return -1;
+ if (fb->restore_termios) {
+ if (tcsetattr(fb->con_fd, TCSANOW, &fb->ts) < 0) {
+ GP_WARN("Failed to tcsetattr() (restore termios): %s",
+ strerror(errno));
+ }
}
+}
- GP_DEBUG(1, "Has been granted tty%i", nr);
-
- close(fd);
-
- snprintf(buf, sizeof(buf), "/dev/tty%i", nr);
- fd = open(buf, O_RDWR | O_NONBLOCK);
-
- if (fd < 0) {
- GP_DEBUG(1, "Opening console %s failed: %s",
- buf, strerror(errno));
- return -1;
+/*
+ * Save console mode and set the mode to raw.
+ */
+static int init_kbd(struct fb_priv *fb)
+{
+ struct termios t;
+ int fd = fb->con_fd;
+
+ if (tcgetattr(fd, &fb->ts)) {
+ GP_WARN("Failed to tcgetattr(): %s", strerror(errno));
+ fb->restore_termios = 0;
+ } else {
+ fb->restore_termios = 1;
}
- if (ioctl(fd, VT_GETSTATE, &vts) == 0)
- fb->last_con_nr = vts.v_active;
- else
- fb->last_con_nr = -1;
+ cfmakeraw(&t);
- if (ioctl(fd, VT_ACTIVATE, nr) < 0) {
- GP_DEBUG(1, "Failed to ioctl VT_ACTIVATE %s: %s",
- buf, strerror(errno));
+ if (tcsetattr(fd, TCSANOW, &t) < 0) {
+ GP_DEBUG(1, "Failed to tcsetattr(): %s",
+ strerror(errno));
close(fd);
return -1;
}
- GP_DEBUG(1, "Waiting for tty%i to activate", nr);
-
- if (ioctl(fd, VT_WAITACTIVE, nr) < 0) {
- GP_DEBUG(1, "Failed to ioctl VT_WAITACTIVE %s: %s",
- buf, strerror(errno));
+ if (ioctl(fd, KDGKBMODE, &fb->saved_kb_mode)) {
+ GP_DEBUG(1, "Failed to ioctl KDGKBMODE tty%i: %s",
+ fb->con_nr, strerror(errno));
close(fd);
return -1;
}
- /* turn off blinking cursor */
- if (ioctl(fd, KDSETMODE, KD_GRAPHICS) < 0) {
- GP_DEBUG(1, "Failed to ioctl KDSETMODE %s: %s",
- buf, strerror(errno));
+ GP_DEBUG(2, "Previous keyboard mode was '%i'",
+ fb->saved_kb_mode);
+
+ if (ioctl(fd, KDSKBMODE, K_MEDIUMRAW) < 0) {
+ GP_DEBUG(1, "Failed to ioctl KDSKBMODE tty%i: %s",
+ fb->con_nr, strerror(errno));
close(fd);
return -1;
}
- /* set keyboard to raw mode */
- if (flag) {
- struct termios t;
- cfmakeraw(&t);
+ return 0;
+}
+
+/*
+ * Allocates and switches to newly allocated console.
+ */
+static int allocate_console(struct fb_priv *fb, int flags)
+{
+ struct vt_stat vts;
+ int fd, nr = -1;
+ char buf[255];
+ const char *tty = "/dev/tty";
+
+ if (flags & GP_FB_ALLOC_CON) {
+ GP_DEBUG(1, "Allocating new console");
- if (tcsetattr(fd, TCSANOW, &t) < 0) {
- GP_DEBUG(1, "Failed to tcsetattr(): %s",
+ fd = open("/dev/tty1", O_WRONLY);
+
+ if (fd < 0) {
+ GP_DEBUG(1, "Opening console /dev/tty1 failed: %s",
strerror(errno));
+ return -1;
+ }
+
+ if (ioctl(fd, VT_OPENQRY, &nr) < 0) {
+ GP_DEBUG(1, "Failed to ioctl VT_OPENQRY /dev/tty1: %s",
+ strerror(errno));
close(fd);
return -1;
}
- if (ioctl(fd, KDGKBMODE, &fb->saved_kb_mode)) {
- GP_DEBUG(1, "Failed to ioctl KDGKBMODE %s: %s",
- buf, strerror(errno));
+ GP_DEBUG(1, "Has been granted tty%i", nr);
+
+ close(fd);
+
+ snprintf(buf, sizeof(buf), "/dev/tty%i", nr);
+ tty = buf;
+ }
+
+ fd = open(tty, O_RDWR | O_NONBLOCK);
+
+ if (fd < 0) {
+ GP_DEBUG(1, "Opening console %s failed: %s",
+ tty, strerror(errno));
+ return -1;
+ }
+
+ if (ioctl(fd, VT_GETSTATE, &vts) == 0)
+ fb->last_con_nr = vts.v_active;
+ else
+ fb->last_con_nr = -1;
+
+ if (flags & GP_FB_ALLOC_CON) {
+ if (ioctl(fd, VT_ACTIVATE, nr) < 0) {
+ GP_DEBUG(1, "Failed to ioctl VT_ACTIVATE %s: %s",
+ tty, strerror(errno));
close(fd);
return -1;
}
- GP_DEBUG(2, "Previous keyboard mode was '%i'",
- fb->saved_kb_mode);
+ GP_DEBUG(1, "Waiting for %s to activate", tty);
- if (ioctl(fd, KDSKBMODE, K_MEDIUMRAW) < 0) {
- GP_DEBUG(1, "Failed to ioctl KDSKBMODE %s: %s",
- buf, strerror(errno));
+ if (ioctl(fd, VT_WAITACTIVE, nr) < 0) {
+ GP_DEBUG(1, "Failed to ioctl VT_WAITACTIVE %s: %s",
+ tty, strerror(errno));
close(fd);
return -1;
}
@@ -157,6 +191,14 @@ static int allocate_console(struct fb_priv *fb, int flag)
fb->con_nr = nr;
fb->con_fd = fd;
+ /* turn off blinking cursor */
+ if (ioctl(fd, KDSETMODE, KD_GRAPHICS) < 0) {
+ GP_DEBUG(1, "Failed to ioctl KDSETMODE %s: %s",
+ tty, strerror(errno));
+ close(fd);
+ return -1;
+ }
+
return 0;
}
@@ -190,20 +232,20 @@ static void fb_exit(GP_Backend *self)
{
struct fb_priv *fb = GP_BACKEND_PRIV(self);
+ if (fb->flags & GP_FB_SHADOW)
+ free(fb->context.pixels);
+
/* unmap framebuffer */
- munmap(fb->context.pixels, fb->bsize);
+ munmap(fb->fb_mem, fb->bsize);
close(fb->fb_fd);
- /* reset keyboard */
- ioctl(fb->con_fd, KDSETMODE, KD_TEXT);
+ /* restore blinking cursor */
+ if (ioctl(fb->con_fd, KDSETMODE, KD_TEXT))
+ GP_WARN("Failed to ioctl KDSETMODE (restore KDMODE)");
/* restore keyboard mode */
- if (fb->flag) {
- if (ioctl(fb->con_fd, KDSKBMODE, fb->saved_kb_mode) < 0) {
- GP_DEBUG(1, "Failed to ioctl KDSKBMODE (restore KBMODE)"
- " /dev/tty%i: %s", fb->con_nr, strerror(errno));
- }
- }
+ if (fb->flags & GP_FB_INPUT_KBD)
+ exit_kbd(fb);
/* switch back console */
if (fb->last_con_nr != -1)
@@ -213,7 +255,34 @@ static void fb_exit(GP_Backend *self)
free(self);
}
-GP_Backend *GP_BackendLinuxFBInit(const char *path, int flag)
+static void fb_flip_shadow(GP_Backend *self)
+{
+ struct fb_priv *fb = GP_BACKEND_PRIV(self);
+
+ GP_DEBUG(2, "Flipping buffer");
+
+ memcpy(fb->fb_mem, fb->context.pixels, fb->bsize);
+}
+
+static void fb_update_rect_shadow(GP_Backend *self, GP_Coord x0, GP_Coord y0,
+ GP_Coord x1, GP_Coord y1)
+{
+ struct fb_priv *fb = GP_BACKEND_PRIV(self);
+
+ GP_DEBUG(2, "Flipping buffer");
+
+ size_t size = ((x1 - x0) * fb->context.bpp) / 8;
+
+ for (;y0 <= y1; y0++) {
+ void *src = GP_PIXEL_ADDR(&fb->context, x0, y0);
+ void *dst = (char*)fb->fb_mem +
+ y0 * fb->context.bytes_per_row +
+ (x0 * fb->context.bpp)/8;
+ memcpy(dst, src, size);
+ }
+}
+
+GP_Backend *GP_BackendLinuxFBInit(const char *path, int flags)
{
GP_Backend *backend;
struct fb_priv *fb;
@@ -229,9 +298,14 @@ GP_Backend *GP_BackendLinuxFBInit(const char *path, int flag)
fb = GP_BACKEND_PRIV(backend);
- if (allocate_console(fb, flag))
+ if (allocate_console(fb, flags & GP_FB_INPUT_KBD))
goto err1;
+ if (flags & GP_FB_INPUT_KBD) {
+ if (init_kbd(fb))
+ goto err1;
+ }
+
/* open and mmap framebuffer */
GP_DEBUG(1, "Opening framebuffer '%s'", path);
@@ -261,7 +335,7 @@ GP_Backend *GP_BackendLinuxFBInit(const char *path, int flag)
* Framebuffer is grayscale.
*/
if (vscri.grayscale) {
- //TODO
+ GP_WARN("Grayscale not implemented!");
goto err3;
}
@@ -277,19 +351,30 @@ GP_Backend *GP_BackendLinuxFBInit(const char *path, int flag)
goto err3;
}
- fb->context.pixels = mmap(NULL, fscri.smem_len,
- PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED,
- fd, 0);
+ if (flags & GP_FB_SHADOW) {
+ fb->context.pixels = malloc(fscri.smem_len);
+
+ if (!fb->context.pixels) {
+ GP_DEBUG(1, "Malloc failed :(");
+ goto err3;
+ }
+ }
+
+ fb->fb_mem = mmap(NULL, fscri.smem_len,
+ PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0);
- if (fb->context.pixels == MAP_FAILED) {
+ if (fb->fb_mem == MAP_FAILED) {
GP_DEBUG(1, "mmaping framebuffer failed: %s", strerror(errno));
- goto err3;
+ goto err4;
}
fb->fb_fd = fd;
- fb->bsize = fscri.smem_len;
+ fb->bsize = fscri.smem_len;
strcpy(fb->path, path);
- fb->flag = flag;
+ fb->flags = flags;
+
+ if (!(flags & GP_FB_SHADOW))
+ fb->context.pixels = fb->fb_mem;
fb->context.w = vscri.xres;
fb->context.h = vscri.yres;
@@ -302,22 +387,28 @@ GP_Backend *GP_BackendLinuxFBInit(const char *path, int flag)
fb->context.bytes_per_row = fscri.line_length;
fb->context.pixel_type = pixel_type;
+ int shadow = flags & GP_FB_SHADOW;
+ int kbd = flags & GP_FB_INPUT_KBD;
+
/* update API */
backend->name = "Linux FB";
backend->context = &fb->context;
- backend->Flip = NULL;
- backend->UpdateRect = NULL;
+ backend->Flip = shadow ? fb_flip_shadow : NULL;
+ backend->UpdateRect = shadow ? fb_update_rect_shadow : NULL;
backend->Exit = fb_exit;
backend->SetAttributes = NULL;
backend->ResizeAck = NULL;
- backend->Poll = flag ? fb_poll : NULL;
- backend->Wait = flag ? fb_wait : NULL;
+ backend->Poll = kbd ? fb_poll : NULL;
+ backend->Wait = kbd ? fb_wait : NULL;
backend->fd = fb->con_fd;
backend->timers = NULL;
GP_EventQueueInit(&backend->event_queue, vscri.xres, vscri.yres, 0);
return backend;
+err4:
+ if (flags & GP_FB_SHADOW)
+ free(fb->context.pixels);
err3:
close(fd);
err2:
-----------------------------------------------------------------------
Summary of changes:
configure | 5 +-
demos/c_simple/linetest.c | 25 ++-
demos/c_simple/shapetest.c | 20 ++-
demos/c_simple/v4l2_show.c | 3 -
demos/particle/particle_demo.c | 24 ++-
demos/spiv/cpu_timer.c | 13 +
demos/spiv/cpu_timer.h | 7 +-
demos/spiv/spiv.c | 7 +-
demos/spiv/spiv_help.c | 3 +
.../version.c => include/backends/GP_AALib.h | 20 +-
include/backends/GP_Backends.h | 1 +
include/backends/GP_LinuxFB.h | 19 ++-
include/core/GP_Common.h | 1 +
libs/backends/GP_AALib.c | 280 ++++++++++++++++++++
libs/backends/GP_BackendInit.c | 33 ++-
libs/backends/GP_LinuxFB.c | 261 ++++++++++++------
libs/backends/GP_SDL.c | 19 +-
libs/filters/GP_ResizeLinear.gen.c.t | 2 -
libs/input/GP_InputDriverKBD.c | 14 +-
19 files changed, 630 insertions(+), 127 deletions(-)
copy demos/c_simple/version.c => include/backends/GP_AALib.h (88%)
create mode 100644 libs/backends/GP_AALib.c
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0