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
21 Jul '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 bcd8f5bd8906312aee47f6cbf16eba26f69ea1c3 (commit)
via a6718e68a480bde3453228f2ac4579fbebd8ff03 (commit)
via 7ac428d4c42068bf9e9344c23a4f38bc65f07bbe (commit)
via 884dd7a3d80177fb248d869ef738f6aa07c0b03c (commit)
via 2bf13c5f6bae8334f7be911f2754d8b3b620b8c5 (commit)
via 271cd6a9b3d67f3590e2e70849cb862578a63378 (commit)
from 5ec9bafb0205f6f1aebde21eebcb2719bbee9074 (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/bcd8f5bd8906312aee47f6cbf16eba26f69e…
commit bcd8f5bd8906312aee47f6cbf16eba26f69ea1c3
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 20 23:28:46 2013 +0200
container: ZIP: Add support for loading PNG.
We need to add more general loaders here, but that is
not possible without small changed in general loaders
structure, so add a bit hacky support for PNG for now.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_ZIP.c b/libs/loaders/GP_ZIP.c
index 4874c7c..c9064b8 100644
--- a/libs/loaders/GP_ZIP.c
+++ b/libs/loaders/GP_ZIP.c
@@ -344,14 +344,24 @@ static GP_Context *zip_next_file(FILE *f, GP_ProgressCallback *callback)
goto out;
ret = GP_ReadJPG(f, callback);
+
goto out;
break;
case COMPRESS_DEFLATE:
if (read_deflate(f, &header, &fres))
goto out;
+
ret = GP_ReadJPG(fres, callback);
- err = errno;
+
+ if (!ret) {
+ rewind(fres);
+ ret = GP_ReadPNG(fres, callback);
+ }
+
+ if (!ret)
+ err = errno;
+
fclose(fres);
goto out;
break;
http://repo.or.cz/w/gfxprim.git/commit/a6718e68a480bde3453228f2ac4579fbebd8…
commit a6718e68a480bde3453228f2ac4579fbebd8ff03
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 20 23:26:56 2013 +0200
loaders: PNG: Change the ReadPNG() and OpenPNG
The ReadPNG() now expects the PNG header too and the OpenPNG() does
rewind the file after the signature is checked.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_PNG.c b/libs/loaders/GP_PNG.c
index 47a4d6a..9e7ce53 100644
--- a/libs/loaders/GP_PNG.c
+++ b/libs/loaders/GP_PNG.c
@@ -78,6 +78,8 @@ int GP_OpenPNG(const char *src_path, FILE **f)
GP_DEBUG(1, "Found PNG signature in '%s'", src_path);
+ rewind(*f);
+
return 0;
err2:
fclose(*f);
@@ -133,7 +135,7 @@ GP_Context *GP_ReadPNG(FILE *f, GP_ProgressCallback *callback)
}
png_init_io(png, f);
- png_set_sig_bytes(png, 8);
+ png_set_sig_bytes(png, 0);
png_read_info(png, png_info);
png_get_IHDR(png, png_info, &w, &h, &depth,
http://repo.or.cz/w/gfxprim.git/commit/7ac428d4c42068bf9e9344c23a4f38bc65f0…
commit 7ac428d4c42068bf9e9344c23a4f38bc65f07bbe
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 20 17:36:20 2013 +0200
doc: loaders_python: Update.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/doc/loaders_python.txt b/doc/loaders_python.txt
index 8fa511a..de37a29 100644
--- a/doc/loaders_python.txt
+++ b/doc/loaders_python.txt
@@ -12,6 +12,16 @@ import gfxprim.loaders as loaders
img = loaders.Load(path, callback=None)
+ img = loaders.LoadBMP(path, callback=None)
+ img = loaders.LoadGIF(path, callback=None)
+ img = loaders.LoadJPG(path, callback=None)
+ img = loaders.LoadPBM(path, callback=None)
+ img = loaders.LoadPGM(path, callback=None)
+ img = loaders.LoadPNG(path, callback=None)
+ img = loaders.LoadPNM(path, callback=None)
+ img = loaders.LoadPPM(path, callback=None)
+ img = loaders.LoadPSP(path, callback=None)
+ img = loaders.LoadTIFF(path, callback=None)
-------------------------------------------------------------------------------
Loads an image from a file.
@@ -40,11 +50,14 @@ import gfxprim.loaders as loaders
img.loaders.Save(path, callback=None)
- img.loaders.SavePNG(path, callback=None)
-
- img.loaders.SaveJPG(path, callback=None)
-
img.loaders.SaveBMP(path, callback=None)
+ img.loaders.SaveJPG(path, callback=None)
+ img.loaders.SavePBM(path, callback=None)
+ img.loaders.SavePGM(path, callback=None)
+ img.loaders.SavePNG(path, callback=None)
+ img.loaders.SavePNM(path, callback=None)
+ img.loaders.SavePPM(path, callback=None)
+ img.loaders.SaveTIFF(path, callback=None)
-------------------------------------------------------------------------------
Save image to a file.
@@ -57,7 +70,7 @@ May raise 'OSError' with errno set to 'EPERM', 'EISDIR', 'ENOENT' or any other
May raise 'OSError' with errno set to 'ENOSYS' on unsupported pixel type for
a given format.
-May raise 'OSError' with errno set to 'EIO' when file is damaged.
+May raise 'OSError' with errno set to 'EIO' when filesystem is full.
May raise 'OSError' with errno set to 'ECANCELED' when action was interrupted
by callback.
http://repo.or.cz/w/gfxprim.git/commit/884dd7a3d80177fb248d869ef738f6aa07c0…
commit 884dd7a3d80177fb248d869ef738f6aa07c0b03c
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 20 17:28:27 2013 +0200
pywrap: loaders: Add a new methods.
* Add error checking for TIFF Load and Save methods.
* Add new Save methods into the loaders submodule.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/pylib/gfxprim/loaders/__init__.py b/pylib/gfxprim/loaders/__init__.py
index a9878fa..d1a63a6 100644
--- a/pylib/gfxprim/loaders/__init__.py
+++ b/pylib/gfxprim/loaders/__init__.py
@@ -24,7 +24,7 @@ def _init(module):
Generally, not all pixel types work with all formats.
"""
c_loaders.GP_SaveImage(self.ctx, filename, callback)
-
+
@extend(LoadersSubmodule)
def SavePNG(self, filename, callback=None):
"""Save the image as PNG.
@@ -32,7 +32,7 @@ def _init(module):
Generally, not all pixel types work with all formats.
"""
c_loaders.GP_SavePNG(self.ctx, filename, callback)
-
+
@extend(LoadersSubmodule)
def SaveJPG(self, filename, callback=None):
"""Save the image as JPEG.
@@ -40,7 +40,7 @@ def _init(module):
Generally, not all pixel types work with all formats.
"""
c_loaders.GP_SaveJPG(self.ctx, filename, callback)
-
+
@extend(LoadersSubmodule)
def SaveBMP(self, filename, callback=None):
"""Save the image as BMP.
@@ -49,6 +49,46 @@ def _init(module):
"""
c_loaders.GP_SaveBMP(self.ctx, filename, callback)
+ @extend(LoadersSubmodule)
+ def SavePBM(self, filename, callback=None):
+ """Save the image as PBM.
+
+ Generally, not all pixel types work with all formats.
+ """
+ c_loaders.GP_SavePBM(self.ctx, filename, callback)
+
+ @extend(LoadersSubmodule)
+ def SavePGM(self, filename, callback=None):
+ """Save the image as PGM.
+
+ Generally, not all pixel types work with all formats.
+ """
+ c_loaders.GP_SavePGM(self.ctx, filename, callback)
+
+ @extend(LoadersSubmodule)
+ def SavePPM(self, filename, callback=None):
+ """Save the image as PPM.
+
+ Generally, not all pixel types work with all formats.
+ """
+ c_loaders.GP_SavePPM(self.ctx, filename, callback)
+
+ @extend(LoadersSubmodule)
+ def SavePNM(self, filename, callback=None):
+ """Save the image as PNM.
+
+ Generally, not all pixel types work with all formats.
+ """
+ c_loaders.GP_SavePNM(self.ctx, filename, callback)
+
+ @extend(LoadersSubmodule)
+ def SaveTIFF(self, filename, callback=None):
+ """Save the image as TIFF.
+
+ Generally, not all pixel types work with all formats.
+ """
+ c_loaders.GP_SaveTIFF(self.ctx, filename, callback)
+
# Imports from the SWIG module
import re
def strip_GP(s):
diff --git a/pylib/gfxprim/loaders/loaders.i b/pylib/gfxprim/loaders/loaders.i
index e651a1c..66bd1e8 100644
--- a/pylib/gfxprim/loaders/loaders.i
+++ b/pylib/gfxprim/loaders/loaders.i
@@ -65,4 +65,22 @@ ERROR_ON_NONZERO(GP_SavePGM);
ERROR_ON_NONZERO(GP_SavePPM);
ERROR_ON_NONZERO(GP_SavePNM);
+%newobject GP_LoadPBM;
+%newobject GP_LoadPGM;
+%newobject GP_LoadPPM;
+%newobject GP_LoadPNM;
+
%include "GP_PNM.h"
+
+ERROR_ON_NULL(GP_LoadTIFF);
+ERROR_ON_NONZERO(GP_SaveTIFF);
+
+%newobject GP_LoadTIFF;
+
+%include "GP_TIFF.h"
+
+ERROR_ON_NULL(GP_LoadPSP);
+
+%newobject GP_LoadPSP;
+
+%include "GP_PSP.h"
http://repo.or.cz/w/gfxprim.git/commit/2bf13c5f6bae8334f7be911f2754d8b3b620…
commit 2bf13c5f6bae8334f7be911f2754d8b3b620b8c5
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 20 17:14:51 2013 +0200
doc: Update general information.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/doc/general.txt b/doc/general.txt
index 23de40d..4179408 100644
--- a/doc/general.txt
+++ b/doc/general.txt
@@ -5,7 +5,7 @@ Gfxprim is simple modular 2D bitmap graphics library with emphasis on speed
and correctness.
One of the key points of the library is meta-programming. Most of the
-operations and filters are wriiten in http://jinja.pocoo.org/[Jinja]
+operations and filters are written in http://jinja.pocoo.org/[Jinja]
templating language that is used to generate specialized code in C
programmming language. Creating code that works with less usuall pixel types
should be as easy as adding pixel definition into the configuration and
@@ -22,9 +22,9 @@ that represents in-memory pixmap.
The Core also contains generated code for basic operations such as
link:get_put_pixel.html[GetPixel] and link:get_put_pixel.html[PutPixel] and
-optimized code for writing continous line of pixels 'GP_WritePixels' that are
-base for the more complex drawing primitives in GFX or for graphics operations
-in Filters.
+optimized functions for writing continous line of pixels 'GP_WritePixels' that
+are base for the more complex drawing primitives in GFX or for graphics
+operations in Filters.
link:blits.html[Blits] are functions used to copy part of one bitmap into
another bitmap. The blits be also used for primitive bitmap pixel type
@@ -65,49 +65,48 @@ Loaders
-------
link:loaders.html[Loaders] are part that is resposible for loading and saving
-images into various standard formats (PNG, JPEG, GIF, BMP, PNM, etc...).
+images into various standard formats (PNG, JPEG, GIF, TIFF, BMP, PNM, etc...).
.Currently supported formats
[width="100%",options="header"]
|=============================================================================
-| Extension | Format Name | Signature | Read Support | Write Support
+| Extension | Format Name | Read Support | Write Support
-| JPEG | | [green]*Yes* | [green]*Yes* | [green]*Yes*
+| JPEG | | [green]*Yes* | [green]*Yes*
| PNG |
Portable Network Graphics |
- [green]*Yes* |
[green]#16 Bit RGB not supported# |
[green]#16 Bit RGB not supported#
| GIF |
Graphics Interchange Format |
[green]*Yes* |
- [green]*Yes* |
[black]*No*
| BMP | |
- [green]*Yes* |
[green]#RLE4 and some less common bitfiels not supported# |
[green]#RGB888 only#
| TIFF |
Tagged Image File Format |
- [green]*Yes* |
- [gray]#Not finished# |
- [black]*No*
+ [green]#Most of the Palette, RGB and Grayscale works (no tiles yet)# |
+ [green]#RGB888 and Grayscale#
| PSP |
Paint Shop Pro Image |
- [green]*Yes* |
[green]#Composite image only for newer formats than 3.0# |
[black]*No*
| PBM PGM PNM |
Netpbm portable bitmap |
- [black]*No* |
- [gray]#Not finished# |
- [gray]#Not finished#
+ [green]#All but < 8bit binary grayscale# |
+ [green]#All ASCII formats#
+
+| CBZ |
+ Comic book archive |
+ [green]#Experimental support via ZIP Container# |
+ [black]*No*
|=============================================================================
@@ -200,14 +199,20 @@ drawing on screen (or into a window) and for getting keystrokes/mouse
coordinates. So far we support X11, linux framebuffer and SDL as a graphics
backend.
+There is also a virtual backend used for testing that allows you to create a
+backend of any pixel type on the top of other backends.
+
+Python bindings
+---------------
+
+Python bindings currently covers most of the library, there is (not yet
+finished) documentation for link:core_python.html[Core],
+link:gfx_python.html[Gfx], link:loaders_python.html[Loaders] and
+link:backends_python.html[Backends].
Work in progress
----------------
-* Python bindings
-
* Anti Aliased drawing
* Gamma correction and color profiles
-
-* Alfa channel blits
diff --git a/doc/input.txt b/doc/input.txt
index aa69595..08b0816 100644
--- a/doc/input.txt
+++ b/doc/input.txt
@@ -165,7 +165,7 @@ image::keyboard.svg["Keyboard Layout",width=800,link="keyboard.svg"]
* The system event is used with 'GP_EV_SYS_RESIZE' and informs you
of the new window size.
-* The value of timer event is simply pointer to the expired timer.
+* The value of timer event is simply pointer to the expired link:#Timers[Timer].
The 'dev_id' is not used at the moment and may be removed.
http://repo.or.cz/w/gfxprim.git/commit/271cd6a9b3d67f3590e2e70849cb862578a6…
commit 271cd6a9b3d67f3590e2e70849cb862578a63378
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 20 16:37:28 2013 +0200
examples, doc: Add backend timers example.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/c_simple/Makefile b/demos/c_simple/Makefile
index 3ed296b..c32d873 100644
--- a/demos/c_simple/Makefile
+++ b/demos/c_simple/Makefile
@@ -19,7 +19,7 @@ APPS=backend_example loaders_example loaders filters_symmetry gfx_koch input_example fileview linetest randomshapetest fonttest loaders_register blittest textaligntest abort sin_AA x11_windows debug_handler gaussian_noise byte_utils version pretty_print timers- zip_container
+ zip_container backend_timers_example
ifeq ($(HAVE_LIBSDL),yes)
APPS+=SDL_glue
@@ -29,6 +29,7 @@ endif
showimage: LDLIBS+=$(LDLIBS_BACKENDS) $(LDLIBS_LOADERS)
backend_example: LDLIBS+=$(LDLIBS_BACKENDS)
+backend_timers_example: LDLIBS+=$(LDLIBS_BACKENDS)
virtual_backend_example: LDLIBS+=$(LDLIBS_BACKENDS)
loaders_example: LDLIBS+=$(LDLIBS_LOADERS)
loaders: LDLIBS+=$(LDLIBS_LOADERS)
diff --git a/demos/c_simple/backend_timers_example.c b/demos/c_simple/backend_timers_example.c
new file mode 100644
index 0000000..e31075c
--- /dev/null
+++ b/demos/c_simple/backend_timers_example.c
@@ -0,0 +1,117 @@
+/*****************************************************************************
+ * 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> *
+ * *
+ *****************************************************************************/
+
+ /*
+
+ Simple backend timers example.
+
+ */
+
+#include <GP.h>
+
+static void redraw(GP_Backend *self)
+{
+ GP_Context *context = self->context;
+ GP_Pixel black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, context);
+
+ GP_Fill(context, black_pixel);
+
+ /* Update the backend screen */
+ GP_BackendFlip(self);
+}
+
+static uint32_t timer_callback(GP_Timer *self)
+{
+ uint32_t next = random() % 10000;
+
+ printf("Timer %s callback called, rescheduling after %u.n",
+ self->id, (unsigned) next);
+
+ return next;
+}
+
+int main(void)
+{
+ GP_Backend *backend;
+ const char *backend_opts = "X11:100x100";
+
+ backend = GP_BackendInit(backend_opts, "Backend Timers Example", stderr);
+
+ if (backend == NULL) {
+ fprintf(stderr, "Failed to initialize backendn");
+ return 1;
+ }
+
+ redraw(backend);
+
+ /*
+ * Periodic timer with 1000ms interval. As the callback is set to NULL
+ * Timer Event is pushed to event queue upon expiration.
+ */
+ GP_TIMER_DECLARE(timer1, 0, 1000, "Timer 1", NULL, NULL);
+
+ /*
+ * Timer with a callback, this timer gets scheduled depending on ouput
+ * from callback (0 means disable timer).
+ */
+ GP_TIMER_DECLARE(timer2, 5000, 0, "Timer 2", timer_callback, NULL);
+
+ GP_BackendAddTimer(backend, &timer1);
+ GP_BackendAddTimer(backend, &timer2);
+
+ /* Handle events */
+ for (;;) {
+ GP_Event ev;
+
+ GP_BackendWaitEvent(backend, &ev);
+
+ GP_EventDump(&ev);
+
+ switch (ev.type) {
+ case GP_EV_KEY:
+ switch (ev.val.val) {
+ case GP_KEY_ESC:
+ case GP_KEY_Q:
+ GP_BackendExit(backend);
+ return 0;
+ break;
+ }
+ break;
+ case GP_EV_SYS:
+ switch (ev.code) {
+ case GP_EV_SYS_RESIZE:
+ GP_BackendResizeAck(backend);
+ redraw(backend);
+ break;
+ case GP_EV_SYS_QUIT:
+ GP_BackendExit(backend);
+ return 0;
+ break;
+ }
+ break;
+ }
+ }
+
+ GP_BackendExit(backend);
+
+ return 0;
+}
diff --git a/doc/backends.txt b/doc/backends.txt
index 7130b29..a57a7ad 100644
--- a/doc/backends.txt
+++ b/doc/backends.txt
@@ -47,7 +47,7 @@ GP_Backend *GP_BackendSDLInit(GP_Size w, GP_Size h,
const char *caption);
-------------------------------------------------------------------------------
-Initialize 'SDL' as an backend driver. The backend is thread safe as all the
+Initialize 'SDL' as a backend driver. The backend is thread safe as all the
operations are guarded by locks.
You can't initialize more than one backend at a time, which is inherited 'SDL'
@@ -236,7 +236,7 @@ GP_BackendExit
void GP_BackendExit(GP_Backend *backend);
-------------------------------------------------------------------------------
-Calls an backend exit callback. Restores the display, keyboard, etc. state
+Calls a backend exit callback. Restores the display, keyboard, etc. state
back.
WARNING: It's important to call this functions on application exit. If you
@@ -424,6 +424,9 @@ backend 'Poll' or 'Wait' functions.
If timer callback is set to 'NULL' a timer event is pushed to the backend
input queue once timer has expired otherwise timer callback is called.
+TIP: For example usage see backend timers
+ link:example_backend_timers.html[example].
+
GP_BackendTimersInQueue
^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/example_backend_timers.txt b/doc/example_backend_timers.txt
new file mode 100644
index 0000000..e9d479f
--- /dev/null
+++ b/doc/example_backend_timers.txt
@@ -0,0 +1,7 @@
+Backend Timers Example
+----------------------
+
+[source,c]
+------------------------------------------------------------------
+include::../demos/c_simple/backend_timers_example.c[]
+------------------------------------------------------------------
-----------------------------------------------------------------------
Summary of changes:
demos/c_simple/Makefile | 3 +-
...{backend_example.c => backend_timers_example.c} | 57 ++++++++++----------
doc/backends.txt | 7 ++-
...xample_input.txt => example_backend_timers.txt} | 6 +-
doc/general.txt | 47 +++++++++-------
doc/input.txt | 2 +-
doc/loaders_python.txt | 23 ++++++--
libs/loaders/GP_PNG.c | 4 +-
libs/loaders/GP_ZIP.c | 12 ++++-
pylib/gfxprim/loaders/__init__.py | 46 +++++++++++++++-
pylib/gfxprim/loaders/loaders.i | 18 ++++++
11 files changed, 159 insertions(+), 66 deletions(-)
copy demos/c_simple/{backend_example.c => backend_timers_example.c} (74%)
copy doc/{example_input.txt => example_backend_timers.txt} (59%)
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 Jul '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 5ec9bafb0205f6f1aebde21eebcb2719bbee9074 (commit)
from 7d6a3c37a8066eaae2a5c3a913c9ee53768ea677 (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/5ec9bafb0205f6f1aebde21eebcb2719bbee…
commit 5ec9bafb0205f6f1aebde21eebcb2719bbee9074
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 20 00:17:50 2013 +0200
spiv: Stop loader thread before the seek in timer
This fixes the same problem as was in the seek for the timer callback.
The seek in image_loader may free the image the loader is working with
so we need explicitly stop the loader thread before the seek.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c
index 6d0cf85..936cb14 100644
--- a/demos/spiv/spiv.c
+++ b/demos/spiv/spiv.c
@@ -575,7 +575,6 @@ static void image_seek(struct loader_params *params,
* image we are currently resamling.
*/
stop_loader();
-
image_loader_seek(offset, whence);
show_image(params);
}
@@ -641,6 +640,11 @@ static uint32_t timer_callback(GP_Timer *self)
{
struct loader_params *params = self->priv;
+ /*
+ * We need to stop loader first because image loader seek may free
+ * image we are currently resamling.
+ */
+ stop_loader();
image_loader_seek(IMG_CUR, 1);
show_image(params);
-----------------------------------------------------------------------
Summary of changes:
demos/spiv/spiv.c | 6 +++++-
1 files changed, 5 insertions(+), 1 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
20 Jul '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 7d6a3c37a8066eaae2a5c3a913c9ee53768ea677 (commit)
via c34bb360259398f9984c827153c53b5d35821ca2 (commit)
via df6de85ac91e6206be01f513951a04df2eee0833 (commit)
via 41bce152b73f2401ac8f5f8505e1be2e4ccb6ef2 (commit)
via b6cbcf6d7265335c20d6dc268160aac84d5af3aa (commit)
from 3a23d37e9e2fc63f02435221e96cef601b5ce2ed (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/7d6a3c37a8066eaae2a5c3a913c9ee53768e…
commit 7d6a3c37a8066eaae2a5c3a913c9ee53768ea677
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 20 00:01:48 2013 +0200
spiv: A bit crude support for containers.
* Mostly works, needs better implementation though
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/spiv/image_loader.c b/demos/spiv/image_loader.c
index 7852fc6..ae4ac6d 100644
--- a/demos/spiv/image_loader.c
+++ b/demos/spiv/image_loader.c
@@ -20,6 +20,8 @@
* *
*****************************************************************************/
+#include <errno.h>
+
#include <core/GP_Context.h>
#include <core/GP_Debug.h>
@@ -33,6 +35,7 @@
static struct image_cache *img_cache;
static struct image_list *img_list;
static GP_Context *cur_img;
+static GP_Container *cur_cont;
int image_loader_init(const char *args[], unsigned int cache_max_bytes)
{
@@ -58,10 +61,16 @@ GP_Context *image_loader_get_image(GP_ProgressCallback *callback, int elevate)
struct cpu_timer timer;
const char *path;
GP_Context *img;
+ int err;
if (cur_img)
return cur_img;
+ if (cur_cont) {
+ cur_img = GP_ContainerLoad(cur_cont, callback);
+ return cur_img;
+ }
+
path = image_list_img_path(img_list);
cur_img = image_cache_get(img_cache, elevate, path);
@@ -73,8 +82,31 @@ GP_Context *image_loader_get_image(GP_ProgressCallback *callback, int elevate)
img = GP_LoadImage(path, callback);
- if (!img)
+ if (!img) {
+ err = errno;
+
+ /*
+ * Try containers, ZIP for now, more to come
+ *
+ * TODO: How to cache container content?
+ */
+ cur_cont = GP_OpenZip(path);
+
+ if (cur_cont) {
+ img = GP_ContainerLoad(cur_cont, callback);
+
+ if (img) {
+ cur_img = img;
+ return img;
+ }
+
+ GP_ContainerClose(cur_cont);
+ cur_cont = NULL;
+ }
+
+ errno = err;
return NULL;
+ }
image_cache_put(img_cache, img, path);
@@ -85,6 +117,15 @@ GP_Context *image_loader_get_image(GP_ProgressCallback *callback, int elevate)
const char *image_loader_img_path(void)
{
+ //TODO: Make this more elegant
+ static char path[512];
+
+ if (cur_cont) {
+ snprintf(path, sizeof(path), "%s:%u",
+ image_list_img_path(img_list), cur_cont->cur_img);
+ return path;
+ }
+
return image_list_img_path(img_list);
}
@@ -112,6 +153,36 @@ void image_loader_seek(enum img_seek_offset offset, int whence)
{
drop_cur_img();
+ if (cur_cont) {
+ switch (offset) {
+ case IMG_FIRST:
+ case IMG_LAST:
+ //TODO do something better for IMG_DIR
+ case IMG_DIR:
+ GP_ContainerClose(cur_cont);
+ cur_cont = NULL;
+ goto list_seek;
+ case IMG_CUR:
+ break;
+ }
+ /*
+ * TODO: We should be able to count how much
+ * we get out of the container and seek
+ * N images in the list
+ *
+ * What about wrapping around?
+ */
+ if (GP_ContainerSeek(cur_cont, whence, GP_CONT_CUR)) {
+ GP_ContainerClose(cur_cont);
+ cur_cont = NULL;
+ goto list_seek;
+ }
+
+ return;
+ }
+
+list_seek:
+
switch (offset) {
case IMG_FIRST:
image_list_first(img_list);
diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c
index 96eda04..6d0cf85 100644
--- a/demos/spiv/spiv.c
+++ b/demos/spiv/spiv.c
@@ -570,6 +570,12 @@ static void show_image(struct loader_params *params)
static void image_seek(struct loader_params *params,
enum img_seek_offset offset, int whence)
{
+ /*
+ * We need to stop loader first because image loader seek may free
+ * image we are currently resamling.
+ */
+ stop_loader();
+
image_loader_seek(offset, whence);
show_image(params);
}
http://repo.or.cz/w/gfxprim.git/commit/c34bb360259398f9984c827153c53b5d3582…
commit c34bb360259398f9984c827153c53b5d35821ca2
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Jul 19 23:44:46 2013 +0200
build: Update list of exported symbols.
Add TIFFSave() + Container + ZIP container API.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/build/syms/Loaders_symbols.txt b/build/syms/Loaders_symbols.txt
index 9820d2f..1814807 100644
--- a/build/syms/Loaders_symbols.txt
+++ b/build/syms/Loaders_symbols.txt
@@ -37,6 +37,7 @@ GP_MatchTIFF
GP_OpenTIFF
GP_ReadTIFF
GP_LoadTIFF
+GP_SaveTIFF
GP_SavePBM
GP_LoadPBM
@@ -79,3 +80,9 @@ GP_MetaDataCreate
GP_MetaDataPrint
GP_MetaDataGetDouble
GP_MetaDataFromExif
+
+GP_ContainerLoad
+GP_ContainerSeek
+
+GP_MatchZip
+GP_OpenZip
http://repo.or.cz/w/gfxprim.git/commit/df6de85ac91e6206be01f513951a04df2eee…
commit df6de85ac91e6206be01f513951a04df2eee0833
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Jul 19 23:42:24 2013 +0200
loaders: Containers, ZIP: More work done.
* Add ZIP signature matching function
* Add basic seek API + Code
(not finished, yet but mostly working)
* ZIP: fix loading for uncompressed parts
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/include/loaders/GP_Container.h b/include/loaders/GP_Container.h
index 36dafdf..d3e9d0f 100644
--- a/include/loaders/GP_Container.h
+++ b/include/loaders/GP_Container.h
@@ -35,6 +35,12 @@
struct GP_Container;
+enum GP_ContainerWhence {
+ GP_CONT_FIRST,
+ GP_CONT_LAST,
+ GP_CONT_CUR,
+};
+
struct GP_ContainerOps {
/*
* Loads next image from container, use the inline function defined
@@ -44,11 +50,28 @@ struct GP_ContainerOps {
GP_ProgressCallback *callback);
/*
+ * Just loads current image, does not advance to the next image.
+ */
+ GP_Context *(*Load)(struct GP_Container *self,
+ GP_ProgressCallback *callback);
+
+ /*
* Close callback, use the inline function defined bellow.
*/
void (*Close)(struct GP_Container *self);
- //TODO: Seek
+ /*
+ * Seeks to the offset from whence.
+ *
+ * Returns 0 on success, errno on failure.
+ */
+ int (*Seek)(struct GP_Container *self, int offset,
+ enum GP_ContainerWhence whence);
+
+ /*
+ * Container type name.
+ */
+ const char *type;
};
typedef struct GP_Container {
@@ -57,12 +80,16 @@ typedef struct GP_Container {
* of images in container is not known prior to parsing the whole
* file.
*/
- int img_count;
+ unsigned int img_count;
+
/*
* Current image counter, do not change from application.
*/
- int cur_img;
+ unsigned int cur_img;
+ /*
+ * Contains container callbacks
+ */
const struct GP_ContainerOps *ops;
char priv[];
@@ -79,6 +106,14 @@ static inline GP_Context *GP_ContainerLoadNext(GP_Container *self,
return self->ops->LoadNext(self, callback);
}
+/*
+ * Just loads current image, does not advance to the next one.
+ */
+GP_Context *GP_ContainerLoad(GP_Container *self, GP_ProgressCallback *callback);
+
+int GP_ContainerSeek(GP_Container *self, int offset,
+ enum GP_ContainerWhence whence);
+
static inline void GP_ContainerClose(GP_Container *self)
{
self->ops->Close(self);
diff --git a/include/loaders/GP_ZIP.h b/include/loaders/GP_ZIP.h
index 06031e9..cb97efd 100644
--- a/include/loaders/GP_ZIP.h
+++ b/include/loaders/GP_ZIP.h
@@ -36,4 +36,6 @@
GP_Container *GP_OpenZip(const char *path);
+int GP_MatchZip(const char *buf);
+
#endif /* LOADERS_GP_ZIP_H */
diff --git a/include/loaders/GP_ZIP.h b/libs/loaders/GP_Container.c
similarity index 73%
copy from include/loaders/GP_ZIP.h
copy to libs/loaders/GP_Container.c
index 06031e9..1a90289 100644
--- a/include/loaders/GP_ZIP.h
+++ b/libs/loaders/GP_Container.c
@@ -20,20 +20,31 @@
* *
*****************************************************************************/
- /*
-
- Zip container, could be used to load images from cbz or from zip files.
-
- */
-
-#ifndef LOADERS_GP_ZIP_H
-#define LOADERS_GP_ZIP_H
-
-#include "core/GP_Context.h"
-#include "core/GP_ProgressCallback.h"
+#include <errno.h>
+#include "core/GP_Debug.h"
#include "loaders/GP_Container.h"
-GP_Container *GP_OpenZip(const char *path);
-
-#endif /* LOADERS_GP_ZIP_H */
+int GP_ContainerSeek(GP_Container *self, int offset,
+ enum GP_ContainerWhence whence)
+{
+ if (!self->ops->Seek) {
+ GP_DEBUG(1, "Seek not implemented in %s container",
+ self->ops->type);
+ return ENOSYS;
+ }
+
+ return self->ops->Seek(self, offset, whence);
+}
+
+GP_Context *GP_ContainerLoad(GP_Container *self, GP_ProgressCallback *callback)
+{
+ if (!self->ops->Load) {
+ GP_DEBUG(1, "Load not implemented in %s container",
+ self->ops->type);
+ errno = ENOSYS;
+ return NULL;
+ }
+
+ return self->ops->Load(self, callback);
+}
diff --git a/libs/loaders/GP_ZIP.c b/libs/loaders/GP_ZIP.c
index c5ab037..4874c7c 100644
--- a/libs/loaders/GP_ZIP.c
+++ b/libs/loaders/GP_ZIP.c
@@ -34,15 +34,46 @@
#endif /* HAVE_ZLIB */
+#include "core/GP_Common.h"
#include "core/GP_Debug.h"
#include "loaders/GP_ByteUtils.h"
#include "loaders/GP_JPG.h"
+#include "loaders/GP_PNG.h"
#include "loaders/GP_ZIP.h"
#ifdef HAVE_ZLIB
+#define ZIP_CHUNKS_IN_TABLE 128
+
+/*
+ * Table used for seeks, populated on the go
+ */
+struct zip_chunks_table {
+ long offsets[ZIP_CHUNKS_IN_TABLE];
+ struct zip_chunks_table *next;
+ struct zip_chunks_table *prev;
+};
+
+struct zip_priv {
+ FILE *f;
+
+ /* Current position in zip continer counted in images we found */
+ unsigned int cur_pos;
+
+ /* Current table */
+ unsigned int cur_table_pos;
+ struct zip_chunks_table *cur_table;
+
+ /* Last table and index into it, this is used for addition */
+ unsigned int tables_used;
+ unsigned int table_used;
+ struct zip_chunks_table *last_table;
+
+ struct zip_chunks_table table;
+};
+
#define GEN_FLAG_ENCRYPTED 0x01
struct zip_local_header {
@@ -54,6 +85,9 @@ struct zip_local_header {
uint32_t comp_size;
uint32_t uncomp_size;
+ uint16_t fname_len;
+ uint16_t extf_len;
+
char *file_name;
};
@@ -73,7 +107,7 @@ enum compress_method {
COMPRESS_BZIP2 = 0x0c,
};
-const char *compress_method_names[] = {
+static const char *compress_method_names[] = {
"Stored (no compression)",
"Shrunk",
"Reduced with factor 1",
@@ -113,12 +147,6 @@ static int seek_bytes(FILE *f, uint32_t bytes)
return 0;
}
-static void read_stored(FILE *f, struct zip_local_header *header)
-{
- /* ignored for now */
- seek_bytes(f, header->uncomp_size);
-}
-
#define CHUNK 512
struct deflate_inbuf {
@@ -242,47 +270,63 @@ err0:
return err;
}
-static int zip_next_file(FILE *f, FILE **res)
+static int zip_load_header(FILE *f, struct zip_local_header *header)
{
- uint16_t fname_len, extf_len;
- struct zip_local_header header = {.file_name = NULL};
- int ret, err = 0;
+ int ret;
+
+ //TODO: check for central directory signature -> end of data
ret = GP_FRead(f, "0x50 0x4b 0x03 0x04 L2 L2 L2 I4 L4 L4 L4 L2 L2",
- &header.ver, &header.bit_flags, &header.comp_type,
- &header.crc, &header.comp_size, &header.uncomp_size,
- &fname_len, &extf_len);
+ &header->ver, &header->bit_flags, &header->comp_type,
+ &header->crc, &header->comp_size, &header->uncomp_size,
+ &header->fname_len, &header->extf_len);
if (ret != 13) {
GP_DEBUG(1, "Failed to read header");
return EIO;
}
+ return 0;
+}
+
+static GP_Context *zip_next_file(FILE *f, GP_ProgressCallback *callback)
+{
+ struct zip_local_header header = {.file_name = NULL};
+ int err = 0;
+ GP_Context *ret = NULL;
+ FILE *fres;
+
+ if ((err = zip_load_header(f, &header)))
+ goto out;
+
GP_DEBUG(1, "Have ZIP local header version %u.%u compression %s",
header.ver/10, header.ver%10,
compress_method_name(header.comp_type));
if (header.bit_flags & GEN_FLAG_ENCRYPTED) {
GP_DEBUG(1, "Can't handle encrypted files");
- return ENOSYS;
+ err = ENOSYS;
+ goto out;
}
/*
* If input was taken from stdin the fname_len is either set to zero or
* to one and filename is set to '-'.
*/
- if (fname_len) {
- header.file_name = malloc(fname_len + 1);
+ if (header.fname_len) {
+ header.file_name = malloc(header.fname_len + 1);
- if (!header.file_name)
- return ENOMEM;
+ if (!header.file_name) {
+ err = ENOMEM;
+ goto out;
+ }
- header.file_name[fname_len] = '0';
+ header.file_name[header.fname_len] = '0';
- if (fread(header.file_name, fname_len, 1, f) != 1) {
+ if (fread(header.file_name, header.fname_len, 1, f) != 1) {
GP_DEBUG(1, "Failed to read filename");
err = EIO;
- goto err0;
+ goto out;
}
GP_DEBUG(1, "Filename '%s' compressed size=%"PRIu32
@@ -291,69 +335,276 @@ static int zip_next_file(FILE *f, FILE **res)
header.uncomp_size);
}
- seek_bytes(f, extf_len);
+ seek_bytes(f, header.extf_len);
switch (header.comp_type) {
case COMPRESS_STORED:
- read_stored(f, &header);
+ /* skip directories */
+ if (header.uncomp_size == 0)
+ goto out;
+
+ ret = GP_ReadJPG(f, callback);
+ goto out;
break;
case COMPRESS_DEFLATE:
- read_deflate(f, &header, res);
+ if (read_deflate(f, &header, &fres))
+ goto out;
+
+ ret = GP_ReadJPG(fres, callback);
+ err = errno;
+ fclose(fres);
+ goto out;
break;
default:
GP_DEBUG(1, "Unimplemented compression %s",
compress_method_name(header.comp_type));
- return ENOSYS;
+ err = ENOSYS;
+ goto out;
}
- return 0;
-err0:
+out:
free(header.file_name);
- return err;
+ errno = err;
+ return ret;
}
-struct zip_priv {
- FILE *f;
-};
+static unsigned int last_offset_idx(struct zip_priv *priv)
+{
+ return priv->table_used + priv->tables_used * ZIP_CHUNKS_IN_TABLE;
+}
+
+static long last_recorded_offset(struct zip_priv *priv)
+{
+ const unsigned int last_idx = ZIP_CHUNKS_IN_TABLE - 1;
+
+ if (priv->table_used == 0) {
+ if (priv->last_table->prev)
+ return priv->last_table->prev->offsets[last_idx];
+
+ return -1;
+ }
+
+ return priv->last_table->offsets[priv->table_used - 1];
+}
+
+static void record_offset(struct zip_priv *priv, long offset)
+{
+ if (offset <= last_recorded_offset(priv))
+ return;
+
+ GP_DEBUG(2, "Recording offset to %i image (%li)",
+ last_offset_idx(priv), offset);
+
+ if (priv->table_used >= ZIP_CHUNKS_IN_TABLE) {
+ struct zip_chunks_table *new_table;
+
+ GP_DEBUG(1, "Allocating chunks table (table nr. %u) (size %i)",
+ priv->tables_used+1, ZIP_CHUNKS_IN_TABLE);
+
+ new_table = malloc(sizeof(struct zip_chunks_table));
+
+ if (!new_table) {
+ GP_WARN("Malloc failed :(");
+ return;
+ }
+
+ priv->tables_used++;
+ priv->table_used = 0;
+ new_table->prev = priv->last_table;
+ new_table->next = NULL;
+ priv->last_table->next = new_table;
+ priv->last_table = new_table;
+ }
+
+ priv->last_table->offsets[priv->table_used++] = offset;
+/*
+ printf("OFFSET tablen");
+ unsigned int i;
+ for (i = 0; i < priv->table_used; i++)
+ printf("** %u -> %lin", i, priv->last_table->offsets[i]);
+ */
+}
static GP_Context *zip_load_next(GP_Container *self,
GP_ProgressCallback *callback)
{
struct zip_priv *priv = GP_CONTAINER_PRIV(self);
- FILE *res = NULL;
GP_Context *ret;
- int err;
+ long offset;
GP_DEBUG(1, "Trying to load next image from ZIP container");
- do
- err = zip_next_file(priv->f, &res);
- while (!err && !res);
+ do {
+ offset = ftell(priv->f);
+ ret = zip_next_file(priv->f, callback);
+ } while (ret == NULL && errno == 0);
- if (err) {
- errno = err;
+ if (!ret)
return NULL;
+
+ if (ret)
+ record_offset(priv, offset);
+
+ priv->cur_pos++;
+ //self->cur_img++;
+ self->cur_img = priv->cur_pos;
+
+ return ret;
+}
+
+/* Seek to the current position */
+static void seek_cur_pos(struct zip_priv *priv)
+{
+ unsigned int cur_table = priv->cur_pos / ZIP_CHUNKS_IN_TABLE;
+ unsigned int cur_pos;
+
+ if (priv->cur_table_pos != cur_table) {
+ unsigned int i;
+
+ GP_DEBUG(3, "cur_pos %u out of cur table %u",
+ priv->cur_pos, priv->cur_table_pos);
+
+ priv->cur_table = &priv->table;
+
+ for (i = 0; i < cur_table; i++) {
+ if (priv->cur_table->next)
+ priv->cur_table = priv->cur_table->next;
+ else
+ GP_WARN("The cur_pos points after last table");
+ }
+
+ priv->cur_table_pos = cur_table;
}
- ret = GP_ReadJPG(res, callback);
- err = errno;
- fclose(res);
- errno = err;
+ //TODO: Asert that we are not in last table and cur_pos < table_used
+
+ cur_pos = priv->cur_pos % ZIP_CHUNKS_IN_TABLE;
+
+ GP_DEBUG(2, "Setting current position to %u (%li)",
+ priv->cur_pos, priv->cur_table->offsets[cur_pos]);
+
+ fseek(priv->f, priv->cur_table->offsets[cur_pos], SEEK_SET);
+}
+
+static int load_next_offset(struct zip_priv *priv)
+{
+ struct zip_local_header header = {.file_name = NULL};
+ int ret;
+ long offset = ftell(priv->f);
+
+ //TODO: End of file!
+ if ((ret = zip_load_header(priv->f, &header)))
+ return ret;
+
+ //TODO: Match image extension and signature
+ record_offset(priv, offset);
+
+ /* Seek to the next local header */
+ seek_bytes(priv->f, (uint32_t)header.fname_len +
+ (uint32_t)header.extf_len);
+ seek_bytes(priv->f, header.comp_size);
+
+ return 0;
+}
+
+/*
+ * Sets current position.
+ */
+static int set_cur_pos(struct zip_priv *priv, unsigned int where)
+{
+ unsigned int max = last_offset_idx(priv);
+ int err;
+
+ GP_DEBUG(2, "where %u max %u", where, max);
+
+ /* Move to the max and beyond */
+ if (where >= max) {
+ if (max == 0) {
+ if ((err = load_next_offset(priv)))
+ return err;
+ priv->cur_pos = 0;
+ } else {
+ priv->cur_pos = max - 1;
+ seek_cur_pos(priv);
+ }
+
+ while (priv->cur_pos < where) {
+ if ((err = load_next_offset(priv)))
+ return err;
+ priv->cur_pos++;
+ }
+
+ return 0;
+ }
+
+ priv->cur_pos = where;
+ seek_cur_pos(priv);
+
+ return 0;
+}
+
+static int zip_seek(GP_Container *self, int offset,
+ enum GP_ContainerWhence whence)
+{
+ struct zip_priv *priv = GP_CONTAINER_PRIV(self);
+ unsigned int where;
+ int ret;
+
+ GP_DEBUG(1, "Seek offset=%i whence=%i", offset, whence);
+
+ switch (whence) {
+ case GP_CONT_CUR:
+ if (offset < 0 && priv->cur_pos < (unsigned int)-offset) {
+ GP_WARN("Current position %u offset %i",
+ priv->cur_pos, offset);
+ where = 0;
+ } else {
+ where = priv->cur_pos + offset;
+ }
+ break;
+ case GP_CONT_FIRST:
+ where = offset;
+ break;
+ default:
+ return ENOSYS;
+ }
+
+ ret = set_cur_pos(priv, where);
+
+ self->cur_img = priv->cur_pos;
return ret;
}
+static GP_Context *zip_load(GP_Container *self,
+ GP_ProgressCallback *callback)
+{
+ GP_Context *img;
+
+ img = zip_load_next(self, callback);
+
+ if (!img)
+ return NULL;
+
+ zip_seek(self, -1, GP_CONT_CUR);
+
+ return img;
+}
+
static void zip_close(GP_Container *self)
{
struct zip_priv *priv = GP_CONTAINER_PRIV(self);
+ struct zip_chunks_table *i, *j;
GP_DEBUG(1, "Closing ZIP container");
+ /* Free allocated offset tables */
+ for (i = priv->table.next; i != NULL; j = i, i = i->next, free(j));
+
fclose(priv->f);
free(self);
}
-
static int open_zip(const char *path, FILE **file)
{
FILE *f;
@@ -387,7 +638,10 @@ err0:
static const struct GP_ContainerOps zip_ops = {
.LoadNext = zip_load_next,
+ .Load = zip_load,
.Close = zip_close,
+ .Seek = zip_seek,
+ .type = "ZIP",
};
GP_Container *GP_OpenZip(const char *path)
@@ -409,14 +663,31 @@ GP_Container *GP_OpenZip(const char *path)
goto err0;
}
- priv = GP_CONTAINER_PRIV(ret);
-
- priv->f = f;
+ GP_DEBUG(1, "ZIP Container initialized");
ret->img_count = -1;
ret->cur_img = 0;
ret->ops = &zip_ops;
+ priv = GP_CONTAINER_PRIV(ret);
+
+ priv->f = f;
+
+ priv->table.next = NULL;
+ priv->table.prev = NULL;
+
+ /* Cache for current table for seeks */
+ priv->cur_table = &priv->table;
+ priv->cur_table_pos = 0;
+
+ /* Current position */
+ priv->cur_pos = 0;
+
+ /* Last table, used for insertion */
+ priv->tables_used = 0;
+ priv->table_used = 0;
+ priv->last_table = &priv->table;
+
return ret;
err0:
fclose(f);
@@ -435,3 +706,7 @@ GP_Container *GP_OpenZip(const char *path)
#endif /* HAVE_ZLIB */
+int GP_MatchZip(const char *buf)
+{
+ return !memcmp("PK0304", buf, 4);
+}
http://repo.or.cz/w/gfxprim.git/commit/41bce152b73f2401ac8f5f8505e1be2e4ccb…
commit 41bce152b73f2401ac8f5f8505e1be2e4ccb6ef2
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Thu Jul 18 23:41:51 2013 +0200
demos: spiv: Two fixes.
* Add destroy functions for image list, image loader
and call them on exit.
(this makes memory debugging with valgrind easier)
* Map 0 key to resize by 10 action.
(1-9 was mapped to resize by 1-9 beforehand)
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/spiv/image_list.c b/demos/spiv/image_list.c
index afaff25..cef9c8e 100644
--- a/demos/spiv/image_list.c
+++ b/demos/spiv/image_list.c
@@ -422,6 +422,15 @@ struct image_list *image_list_create(const char *args[])
return self;
}
+void image_list_destroy(struct image_list *self)
+{
+ if (self->in_dir)
+ exit_dir(self);
+
+ free(self->arg_file_counts);
+ free(self);
+}
+
const char *image_list_img_path(struct image_list *self)
{
if (!self->path_loaded)
diff --git a/demos/spiv/image_list.h b/demos/spiv/image_list.h
index 54dbfab..e2263d0 100644
--- a/demos/spiv/image_list.h
+++ b/demos/spiv/image_list.h
@@ -36,6 +36,9 @@ struct image_list;
*/
struct image_list *image_list_create(const char *args[]);
+
+void image_list_destroy(struct image_list *self);
+
/*
* Returns path to the current image.
*/
diff --git a/demos/spiv/image_loader.c b/demos/spiv/image_loader.c
index 1c6321f..7852fc6 100644
--- a/demos/spiv/image_loader.c
+++ b/demos/spiv/image_loader.c
@@ -102,7 +102,7 @@ static void drop_cur_img(void)
/*
* Currently loaded image is too big to be cached -> free it.
*/
- if (!image_cache_get(img_cache, 1, path))
+ if (!image_cache_get(img_cache, 0, path))
GP_ContextFree(cur_img);
cur_img = NULL;
@@ -164,6 +164,10 @@ void image_loader_drop_cache(void)
void image_loader_destroy(void)
{
+ GP_DEBUG(1, "Destroying loader");
+ drop_cur_img();
+ GP_DEBUG(1, "Destroying cache");
image_cache_destroy(img_cache);
- //TODO Image list destroy?
+ GP_DEBUG(1, "Destroying image list");
+ image_list_destroy(img_list);
}
diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c
index c594205..96eda04 100644
--- a/demos/spiv/spiv.c
+++ b/demos/spiv/spiv.c
@@ -623,7 +623,6 @@ static int init_loader(struct loader_params *params, const char **argv)
GP_DEBUG(1, "Resized cache size = %u", resized_size);
- //TODO: cache size init
if (image_loader_init(argv, orig_size))
return 1;
@@ -874,8 +873,9 @@ int main(int argc, char *argv[])
case GP_KEY_ESC:
case GP_KEY_ENTER:
case GP_KEY_Q:
- image_cache_drop(params.img_resized_cache);
- image_loader_drop_cache();
+ stop_loader();
+ image_cache_destroy(params.img_resized_cache);
+ image_loader_destroy();
GP_BackendExit(backend);
return 0;
break;
@@ -940,6 +940,9 @@ int main(int argc, char *argv[])
int val = ev.val.key.key - GP_KEY_1 + 1;
resize_backend(val, shift_flag);
} break;
+ case GP_KEY_0:
+ resize_backend(10, shift_flag);
+ break;
case GP_KEY_KP_PLUS:
case GP_KEY_DOT:
params.show_progress_once = 1;
diff --git a/demos/spiv/spiv_help.c b/demos/spiv/spiv_help.c
index 43cbaa1..9e2d14b 100644
--- a/demos/spiv/spiv_help.c
+++ b/demos/spiv/spiv_help.c
@@ -58,6 +58,7 @@ static const char *keys_help[] = {
"3 - resize spiv window to the third of the image size",
"...",
"9 - resize spiv window to the ninth of the image size",
+ "0 - resize spiv window to the tenth of the image size",
"",
"Shift 2 - resize spiv window twice of the image size",
"Shift 3 - resize spiv window three times of the image size",
http://repo.or.cz/w/gfxprim.git/commit/b6cbcf6d7265335c20d6dc268160aac84d5a…
commit b6cbcf6d7265335c20d6dc268160aac84d5af3aa
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Thu Jul 18 23:35:07 2013 +0200
loaders: TIFF: Mark internal funcitons static.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_TIFF.c b/libs/loaders/GP_TIFF.c
index ac49d06..160a85a 100644
--- a/libs/loaders/GP_TIFF.c
+++ b/libs/loaders/GP_TIFF.c
@@ -275,7 +275,7 @@ static GP_PixelType match_pixel_type(TIFF *tiff, struct tiff_header *header)
}
}
-uint16_t get_idx(uint8_t *row, uint32_t x, uint16_t bps)
+static uint16_t get_idx(uint8_t *row, uint32_t x, uint16_t bps)
{
switch (bps) {
case 1:
@@ -294,8 +294,9 @@ uint16_t get_idx(uint8_t *row, uint32_t x, uint16_t bps)
return 0;
}
-int tiff_read_palette(TIFF *tiff, GP_Context *res, struct tiff_header *header,
- GP_ProgressCallback *callback)
+static int tiff_read_palette(TIFF *tiff, GP_Context *res,
+ struct tiff_header *header,
+ GP_ProgressCallback *callback)
{
if (TIFFIsTiled(tiff)) {
//TODO
@@ -365,8 +366,8 @@ int tiff_read_palette(TIFF *tiff, GP_Context *res, struct tiff_header *header,
/*
* Direct read -> data in image are in right format.
*/
-int tiff_read(TIFF *tiff, GP_Context *res, struct tiff_header *header,
- GP_ProgressCallback *callback)
+static int tiff_read(TIFF *tiff, GP_Context *res, struct tiff_header *header,
+ GP_ProgressCallback *callback)
{
uint32_t i, y;
uint16_t planar_config, samples, s;
-----------------------------------------------------------------------
Summary of changes:
build/syms/Loaders_symbols.txt | 7 +
demos/spiv/image_list.c | 9 +
demos/spiv/image_list.h | 3 +
demos/spiv/image_loader.c | 81 ++++-
demos/spiv/spiv.c | 15 +-
demos/spiv/spiv_help.c | 1 +
include/loaders/GP_Container.h | 41 ++-
include/loaders/GP_ZIP.h | 2 +
.../GP_ZIP.h => libs/loaders/GP_Container.c | 39 ++-
libs/loaders/GP_TIFF.c | 11 +-
libs/loaders/GP_ZIP.c | 369 +++++++++++++++++---
11 files changed, 503 insertions(+), 75 deletions(-)
copy include/loaders/GP_ZIP.h => libs/loaders/GP_Container.c (73%)
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 Jul '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 3a23d37e9e2fc63f02435221e96cef601b5ce2ed (commit)
from 177fb88927406348571117c81c0ae6ceac6b92e3 (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/3a23d37e9e2fc63f02435221e96cef601b5c…
commit 3a23d37e9e2fc63f02435221e96cef601b5ce2ed
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Jul 15 00:46:45 2013 +0200
loaders: JPG: Fix signature matching.
The first marker in JPEG may not be the 0xff 0xc0 so this commit limits
signature lenght to three bytes.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_JPG.c b/libs/loaders/GP_JPG.c
index 0cf10f7..d7d3bf7 100644
--- a/libs/loaders/GP_JPG.c
+++ b/libs/loaders/GP_JPG.c
@@ -45,10 +45,10 @@
/*
* 0xff 0xd8 - start of image
- * 0xff 0xe0 - APP0 JFIF meta data
+ * 0xff 0x.. - start of frame
*/
-#define JPEG_SIGNATURE "xffxd8xffxe0"
-#define JPEG_SIGNATURE_LEN 4
+#define JPEG_SIGNATURE "xffxd8xff"
+#define JPEG_SIGNATURE_LEN 3
int GP_MatchJPG(const void *buf)
{
@@ -380,7 +380,7 @@ int GP_SaveJPG(const GP_Context *src, const char *dst_path,
/* fix the pixels as we want in fact BGR */
for (i = 0; i < src->w; i++) {
- uint8_t *pix = tmp + 3 * i;
+ uint8_t *pix = tmp + 3 * i;
GP_SWAP(pix[0], pix[2]);
}
-----------------------------------------------------------------------
Summary of changes:
libs/loaders/GP_JPG.c | 8 ++++----
1 files changed, 4 insertions(+), 4 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
14 Jul '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 177fb88927406348571117c81c0ae6ceac6b92e3 (commit)
via d2f0c789183f62bc30cd0638c7da9bf5aa52ba44 (commit)
from f13f4d07dae989e9db0a670f5e8bfa7dc78e197d (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/177fb88927406348571117c81c0ae6ceac6b…
commit 177fb88927406348571117c81c0ae6ceac6b92e3
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 13 19:14:05 2013 +0200
spiv: Large scale cleanup.
This is large scale cleanup in spiv which is much needed before the
functional changes.
This also fixes several bugs that were not posible to fix before the
cleanup, namely:
* Image that doesn't fit to the image cache is now freed
(this bug was there since the implementation of the cache)
* Image size in info box is printed correctly even when
image is rotated
+ numerous small fixes
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/spiv/Makefile b/demos/spiv/Makefile
index 10bac03..93750f3 100644
--- a/demos/spiv/Makefile
+++ b/demos/spiv/Makefile
@@ -1,4 +1,5 @@
TOPDIR=../..
+include $(TOPDIR)/pre.mk
CSOURCES=$(shell echo *.c)
@@ -10,8 +11,8 @@ LDLIBS+=$(LDLIBS_LOADERS) $(LDLIBS_BACKENDS)
APPS=spiv
-spiv: cpu_timer.o image_cache.o image_list.o image_actions.o spiv_help.o
+spiv: cpu_timer.o image_cache.o image_list.o image_actions.o spiv_help.o+ image_loader.o
-include $(TOPDIR)/pre.mk
include $(TOPDIR)/app.mk
include $(TOPDIR)/post.mk
diff --git a/demos/spiv/image_cache.c b/demos/spiv/image_cache.c
index 22f3b70..509d507 100644
--- a/demos/spiv/image_cache.c
+++ b/demos/spiv/image_cache.c
@@ -20,6 +20,7 @@
* *
*****************************************************************************/
+#include <stdarg.h>
#include <string.h>
#include <GP.h>
#include "image_cache.h"
@@ -34,8 +35,6 @@ struct image {
unsigned int elevated;
/* this identifies an image */
- long cookie1;
- long cookie2;
char path[];
};
@@ -124,8 +123,7 @@ static void remove_img(struct image_cache *self, struct image *img, size_t size)
static void remove_img_free(struct image_cache *self,
struct image *img, size_t size)
{
- GP_DEBUG(2, "Freeing image '%s:%10li:%10li' size %zu",
- img->path, img->cookie1, img->cookie2, size);
+ GP_DEBUG(2, "Freeing image '%s' size %zu", img->path, size);
remove_img(self, img, size);
GP_ContextFree(img->ctx);
@@ -151,19 +149,18 @@ static void add_img(struct image_cache *self, struct image *img, size_t size)
self->end = img;
}
-GP_Context *image_cache_get(struct image_cache *self, const char *path,
- long cookie1, long cookie2, int elevate)
+GP_Context *image_cache_get(struct image_cache *self, int elevate,
+ const char *key)
{
struct image *i;
if (self == NULL)
return NULL;
- GP_DEBUG(2, "Looking for image '%s:%10li:%10li'", path, cookie1, cookie2);
+ GP_DEBUG(2, "Looking for image '%s'", key);
for (i = self->root; i != NULL; i = i->next)
- if (!strcmp(path, i->path) &&
- i->cookie1 == cookie1 && i->cookie2 == cookie2)
+ if (!strcmp(key, i->path))
break;
if (i == NULL)
@@ -173,8 +170,7 @@ GP_Context *image_cache_get(struct image_cache *self, const char *path,
if (elevate) {
size_t size = image_size(i);
- GP_DEBUG(2, "Refreshing image '%s:%10li:%10li",
- path, cookie1, cookie2);
+ GP_DEBUG(2, "Refreshing image '%s'", key);
remove_img(self, i, size);
add_img(self, i, size);
@@ -185,6 +181,58 @@ GP_Context *image_cache_get(struct image_cache *self, const char *path,
return i->ctx;
}
+GP_Context *image_cache_get2(struct image_cache *self, int elevate,
+ const char *fmt, ...)
+{
+ va_list va;
+ size_t len;
+ char buf[512];
+ char *key = buf;
+ struct image *i;
+
+ if (self == NULL)
+ return NULL;
+
+ va_start(va, fmt);
+ len = vsnprintf(buf, sizeof(buf), fmt, va);
+ va_end(va);
+
+ if (len >= sizeof(buf)) {
+ key = malloc(len + 1);
+ if (!key) {
+ GP_WARN("Malloc failed :(");
+ return NULL;
+ }
+
+ va_start(va, fmt);
+ vsprintf(key, fmt, va);
+ va_end(va);
+ }
+
+ GP_DEBUG(2, "Looking for image '%s'", key);
+
+ for (i = self->root; i != NULL; i = i->next)
+ if (!strcmp(key, i->path))
+ break;
+
+ /* Push the image to the root of the list */
+ if (i && elevate) {
+ size_t size = image_size(i);
+
+ GP_DEBUG(2, "Refreshing image '%s'", key);
+
+ remove_img(self, i, size);
+ add_img(self, i, size);
+
+ i->elevated++;
+ }
+
+ if (len >= sizeof(buf))
+ free(key);
+
+ return i ? i->ctx : NULL;
+}
+
void image_cache_print(struct image_cache *self)
{
struct image *i;
@@ -197,8 +245,8 @@ void image_cache_print(struct image_cache *self)
printf("Image cache size %u used %un", self->max_size, self->cur_size);
for (i = self->root; i != NULL; i = i->next)
- printf(" Image '%s:%10li:%10li' size %10zu elevated %un", i->path,
- i->cookie1, i->cookie2, image_size(i), i->elevated);
+ printf(" size=%10zu elevated=%u key='%s'n",
+ image_size(i), i->elevated, i->path);
}
static int assert_size(struct image_cache *self, size_t size)
@@ -219,15 +267,56 @@ static int assert_size(struct image_cache *self, size_t size)
return 0;
}
-int image_cache_put(struct image_cache *self, GP_Context *ctx, const char *path,
- long cookie1, long cookie2)
+int image_cache_put(struct image_cache *self, GP_Context *ctx,
+ const char *key)
{
size_t size;
if (self == NULL)
return 1;
- size = image_size2(ctx, path);
+ size = image_size2(ctx, key);
+
+ /*
+ * We try to create room for the image. If this fails we add the image
+ * anyway because we need to store it while we are showing it (and it
+ * will be removed from cache by next image for sure).
+ */
+ assert_size(self, size);
+
+ struct image *img = malloc(sizeof(struct image) + strlen(key) + 1);
+
+ if (img == NULL) {
+ GP_WARN("Malloc failed :(");
+ return 1;
+ }
+
+ img->ctx = ctx;
+ img->elevated = 0;
+ strcpy(img->path, key);
+
+ GP_DEBUG(2, "Adding image '%s' size %zu", img->path, size);
+
+ add_img(self, img, size);
+
+ return 0;
+}
+
+int image_cache_put2(struct image_cache *self, GP_Context *ctx,
+ const char *fmt, ...)
+{
+ size_t size, len;
+ va_list va;
+
+ if (self == NULL)
+ return 1;
+
+ va_start(va, fmt);
+ len = vsnprintf(NULL, 0, fmt, va);
+ va_end(va);
+
+ //TODO: FIX THIS
+ size = image_size2(ctx, "") + len + 1;
/*
* We try to create room for the image. If this fails we add the image
@@ -236,7 +325,7 @@ int image_cache_put(struct image_cache *self, GP_Context *ctx, const char *path,
*/
assert_size(self, size);
- struct image *img = malloc(sizeof(struct image) + strlen(path) + 1);
+ struct image *img = malloc(sizeof(struct image) + len + 1);
if (img == NULL) {
GP_WARN("Malloc failed :(");
@@ -244,13 +333,14 @@ int image_cache_put(struct image_cache *self, GP_Context *ctx, const char *path,
}
img->ctx = ctx;
- img->cookie1 = cookie1;
- img->cookie2 = cookie2;
img->elevated = 0;
- strcpy(img->path, path);
- GP_DEBUG(2, "Adding image '%s:%10li:%10li' size %zu",
- img->path, img->cookie1, img->cookie2, size);
+ va_start(va, fmt);
+ vsprintf(img->path, fmt, va);
+ va_end(va);
+
+ GP_DEBUG(2, "Adding image '%s' size %zu",
+ img->path, size);
add_img(self, img, size);
diff --git a/demos/spiv/image_cache.h b/demos/spiv/image_cache.h
index 1c03545..84cec1d 100644
--- a/demos/spiv/image_cache.h
+++ b/demos/spiv/image_cache.h
@@ -47,14 +47,21 @@ struct image_cache *image_cache_create(unsigned int max_size_bytes);
* If elevate set and image is found, the image is elevated to the top so
* it has lesser chance of being freed.
*/
-GP_Context *image_cache_get(struct image_cache *self, const char *path,
- long cookie1, long cookie2, int elevate);
+GP_Context *image_cache_get(struct image_cache *self, int elevate,
+ const char *key);
+GP_Context *image_cache_get2(struct image_cache *self, int elevate,
+ const char *fmt, ...)
+ __attribute__ ((format (printf, 3, 4)));
/*
* Puts an image into a cache.
*/
int image_cache_put(struct image_cache *self, GP_Context *img,
- const char *path, long cookie1, long cookie2);
+ const char *key);
+
+int image_cache_put2(struct image_cache *self, GP_Context *img,
+ const char *fmt, ...)
+ __attribute__ ((format (printf, 3, 4)));
/*
* Drop all image in cache.
diff --git a/demos/spiv/image_loader.c b/demos/spiv/image_loader.c
new file mode 100644
index 0000000..1c6321f
--- /dev/null
+++ b/demos/spiv/image_loader.c
@@ -0,0 +1,169 @@
+/*****************************************************************************
+ * 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 <loaders/GP_Loaders.h>
+
+#include "cpu_timer.h"
+#include "image_cache.h"
+#include "image_list.h"
+#include "image_loader.h"
+
+static struct image_cache *img_cache;
+static struct image_list *img_list;
+static GP_Context *cur_img;
+
+int image_loader_init(const char *args[], unsigned int cache_max_bytes)
+{
+ img_cache = image_cache_create(cache_max_bytes);
+
+ if (!img_cache) {
+ GP_WARN("Failed to initialize image cache (size=%u)",
+ cache_max_bytes);
+ }
+
+ img_list = image_list_create(args);
+
+ if (!img_list) {
+ GP_FATAL("Failed to initialize image list");
+ return 1;
+ }
+
+ return 0;
+}
+
+GP_Context *image_loader_get_image(GP_ProgressCallback *callback, int elevate)
+{
+ struct cpu_timer timer;
+ const char *path;
+ GP_Context *img;
+
+ if (cur_img)
+ return cur_img;
+
+ path = image_list_img_path(img_list);
+
+ cur_img = image_cache_get(img_cache, elevate, path);
+
+ if (cur_img)
+ return cur_img;
+
+ cpu_timer_start(&timer, "Loading");
+
+ img = GP_LoadImage(path, callback);
+
+ if (!img)
+ return NULL;
+
+ image_cache_put(img_cache, img, path);
+
+ cpu_timer_stop(&timer);
+
+ return img;
+}
+
+const char *image_loader_img_path(void)
+{
+ return image_list_img_path(img_list);
+}
+
+const char *image_loader_img_name(void)
+{
+ return image_list_img_path(img_list);
+}
+
+static void drop_cur_img(void)
+{
+ const char *path;
+
+ path = image_list_img_path(img_list);
+
+ /*
+ * Currently loaded image is too big to be cached -> free it.
+ */
+ if (!image_cache_get(img_cache, 1, path))
+ GP_ContextFree(cur_img);
+
+ cur_img = NULL;
+}
+
+void image_loader_seek(enum img_seek_offset offset, int whence)
+{
+ drop_cur_img();
+
+ switch (offset) {
+ case IMG_FIRST:
+ image_list_first(img_list);
+ break;
+ case IMG_LAST:
+ image_list_last(img_list);
+ break;
+ case IMG_CUR:
+ break;
+ case IMG_DIR:
+ image_list_dir_move(img_list, whence);
+ return;
+ }
+
+ if (!whence)
+ return;
+
+ image_list_move(img_list, whence);
+}
+
+unsigned int image_loader_count(void)
+{
+ return image_list_count(img_list);
+}
+
+unsigned int image_loader_pos(void)
+{
+ return image_list_pos(img_list);
+}
+
+int image_loader_is_in_dir(void)
+{
+ return image_list_dir_count(img_list) != 0;
+}
+
+unsigned int image_loader_dir_count(void)
+{
+ return image_list_dir_count(img_list);
+}
+
+unsigned int image_loader_dir_pos(void)
+{
+ return image_list_dir_pos(img_list);
+}
+
+void image_loader_drop_cache(void)
+{
+ image_cache_drop(img_cache);
+}
+
+void image_loader_destroy(void)
+{
+ image_cache_destroy(img_cache);
+ //TODO Image list destroy?
+}
diff --git a/demos/spiv/image_loader.h b/demos/spiv/image_loader.h
new file mode 100644
index 0000000..46b65fa
--- /dev/null
+++ b/demos/spiv/image_loader.h
@@ -0,0 +1,116 @@
+/*****************************************************************************
+ * 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> *
+ * *
+ *****************************************************************************/
+
+ /*
+
+ Image loader.
+
+ This is abstraction on the top of the image list and image cache.
+
+ */
+
+#ifndef __IMAGE_LOADER_H__
+#define __IMAGE_LOADER_H__
+
+#include <core/GP_Context.h>
+#include <core/GP_ProgressCallback.h>
+
+/*
+ * Initialize image loader.
+ */
+int image_loader_init(const char *args[], unsigned int cache_max_bytes);
+
+/*
+ * Fills pointer to current image.
+ *
+ * Returns zero or, in case of failure, errno.
+ *
+ * Note that the callback may not be called when the image is cached.
+ */
+GP_Context *image_loader_get_image(GP_ProgressCallback *callback, int elevate);
+
+/*
+ * Returns path to current image.
+ */
+const char *image_loader_img_path(void);
+
+/*
+ * Returns image name.
+ *
+ * Note that in case of image containers this is different from the image path.
+ */
+const char *image_loader_img_name(void);
+
+
+enum img_seek_offset {
+ IMG_FIRST,
+ IMG_LAST,
+ IMG_CUR,
+ /*
+ * Seeks to the last image in the directory if whence > 0
+ * to the first image in dir otherwise.
+ */
+ IMG_DIR,
+};
+
+/*
+ * Changes position in image list.
+ */
+void image_loader_seek(enum img_seek_offset offset, int whence);
+
+/*
+ * Drops image cache.
+ */
+void image_loader_drop_cache(void);
+
+/*
+ * Free all memory, close all files.
+ */
+void image_loader_destroy(void);
+
+/*
+ * Counts images in the image list.
+ */
+unsigned int image_loader_count(void);
+
+/*
+ * Returns current position.
+ */
+unsigned int image_loader_pos(void);
+
+
+/*
+ * Returns non-zero if we are in diretory.
+ */
+int image_loader_is_in_dir(void);
+
+/*
+ * Counts number of images in current directory.
+ */
+unsigned int image_loader_dir_count(void);
+
+/*
+ * Returns current position in directory.
+ */
+unsigned int image_loader_dir_pos(void);
+
+#endif /* __IMAGE_LOADER_H__ */
diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c
index 245412a..c594205 100644
--- a/demos/spiv/spiv.c
+++ b/demos/spiv/spiv.c
@@ -36,6 +36,7 @@
#include "image_cache.h"
#include "image_list.h"
+#include "image_loader.h"
#include "image_actions.h"
#include "spiv_help.h"
#include "cpu_timer.h"
@@ -75,8 +76,6 @@ enum zoom_type {
};
struct loader_params {
- /* current image path */
- const char *img_path;
/* current resize ratio */
float rat;
@@ -106,10 +105,6 @@ struct loader_params {
/* caches for loaded images */
struct image_cache *img_resized_cache;
- struct image_cache *img_orig_cache;
-
- /* image list structure */
- struct image_list *img_list;
};
static int image_loader_callback(GP_ProgressCallback *self)
@@ -148,17 +143,16 @@ static int image_loader_callback(GP_ProgressCallback *self)
return 0;
}
-static GP_Context *load_image(struct loader_params *params, int elevate);
+static GP_Context *load_image(int elevate);
/*
* Ask backend to resize window may not be implemented or authorized. If
* backend (window) is resized we will get SYS_RESIZE event, see the main event
* loop.
*/
-static void resize_backend(struct loader_params *params,
- float ratio, int shift_flag)
+static void resize_backend(float ratio, int shift_flag)
{
- GP_Context *img = load_image(params, 1);
+ GP_Context *img = load_image(1);
if (!shift_flag)
ratio = 1.00 / ratio;
@@ -188,7 +182,7 @@ static float calc_img_size(struct loader_params *params,
case ZOOM_FIXED:
return params->zoom;
case ZOOM_FIXED_WIN:
- resize_backend(params, params->zoom, 0);
+ resize_backend(params->zoom, 0);
return params->zoom;
}
@@ -219,51 +213,29 @@ static void set_caption(const char *path, float rat)
/*
* Loads image
*/
-static GP_Context *load_image(struct loader_params *params, int elevate)
+static GP_Context *load_image(int elevate)
{
- struct cpu_timer timer;
- GP_Context *img, *context = backend->context;
-
+ GP_Context *img;
GP_ProgressCallback callback = {.callback = image_loader_callback,
.priv = "Loading image"};
- img = image_cache_get(params->img_orig_cache, params->img_path, 0, 0, elevate);
-
- /* Image not cached, load it */
- if (img == NULL) {
- fprintf(stderr, "Loading '%s'n", params->img_path);
+ img = image_loader_get_image(&callback, elevate);
- cpu_timer_start(&timer, "Loading");
- if ((img = GP_LoadImage(params->img_path, &callback)) == NULL) {
-
- if (errno == ECANCELED)
- return NULL;
-
- GP_Fill(context, black_pixel);
- GP_Print(context, NULL, context->w/2, context->h/2 - 10,
- GP_ALIGN_CENTER|GP_VALIGN_CENTER, white_pixel, black_pixel,
- "'%s'", params->img_path);
- GP_Print(context, NULL, context->w/2, context->h/2 + 10,
- GP_ALIGN_CENTER|GP_VALIGN_CENTER, white_pixel, black_pixel,
- "Failed to load image :( (%s)", strerror(errno));
- GP_BackendFlip(backend);
- return NULL;
- }
-
- /* Workaround */
-// if (img->pixel_type != GP_PIXEL_RGB888) {
-// GP_Context *tmp;
-// tmp = GP_ContextConvertAlloc(img, GP_PIXEL_RGB888);
-// GP_ContextFree(img);
-// img = tmp;
-// }
+ if (img)
+ return img;
- image_cache_put(params->img_orig_cache, img, params->img_path, 0, 0);
+ GP_Context *ctx = backend->context;
- cpu_timer_stop(&timer);
- }
+ GP_Fill(ctx, black_pixel);
+ GP_Print(ctx, NULL, ctx->w/2, ctx->h/2 - 10,
+ GP_ALIGN_CENTER|GP_VALIGN_CENTER, white_pixel, black_pixel,
+ "'%s'", image_loader_img_path());
+ GP_Print(ctx, NULL, ctx->w/2, ctx->h/2 + 10,
+ GP_ALIGN_CENTER|GP_VALIGN_CENTER, white_pixel, black_pixel,
+ "Failed to load image :( (%s)", strerror(errno));
+ GP_BackendFlip(backend);
- return img;
+ return NULL;
}
/*
@@ -296,10 +268,8 @@ static void pattern_fill(GP_Context *ctx, unsigned int x0, unsigned int y0,
}
}
-/*
- * Updates display.
- */
-static void update_display(struct loader_params *params, GP_Context *img)
+static void update_display(struct loader_params *params, GP_Context *img,
+ GP_Context *orig_img)
{
GP_Context *context = backend->context;
struct cpu_timer timer;
@@ -359,9 +329,6 @@ static void update_display(struct loader_params *params, GP_Context *img)
cpu_timer_stop(&timer);
- if (params->rotate)
- GP_ContextFree(img);
-
/* clean up the rest of the display */
GP_FillRectXYWH(context, 0, 0, cx, context->h, black_pixel);
GP_FillRectXYWH(context, 0, 0, context->w, cy, black_pixel);
@@ -376,90 +343,91 @@ static void update_display(struct loader_params *params, GP_Context *img)
if (h > 0)
GP_FillRectXYWH(context, 0, img->h + cy, context->w, h, black_pixel);
- set_caption(params->img_path, params->rat);
+ const char *img_path = image_loader_img_path();
- if (!params->show_info) {
- GP_BackendFlip(backend);
- return;
- }
+ set_caption(img_path, params->rat);
+
+ if (!params->show_info)
+ goto out;
GP_Size th = GP_TextHeight(NULL);
GP_Print(context, NULL, 11, 11, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
- black_pixel, white_pixel, "%ux%u", img->w, img->h);
+ black_pixel, white_pixel, "%ux%u (%ux%u) 1:%3.3f",
+ img->w, img->h, orig_img->w, orig_img->h, params->rat);
GP_Print(context, NULL, 10, 10, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
- white_pixel, black_pixel, "%ux%u", img->w, img->h);
+ white_pixel, black_pixel, "%ux%u (%ux%u) 1:%3.3f",
+ img->w, img->h, orig_img->w, orig_img->h, params->rat);
GP_Print(context, NULL, 11, 13 + th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
- black_pixel, white_pixel, "1:%3.3f", params->rat);
+ black_pixel, white_pixel, "%s", img_name(img_path));
GP_Print(context, NULL, 10, 12 + th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
- white_pixel, black_pixel, "1:%3.3f", params->rat);
+ white_pixel, black_pixel, "%s", img_name(img_path));
- GP_Print(context, NULL, 11, 15 + 2 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
- black_pixel, white_pixel, "%s", img_name(params->img_path));
-
- GP_Print(context, NULL, 10, 14 + 2 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
- white_pixel, black_pixel, "%s", img_name(params->img_path));
-
- GP_Print(context, NULL, 11, 17 + 3 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
+ GP_Print(context, NULL, 11, 13 + 2 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
black_pixel, white_pixel, "%s%s",
params->use_low_pass && params->rat < 1 ? "Gaussian LP + " : "",
GP_InterpolationTypeName(params->resampling_method));
- GP_Print(context, NULL, 10, 16 + 3 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
+ GP_Print(context, NULL, 10, 14 + 2 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
white_pixel, black_pixel, "%s%s",
params->use_low_pass && params->rat < 1 ? "Gaussian LP + " : "",
GP_InterpolationTypeName(params->resampling_method));
- unsigned int count = image_list_count(params->img_list);
- unsigned int pos = image_list_pos(params->img_list) + 1;
+ unsigned int count = image_loader_count();
+ unsigned int pos = image_loader_pos() + 1;
- GP_Print(context, NULL, 11, 19 + 4 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
+ GP_Print(context, NULL, 11, 17 + 3 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
black_pixel, white_pixel, "%u of %u", pos, count);
- GP_Print(context, NULL, 10, 18 + 4 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
+ GP_Print(context, NULL, 10, 16 + 3 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
white_pixel, black_pixel, "%u of %u", pos, count);
- unsigned int dir_count = image_list_dir_count(params->img_list);
- unsigned int dir_pos = image_list_dir_pos(params->img_list) + 1;
+ if (!image_loader_is_in_dir())
+ goto out;
- if (dir_count > 1 && dir_count != count) {
- GP_Print(context, NULL, 11, 21 + 5 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
- black_pixel, white_pixel, "%u of %u in directory", dir_pos, dir_count);
+ unsigned int dir_count = image_loader_dir_count();
+ unsigned int dir_pos = image_loader_dir_pos() + 1;
- GP_Print(context, NULL, 10, 20 + 5 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
- white_pixel, black_pixel, "%u of %u in directory", dir_pos, dir_count);
- }
+ GP_Print(context, NULL, 11, 19 + 4 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
+ black_pixel, white_pixel, "%u of %u in directory", dir_pos, dir_count);
+
+ GP_Print(context, NULL, 10, 18 + 4* th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
+ white_pixel, black_pixel, "%u of %u in directory", dir_pos, dir_count);
+out:
+ if (params->rotate)
+ GP_ContextFree(img);
GP_BackendFlip(backend);
}
GP_Context *load_resized_image(struct loader_params *params, GP_Size w, GP_Size h)
{
- long cookie = (w & 0xffff) | (h & 0xffff)<<16;
GP_Context *img, *res = NULL;
struct cpu_timer timer;
GP_ProgressCallback callback = {.callback = image_loader_callback};
- int key = (params->resampling_method<<1) | !!(params->use_low_pass);
+ const char *img_path = image_loader_img_path();
/* Try to get resized cached image */
- img = image_cache_get(params->img_resized_cache, params->img_path, cookie, key, 1);
+ img = image_cache_get2(params->img_resized_cache, 1, "%s %ux%u r%i l%i",
+ img_path, w, h, params->resampling_method,
+ params->use_low_pass);
if (img != NULL)
return img;
/* Otherwise load image and resize it */
- if ((img = load_image(params, 1)) == NULL)
+ if ((img = load_image(1)) == NULL)
return NULL;
if (params->show_nn_first) {
/* Do simple interpolation and blit the result */
GP_Context *nn = GP_FilterResizeNNAlloc(img, w, h, NULL);
if (nn != NULL) {
- update_display(params, nn);
+ update_display(params, nn, img);
GP_ContextFree(nn);
}
}
@@ -509,7 +477,9 @@ GP_Context *load_resized_image(struct loader_params *params, GP_Size w, GP_Size
if (img == NULL)
return NULL;
- image_cache_put(params->img_resized_cache, img, params->img_path, cookie, key);
+ image_cache_put2(params->img_resized_cache, img, "%s %ux%u r%i l%i",
+ img_path, w, h, params->resampling_method,
+ params->use_low_pass);
return img;
}
@@ -518,7 +488,7 @@ static void *image_loader(void *ptr)
{
struct loader_params *params = ptr;
struct cpu_timer sum_timer;
- GP_Context *img, *context = backend->context;
+ GP_Context *img, *orig_img, *context = backend->context;
cpu_timer_start(&sum_timer, "sum");
@@ -542,28 +512,28 @@ static void *image_loader(void *ptr)
break;
}
- if ((img = load_image(params, 0)) == NULL)
+ if ((orig_img = load_image(0)) == NULL)
return NULL;
- params->rat = calc_img_size(params, img->w, img->h, w, h);
+ params->rat = calc_img_size(params, orig_img->w, orig_img->h, w, h);
/* Special case => no need to resize */
- if (params->rat == 1.0)
+ if (params->rat == 1.0) {
+ img = orig_img;
goto update;
+ }
- w = img->w;
- h = img->h;
+ w = orig_img->w * params->rat + 0.5;
+ h = orig_img->h * params->rat + 0.5;
- img = load_resized_image(params, w * params->rat + 0.5, h * params->rat + 0.5);
+ img = load_resized_image(params, w, h);
if (img == NULL)
return NULL;
image_cache_print(params->img_resized_cache);
- image_cache_print(params->img_orig_cache);
-
update:
- update_display(params, img);
+ update_display(params, img, orig_img);
cpu_timer_stop(&sum_timer);
return NULL;
@@ -581,13 +551,10 @@ static void stop_loader(void)
}
}
-static void show_image(struct loader_params *params, const char *path)
+static void show_image(struct loader_params *params)
{
int ret;
- if (path != NULL)
- params->img_path = path;
-
/* stop previous loader thread */
stop_loader();
@@ -600,17 +567,24 @@ static void show_image(struct loader_params *params, const char *path)
}
}
+static void image_seek(struct loader_params *params,
+ enum img_seek_offset offset, int whence)
+{
+ image_loader_seek(offset, whence);
+ show_image(params);
+}
+
static void set_zoom_offset(struct loader_params *params, int dx, int dy)
{
params->zoom_x_offset += dx;
params->zoom_y_offset += dy;
- show_image(params, NULL);
+ show_image(params);
}
static void zoom_mul(struct loader_params *params, float mul)
{
params->zoom *= mul;
- show_image(params, NULL);
+ show_image(params);
}
static void sighandler(int signo)
@@ -633,7 +607,12 @@ static void init_backend(const char *backend_opts)
}
}
-static void init_caches(struct loader_params *params)
+/*
+ * Figure out cache size depending on the size of RAM.
+ *
+ * Initialize cache, image loader.
+ */
+static int init_loader(struct loader_params *params, const char **argv)
{
size_t size = image_cache_get_ram_size();
unsigned int resized_size = (1024 * size)/10;
@@ -642,24 +621,23 @@ static void init_caches(struct loader_params *params)
if (resized_size > 100 * 1024 * 1024)
resized_size = 100 * 1024 * 1024;
- if (orig_size > 40 * 1024 * 1024)
- orig_size = 40 * 1024 * 1024;
+ GP_DEBUG(1, "Resized cache size = %u", resized_size);
- GP_DEBUG(1, "Cache sizes original = %u, resized = %u",
- orig_size, resized_size);
+ //TODO: cache size init
+ if (image_loader_init(argv, orig_size))
+ return 1;
params->img_resized_cache = image_cache_create(resized_size);
- params->img_orig_cache = image_cache_create(orig_size);
-// params->img_resized_cache = NULL;
-// params->img_orig_cache = NULL;
+ return 0;
}
static uint32_t timer_callback(GP_Timer *self)
{
struct loader_params *params = self->priv;
- show_image(params, image_list_move(params->img_list, 1));
+ image_loader_seek(IMG_CUR, 1);
+ show_image(params);
return 0;
}
@@ -674,8 +652,6 @@ int main(int argc, char *argv[])
GP_PixelType emul_type = GP_PIXEL_UNKNOWN;
struct loader_params params = {
- .img_path = NULL,
-
.show_progress = 0,
.show_progress_once = 0,
.show_info = 0,
@@ -684,11 +660,10 @@ int main(int argc, char *argv[])
.rotate = 0,
.resampling_method = GP_INTERP_LINEAR_LF_INT,
- .zoom_type = ZOOM_FIT_DOWNSCALE,
+ .zoom_type = ZOOM_FIT,
.zoom = 1,
.img_resized_cache = NULL,
- .img_orig_cache = NULL,
};
GP_TIMER_DECLARE(timer, 0, 0, "Slideshow", timer_callback, ¶ms);
@@ -771,7 +746,8 @@ int main(int argc, char *argv[])
signal(SIGBUS, sighandler);
signal(SIGABRT, sighandler);
- init_caches(¶ms);
+ if (init_loader(¶ms, (const char **)argv + optind))
+ return 1;
init_backend(backend_opts);
@@ -787,11 +763,8 @@ int main(int argc, char *argv[])
GP_Fill(context, black_pixel);
GP_BackendFlip(backend);
- struct image_list *list = image_list_create((const char**)argv + optind);
- params.img_list = list;
-
params.show_progress_once = 1;
- show_image(¶ms, image_list_img_path(list));
+ show_image(¶ms);
if (sleep_ms) {
timer.period = sleep_ms;
@@ -831,7 +804,7 @@ int main(int argc, char *argv[])
switch (ev.val.key.key) {
case GP_KEY_H:
draw_help(backend);
- show_image(¶ms, NULL);
+ show_image(¶ms);
break;
case GP_KEY_F:
if (GP_BackendIsX11(backend))
@@ -841,7 +814,7 @@ int main(int argc, char *argv[])
params.show_info = !params.show_info;
params.show_progress_once = 1;
- show_image(¶ms, NULL);
+ show_image(¶ms);
break;
case GP_KEY_P:
params.show_progress = !params.show_progress;
@@ -852,7 +825,7 @@ int main(int argc, char *argv[])
params.rotate = 0;
params.show_progress_once = 1;
- show_image(¶ms, NULL);
+ show_image(¶ms);
break;
case GP_KEY_RIGHT_BRACE:
params.resampling_method++;
@@ -869,7 +842,7 @@ int main(int argc, char *argv[])
}
params.show_progress_once = 1;
- show_image(¶ms, image_list_img_path(list));
+ show_image(¶ms);
break;
case GP_KEY_LEFT_BRACE:
if (params.resampling_method == 0)
@@ -886,41 +859,41 @@ int main(int argc, char *argv[])
}
params.show_progress_once = 1;
- show_image(¶ms, image_list_img_path(list));
+ show_image(¶ms);
break;
case GP_KEY_L:
params.use_low_pass = !params.use_low_pass;
params.show_progress_once = 1;
- show_image(¶ms, image_list_img_path(list));
+ show_image(¶ms);
break;
case GP_KEY_D:
image_cache_drop(params.img_resized_cache);
- image_cache_drop(params.img_orig_cache);
+ image_loader_drop_cache();
break;
case GP_KEY_ESC:
case GP_KEY_ENTER:
case GP_KEY_Q:
image_cache_drop(params.img_resized_cache);
- image_cache_drop(params.img_orig_cache);
+ image_loader_drop_cache();
GP_BackendExit(backend);
return 0;
break;
case GP_KEY_PAGE_UP:
params.show_progress_once = 1;
- show_image(¶ms, image_list_dir_move(list, -1));
+ image_seek(¶ms, IMG_DIR, -1);
break;
case GP_KEY_PAGE_DOWN:
params.show_progress_once = 1;
- show_image(¶ms, image_list_dir_move(list, 1));
+ image_seek(¶ms, IMG_DIR, 1);
break;
case GP_KEY_HOME:
params.show_progress_once = 1;
- show_image(¶ms, image_list_first(list));
+ image_seek(¶ms, IMG_FIRST, 0);
break;
case GP_KEY_END:
params.show_progress_once = 1;
- show_image(¶ms, image_list_last(list));
+ image_seek(¶ms, IMG_LAST, 0);
break;
case GP_KEY_RIGHT:
if (shift_flag)
@@ -951,45 +924,22 @@ int main(int argc, char *argv[])
case GP_KEY_SPACE:
params.show_progress_once = 1;
if (shift_flag)
- show_image(¶ms, image_list_move(list, 10));
+ image_seek(¶ms, IMG_CUR, 10);
else
- show_image(¶ms, image_list_move(list, 1));
+ image_seek(¶ms, IMG_CUR, 1);
break;
prev:
case GP_KEY_BACKSPACE:
params.show_progress_once = 1;
if (shift_flag)
- show_image(¶ms, image_list_move(list, -10));
+ image_seek(¶ms, IMG_CUR, -10);
else
- show_image(¶ms, image_list_move(list, -1));
- break;
- case GP_KEY_1:
- resize_backend(¶ms, 1, shift_flag);
- break;
- case GP_KEY_2:
- resize_backend(¶ms, 2, shift_flag);
- break;
- case GP_KEY_3:
- resize_backend(¶ms, 3, shift_flag);
- break;
- case GP_KEY_4:
- resize_backend(¶ms, 4, shift_flag);
- break;
- case GP_KEY_5:
- resize_backend(¶ms, 5, shift_flag);
- break;
- case GP_KEY_6:
- resize_backend(¶ms, 6, shift_flag);
- break;
- case GP_KEY_7:
- resize_backend(¶ms, 7, shift_flag);
- break;
- case GP_KEY_8:
- resize_backend(¶ms, 8, shift_flag);
- break;
- case GP_KEY_9:
- resize_backend(¶ms, 9, shift_flag);
+ image_seek(¶ms, IMG_CUR, -1);
break;
+ case GP_KEY_1 ... GP_KEY_9: {
+ int val = ev.val.key.key - GP_KEY_1 + 1;
+ resize_backend(val, shift_flag);
+ } break;
case GP_KEY_KP_PLUS:
case GP_KEY_DOT:
params.show_progress_once = 1;
@@ -1002,7 +952,7 @@ int main(int argc, char *argv[])
break;
case GP_KEY_F1 ... GP_KEY_F10:
image_action_run(ev.val.key.key - GP_KEY_F1,
- image_list_img_path(list));
+ image_loader_img_path());
break;
}
break;
@@ -1014,7 +964,7 @@ int main(int argc, char *argv[])
GP_BackendResizeAck(backend);
GP_Fill(backend->context, 0);
params.show_progress_once = 1;
- show_image(¶ms, NULL);
+ show_image(¶ms);
break;
case GP_EV_SYS_QUIT:
GP_BackendExit(backend);
http://repo.or.cz/w/gfxprim.git/commit/d2f0c789183f62bc30cd0638c7da9bf5aa52…
commit d2f0c789183f62bc30cd0638c7da9bf5aa52ba44
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 13 18:28:43 2013 +0200
libs: EventQueue: Zero keypress bitflags on init.
Each event carries bitflags of currently pressed keys, these flags are
recorded in bitflag array in the the EventQueue and must be initialized
to zeroes prior the use.
This fixes bug where some of the keys were wrongly reported as pressed
at the start of the application.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/input/GP_EventQueue.c b/libs/input/GP_EventQueue.c
index f13a733..ec13f73 100644
--- a/libs/input/GP_EventQueue.c
+++ b/libs/input/GP_EventQueue.c
@@ -20,6 +20,8 @@
* *
*****************************************************************************/
+#include <string.h>
+
#include "core/GP_Common.h"
#include "core/GP_Debug.h"
@@ -32,6 +34,8 @@ void GP_EventQueueInit(struct GP_EventQueue *self,
self->screen_w = screen_w;
self->screen_h = screen_h;
+ memset(&self->cur_state, 0, sizeof(self->cur_state));
+
self->cur_state.cursor_x = screen_w / 2;
self->cur_state.cursor_y = screen_h / 2;
-----------------------------------------------------------------------
Summary of changes:
demos/spiv/Makefile | 5 +-
demos/spiv/image_cache.c | 134 +++++++++++--
demos/spiv/image_cache.h | 13 +-
demos/spiv/image_loader.c | 169 ++++++++++++++++
demos/spiv/{image_list.h => image_loader.h} | 85 +++++---
demos/spiv/spiv.c | 288 +++++++++++----------------
libs/input/GP_EventQueue.c | 4 +
7 files changed, 473 insertions(+), 225 deletions(-)
create mode 100644 demos/spiv/image_loader.c
copy demos/spiv/{image_list.h => image_loader.h} (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
12 Jul '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 f13f4d07dae989e9db0a670f5e8bfa7dc78e197d (commit)
via 40d6efca4f442ebc55954f7a71d3aa31d32a5c0b (commit)
via ee6a6e989763d44e3561c49b8712a3c712883c5c (commit)
from 0de5472415c0c4e5031b1dfbd0bc3bdb995fb334 (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/f13f4d07dae989e9db0a670f5e8bfa7dc78e…
commit f13f4d07dae989e9db0a670f5e8bfa7dc78e197d
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Jul 12 18:44:05 2013 +0200
spiv: Map the actions better to the F keys.
Now action triggered by F1 has cmdline switch -1 etc. and the -0 is
mapped to action 10 and F10.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/spiv/image_actions.c b/demos/spiv/image_actions.c
index b153af4..afeebe6 100644
--- a/demos/spiv/image_actions.c
+++ b/demos/spiv/image_actions.c
@@ -313,7 +313,7 @@ static int prepare_cmd(unsigned int action, const char *img_path)
int image_action_run(unsigned int action, const char *img_path)
{
if (!actions[action]) {
- fprintf(stderr, "Undefined action %un", action);
+ fprintf(stderr, "Undefined action %un", action+1);
return 1;
}
@@ -323,7 +323,8 @@ int image_action_run(unsigned int action, const char *img_path)
printf("Executing cmd "%s"n", cmd);
if (system(cmd)) {
- fprintf(stderr, "Failed to execute cmd '%s': %s", cmd, strerror(errno));
+ fprintf(stderr, "Failed to execute cmd '%s': %s",
+ cmd, strerror(errno));
return 1;
}
diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c
index bd3194c..245412a 100644
--- a/demos/spiv/spiv.c
+++ b/demos/spiv/spiv.c
@@ -746,8 +746,12 @@ int main(int argc, char *argv[])
break;
}
break;
- case '0' ... '9':
- image_action_set(opt - '0', optarg);
+ case '0':
+ /* -0 is mapped to action 10 */
+ image_action_set(9, optarg);
+ break;
+ case '1' ... '9':
+ image_action_set(opt - '1', optarg);
break;
default:
fprintf(stderr, "Invalid paramter '%c'n", opt);
diff --git a/demos/spiv/spiv_help.c b/demos/spiv/spiv_help.c
index ca00a70..43cbaa1 100644
--- a/demos/spiv/spiv_help.c
+++ b/demos/spiv/spiv_help.c
@@ -51,7 +51,7 @@ static const char *keys_help[] = {
"D - drop image cache",
"H - toggle help",
"",
- "F1-F10 - execute action 0 - 9",
+ "F1-F10 - execute action 1 - 10",
"",
"1 - resize spiv window to the image size",
"2 - resize spiv window to the half of the image size",
@@ -86,10 +86,10 @@ void print_help(void)
printf(" pass -b help for more infon");
puts("n");
printf("Actions:nn");
- printf(" -0 'cmd' sets first actionn");
- printf(" -1 'cmd' sets second actionn");
+ printf(" -1 'cmd' sets first actionn");
printf(" ...n");
- printf(" -9 'cmd' sets tenth actionn");
+ printf(" -9 'cmd' sets ninth actionn");
+ printf(" -0 'cmd' sets tenth actionn");
puts("");
printf(" actions are shell commands with following modifiers:n");
printf(" %%f path to current imagen");
http://repo.or.cz/w/gfxprim.git/commit/40d6efca4f442ebc55954f7a71d3aa31d32a…
commit 40d6efca4f442ebc55954f7a71d3aa31d32a5c0b
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Jul 12 18:32:15 2013 +0200
loaders: pnm: Avoid fgetc() in inner loops.
The fgetc() is guarded by lock to be thread safe which slows things down
more than hundred times.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_PNM.c b/libs/loaders/GP_PNM.c
index 8ce5497..dc29a7c 100644
--- a/libs/loaders/GP_PNM.c
+++ b/libs/loaders/GP_PNM.c
@@ -257,7 +257,7 @@ static int get_ascii_int(FILE *f, int *val)
*val = 0;
for (;;) {
- c = fgetc(f);
+ c = getc_unlocked(f);
switch (c) {
case EOF:
@@ -529,24 +529,17 @@ static int load_ascii_rgb888(FILE *f, GP_Context *ctx, GP_ProgressCallback *cb)
static int load_bin_rgb888(FILE *f, GP_Context *ctx, GP_ProgressCallback *cb)
{
- uint32_t x, y;
- int r, g, b, err;
+ uint32_t y, x;
for (y = 0; y < ctx->h; y++) {
- for (x = 0; x < ctx->w; x++) {
- r = fgetc(f);
- g = fgetc(f);
- b = fgetc(f);
+ uint8_t *addr = GP_PIXEL_ADDR(ctx, 0, y);
- if (r == EOF || g == EOF || b == EOF) {
- err = errno;
- GP_DEBUG(1, "Unexpected end of PBM file");
- return err;
- }
+ if (fread(addr, ctx->w * 3, 1, f) != 1)
+ return errno;
+
+ for (x = 0; x < ctx->w; x++)
+ GP_SWAP(addr[3*x], addr[3*x + 2]);
- GP_PutPixel_Raw_24BPP(ctx, x, y,
- GP_Pixel_CREATE_RGB888(r, g, b));
- }
if (GP_ProgressCallbackReport(cb, y, ctx->h, ctx->w)) {
GP_DEBUG(1, "Operation aborted");
return ECANCELED;
http://repo.or.cz/w/gfxprim.git/commit/ee6a6e989763d44e3561c49b8712a3c71288…
commit ee6a6e989763d44e3561c49b8712a3c712883c5c
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Jul 12 14:55:33 2013 +0200
loaders: PNM: Add support for binary G8.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_PNM.c b/libs/loaders/GP_PNM.c
index a0b5fab..8ce5497 100644
--- a/libs/loaders/GP_PNM.c
+++ b/libs/loaders/GP_PNM.c
@@ -461,6 +461,26 @@ static int load_ascii_g8(FILE *f, GP_Context *ctx, GP_ProgressCallback *cb)
return 0;
}
+static int load_bin_g8(FILE *f, GP_Context *ctx, GP_ProgressCallback *cb)
+{
+ uint32_t y;
+
+ for (y = 0; y < ctx->h; y++) {
+ uint8_t *addr = GP_PIXEL_ADDR(ctx, 0, y);
+
+ if (fread(addr, ctx->w, 1, f) != 1)
+ return errno;
+
+ if (GP_ProgressCallbackReport(cb, y, ctx->h, ctx->w)) {
+ GP_DEBUG(1, "Operation aborted");
+ return ECANCELED;
+ }
+ }
+
+ GP_ProgressCallbackDone(cb);
+ return 0;
+}
+
static int load_ascii_rgb888(FILE *f, GP_Context *ctx, GP_ProgressCallback *cb)
{
uint32_t x, y;
@@ -689,6 +709,43 @@ static GP_Pixel depth_to_pixel(int depth)
}
}
+static int load_ascii_graymap(FILE *f, struct pnm_header *header,
+ GP_Context *ret, GP_ProgressCallback *callback)
+{
+ int err = ENOSYS;
+
+ switch (header->depth) {
+ case 1:
+ err = load_ascii_g1(f, ret, callback);
+ break;
+ case 3:
+ err = load_ascii_g2(f, ret, callback);
+ break;
+ case 15:
+ err = load_ascii_g4(f, ret, callback);
+ break;
+ case 255:
+ err = load_ascii_g8(f, ret, callback);
+ break;
+ }
+
+ return err;
+}
+
+static int load_bin_graymap(FILE *f, struct pnm_header *header,
+ GP_Context *ret, GP_ProgressCallback *callback)
+{
+ int err = ENOSYS;
+
+ switch (header->depth) {
+ case 255:
+ err = load_bin_g8(f, ret, callback);
+ break;
+ }
+
+ return err;
+}
+
static GP_Context *read_graymap(FILE *f, struct pnm_header *header, int flag,
GP_ProgressCallback *callback)
{
@@ -715,24 +772,13 @@ static GP_Context *read_graymap(FILE *f, struct pnm_header *header, int flag,
goto err1;
}
- switch (header->depth) {
- case 1:
- if ((err = load_ascii_g1(f, ret, callback)))
- goto err1;
- break;
- case 3:
- if ((err = load_ascii_g2(f, ret, callback)))
- goto err1;
- break;
- case 15:
- if ((err = load_ascii_g4(f, ret, callback)))
- goto err1;
- break;
- case 255:
- if ((err = load_ascii_g8(f, ret, callback)))
- goto err1;
- break;
- }
+ if (header->magic == '5')
+ err = load_bin_graymap(f, header, ret, callback);
+ else
+ err = load_ascii_graymap(f, header, ret, callback);
+
+ if (err)
+ goto err1;
if (flag)
fclose(f);
-----------------------------------------------------------------------
Summary of changes:
demos/spiv/image_actions.c | 5 +-
demos/spiv/spiv.c | 8 +++-
demos/spiv/spiv_help.c | 8 ++--
libs/loaders/GP_PNM.c | 105 ++++++++++++++++++++++++++++++--------------
4 files changed, 85 insertions(+), 41 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
Re: [Gfxprim] Can't build because XKeysymToString not found in tests and demos dirs
by Milan Vancura 10 Jul '13
by Milan Vancura 10 Jul '13
10 Jul '13
Hi Cyril.
> > I do not understand the code in deep but still feel this patch is
> > questionable. It works but I'd expect a wrapper around XKeysymToString
> > so no direct "-lX11" is needed in tests and demos utilities.
> > Let this be a question for the maintainer :-)
>
> This should be covered by the configure script. If you run configure, it looks
> for X11 devel headers and if found it enables build againts X11 libraries (and
> generally any libraries it should link with).
>
> Now if there are no X11 libs detected the X11 backend should be compiled with
> stubs functions that only prints "X11 not compiled in" and aborts.
>
> So generally whole library could be compiled without X11 (or any other library)
> but some demos may not run (these that opens a window and draws into it).
>
> Check output from 'gfxprim-config --libs-backends' which should print linker
> flags for drawing backends (i.e. X11, SDL, Framebuffer) and is used to fill the
> LDLIBS_LOADERS make variable.
mvancura@prisera:~/gfxprim$ gfxprim-config --libs-backends -lGP_backends -lX11 -lXext
>
> Moreover something seems fishy here as test for loaders are not linked agains
> backends at all. So this rather seems to be bug in the build system or
> something similar.
>
> Could you send a log from verbose build, i.e. output from:
>
> VERBOSE=1 make
>
>
> BTW: This kind of questions would be better discussed on GFXprim mailing list
> (although I would be most likely the only one answering them there).
Moved to the mailing list. Both the patch in question and requested log are
attached.
Details:
git commit 5381c2dcc328739b9d82e462da5e2135a8d23c2a (current HEAD of master)
machine is debian squeeze, libx11-6, libx11-data and libx11-dev installed
With the attached patch, I can build gfxprim succesfully and spiv also works
then.
Milan Vancura
2
3
10 Jul '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 0de5472415c0c4e5031b1dfbd0bc3bdb995fb334 (commit)
from 3062e03a9503f1b624fc80fc91b76b129646cf01 (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/0de5472415c0c4e5031b1dfbd0bc3bdb995f…
commit 0de5472415c0c4e5031b1dfbd0bc3bdb995fb334
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Wed Jul 10 21:02:22 2013 +0200
build: Make distclean remove possible leftovers.
The build system, as it is, removes only files it knows about in make
clean, which can break build when you pull from git and some files were
moved or deleted. Then the object files and dep files for these files
will stay possibly breaking the build.
This commit makes the distclean target remove all files that looks like
they were generated, i.e. *.o *.dep *.gen.h and *.gen.c.
Reported-by: Milan Vancura <milan(a)ucw.cz>
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/Makefile b/Makefile
index a2b327d..33cc33c 100644
--- a/Makefile
+++ b/Makefile
@@ -16,13 +16,14 @@ tests: build
pylib: build
demos: build
+GENFILES=config.h config.gen.mk gfxprim-config
+
distclean:
ifdef VERBOSE
- rm config.h config.gen.mk
- $(MAKE) clean
+ rm $(GENFILES)
else
- @$(MAKE) clean
- @rm config.h config.gen.mk
+ @echo "RM $(GENFILES)"
+ @rm $(GENFILES)
endif
HEADER_LOC=/usr/include/
diff --git a/build/Makefile b/build/Makefile
index d4a8b5d..d21da7a 100644
--- a/build/Makefile
+++ b/build/Makefile
@@ -15,6 +15,8 @@ all: $(STATIC_LIB) $(DYNAMIC_LIB) $(SYMLINKS)
rebuild: all
+distclean: clean
+
clean:
ifdef VERBOSE
rm -rf $(STATIC_LIB) $(DYNAMIC_LIB) $(SYMLINKS)
diff --git a/post.mk b/post.mk
index c217f97..0b9fc90 100644
--- a/post.mk
+++ b/post.mk
@@ -9,21 +9,25 @@ endif
all: $(SUBDIRS)
clean: $(SUBDIRS)
+distclean: $(SUBDIRS)
rebuild: $(SUBDIRS)
install: $(SUBDIRS)
help:
- @echo "*** Available targets ***"
+ @echo "*** Available targets ***"
@echo ""
- @echo "help: prints this help"
+ @echo "help: prints this help"
@echo ""
- @echo "doc: builds (only) the documentation"
+ @echo "doc: builds (only) the documentation"
@echo ""
- @echo "clean: cleans current directory and all subdirectories"
+ @echo "clean: cleans current directory and all subdirectories"
@echo ""
- @echo "all: make current directory and all subdirectories"
+ @echo "distclean: cleans all generated files including possible"
+ @echo " leftovers caused by deleted files"
@echo ""
- @echo "rebuild: does clean and all"
+ @echo "all: make current directory and all subdirectories"
+ @echo ""
+ @echo "rebuild: does clean and all"
@echo ""
@echo "The default silent output could be turned off by defining"
@echo "'VERBOSE' shell variable as 'VERBOSE=1 make'"
@@ -109,6 +113,13 @@ else
endif
ifdef CLEAN
+
+ifeq ($(MAKECMDGOALS),distclean)
+CLEAN+=*.o *.dep *.gen.c *.gen.h
+endif
+
+distclean: clean
+
clean:
ifdef VERBOSE
rm -f $(CLEAN)
-----------------------------------------------------------------------
Summary of changes:
Makefile | 9 +++++----
build/Makefile | 2 ++
post.mk | 23 +++++++++++++++++------
3 files changed, 24 insertions(+), 10 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
10 Jul '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 3062e03a9503f1b624fc80fc91b76b129646cf01 (commit)
via de4f3fac6d2249efeb6023d2f9ce8c6e0cf96b61 (commit)
via 33cedf107e230a76204bee5ea1ee0aab853023fc (commit)
via 86c1e0faccd6228843fa35d6f7f2bf54ab57fa11 (commit)
via 475c56e9cccddae51438fec2b1ddfb546fa8b20a (commit)
from 7fe49055375ddf8ad4216a8abf25146ee49a4859 (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/3062e03a9503f1b624fc80fc91b76b129646…
commit 3062e03a9503f1b624fc80fc91b76b129646cf01
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Wed Jul 10 00:26:41 2013 +0200
spiv: Small cleanup.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c
index 287cc12..bd3194c 100644
--- a/demos/spiv/spiv.c
+++ b/demos/spiv/spiv.c
@@ -33,7 +33,6 @@
#include <pthread.h>
#include <GP.h>
-#include <input/GP_InputDriverLinux.h>
#include "image_cache.h"
#include "image_list.h"
@@ -270,7 +269,8 @@ static GP_Context *load_image(struct loader_params *params, int elevate)
/*
* Fill context with chessboard-like pattern.
*/
-static void pattern_fill(GP_Context *ctx, unsigned int x0, unsigned int y0, unsigned int w, unsigned int h)
+static void pattern_fill(GP_Context *ctx, unsigned int x0, unsigned int y0,
+ unsigned int w, unsigned int h)
{
unsigned int x, y;
@@ -633,7 +633,6 @@ static void init_backend(const char *backend_opts)
}
}
-
static void init_caches(struct loader_params *params)
{
size_t size = image_cache_get_ram_size();
@@ -796,11 +795,9 @@ int main(int argc, char *argv[])
}
for (;;) {
- GP_BackendWait(backend);
-
GP_Event ev;
- while (GP_BackendGetEvent(backend, &ev)) {
+ while (GP_BackendWaitEvent(backend, &ev)) {
shift_flag = GP_EventGetKey(&ev, GP_KEY_LEFT_SHIFT) ||
GP_EventGetKey(&ev, GP_KEY_RIGHT_SHIFT);
@@ -1025,7 +1022,5 @@ int main(int argc, char *argv[])
}
}
- GP_BackendExit(backend);
-
return 0;
}
http://repo.or.cz/w/gfxprim.git/commit/de4f3fac6d2249efeb6023d2f9ce8c6e0cf9…
commit de4f3fac6d2249efeb6023d2f9ce8c6e0cf96b61
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Wed Jul 10 00:25:36 2013 +0200
core: Fix typon in GP_Threads.h
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/include/core/GP_Threads.h b/include/core/GP_Threads.h
index 69da584..204ebe7 100644
--- a/include/core/GP_Threads.h
+++ b/include/core/GP_Threads.h
@@ -76,7 +76,7 @@ struct GP_ProgressCallbackMPPriv {
*
* The intended usage is:
*
- * GP_PROGRESS_CALLBACK(callback_mp, orig_callback);
+ * GP_PROGRESS_CALLBACK_MP(callback_mp, orig_callback);
*
* ...
*
http://repo.or.cz/w/gfxprim.git/commit/33cedf107e230a76204bee5ea1ee0aab8530…
commit 33cedf107e230a76204bee5ea1ee0aab853023fc
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Wed Jul 10 00:21:41 2013 +0200
loaders: Add image containers + ZIP container.
Image container is an abstraction for image formats capable of storing
several images. The container could be opened and image loaded one by
one.
ZIP container is first container implementation, it can load images from
a ZIP file, so far it can only handle JPEGs and deflate compressed ZIPs.
This is also base code for implementing CBZ support for spiv.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/configure b/configure
index 971a960..7a3b93d 100755
--- a/configure
+++ b/configure
@@ -321,7 +321,10 @@ if __name__ == '__main__':
["tiff",
"Tag Image File Format (TIFF) library",
[header_exists, "tiffio.h"], "", "-ltiff", ["loaders"]],
- ["libX11",
+ ["zlib",
+ "Standard (de)compression library",
+ [header_exists, "zlib.h"], "", "-lz", ["loaders"]],
+ ["libX11",
"X11 library",
[header_exists, "X11/Xlib.h"], "", "-lX11", ["backends"]],
["X_SHM",
diff --git a/demos/c_simple/Makefile b/demos/c_simple/Makefile
index e430cc4..3ed296b 100644
--- a/demos/c_simple/Makefile
+++ b/demos/c_simple/Makefile
@@ -18,7 +18,8 @@ APPS=backend_example loaders_example loaders filters_symmetry gfx_koch v4l2_show v4l2_grab convolution weighted_median shapetest koch input_example fileview linetest randomshapetest fonttest loaders_register blittest textaligntest abort sin_AA x11_windows- debug_handler gaussian_noise byte_utils version pretty_print timers
+ debug_handler gaussian_noise byte_utils version pretty_print timers+ zip_container
ifeq ($(HAVE_LIBSDL),yes)
APPS+=SDL_glue
@@ -54,6 +55,7 @@ byte_utils: LDLIBS+=$(LDLIBS_LOADERS)
blittest: LDLIBS+=$(LDLIBS_BACKENDS) $(LDLIBS_LOADERS)
sin_AA: LDLIBS+=$(LDLIBS_BACKENDS)
x11_windows: LDLIBS+=$(LDLIBS_BACKENDS)
+zip_container: LDLIBS+=$(LDLIBS_LOADERS) $(LDLIBS_BACKENDS)
include $(TOPDIR)/app.mk
include $(TOPDIR)/post.mk
diff --git a/demos/c_simple/zip_container.c b/demos/c_simple/zip_container.c
new file mode 100644
index 0000000..6e24108
--- /dev/null
+++ b/demos/c_simple/zip_container.c
@@ -0,0 +1,134 @@
+/*****************************************************************************
+ * 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> *
+ * *
+ *****************************************************************************/
+
+/*
+
+ Simple example that loads and show image from zip container into X11 window.
+
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include <GP.h>
+
+static GP_Backend *backend;
+static GP_Context *image;
+static GP_Container *container;
+
+/*
+ * Try to load next image in container, if image has different size than the
+ * window request resize and blit it at the resize event in the main loop.
+ *
+ * Note that the resize event needs not to be granted so we really should have
+ * plan b (which is omited here for the sake of simplicity).
+ */
+static void load_next(void)
+{
+ GP_ContextFree(image);
+
+ image = GP_ContainerLoadNext(container, NULL);
+
+ if (image == NULL)
+ return;
+
+ if (image->w != backend->context->w ||
+ image->h != backend->context->h) {
+ GP_BackendResize(backend, image->w, image->h);
+ return;
+ }
+
+ GP_Blit(image, 0, 0, image->w, image->h, backend->context, 0, 0);
+ GP_BackendFlip(backend);
+}
+
+int main(int argc, char *argv[])
+{
+
+ if (argc != 2) {
+ fprintf(stderr, "Takes path to zip or cbz as an argumentn");
+ return 1;
+ }
+
+ /* Open zip container */
+ container = GP_OpenZip(argv[1]);
+
+ if (container == NULL) {
+ fprintf(stderr, "Failed to open container: %sn", strerror(errno));
+ return 1;
+ }
+
+ /* Load image */
+ image = GP_ContainerLoadNext(container, NULL);
+
+ if (image == NULL) {
+ fprintf(stderr, "Failed to load image %sn", strerror(errno));
+ return 1;
+ }
+
+ /* Initalize backend */
+ backend = GP_BackendX11Init(NULL, 0, 0, image->w, image->h, argv[1], 0);
+
+ if (backend == NULL) {
+ fprintf(stderr, "Failed to initalize backendn");
+ return 1;
+ }
+
+ /* Blit image into the window and show it */
+ GP_Blit(image, 0, 0, image->w, image->h, backend->context, 0, 0);
+ GP_BackendFlip(backend);
+
+ /* Wait for events */
+ for (;;) {
+ GP_Event ev;
+
+ GP_BackendWaitEvent(backend, &ev);
+
+ switch (ev.type) {
+ case GP_EV_KEY:
+ if (!ev.code == GP_EV_KEY_DOWN)
+ continue;
+
+ switch (ev.val.val) {
+ case GP_KEY_Q:
+ GP_BackendExit(backend);
+ return 0;
+ break;
+ case GP_KEY_SPACE:
+ load_next();
+ break;
+ }
+ break;
+ case GP_EV_SYS:
+ if (ev.code == GP_EV_SYS_RESIZE) {
+ GP_BackendResizeAck(backend);
+ GP_Blit(image, 0, 0, image->w, image->h,
+ backend->context, 0, 0);
+ GP_BackendFlip(backend);
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
diff --git a/include/loaders/GP_Loaders.h b/include/loaders/GP_Container.h
similarity index 55%
copy from include/loaders/GP_Loaders.h
copy to include/loaders/GP_Container.h
index 31066d3..36dafdf 100644
--- a/include/loaders/GP_Loaders.h
+++ b/include/loaders/GP_Container.h
@@ -16,37 +16,72 @@
* 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.
+ Container is an abstraction for file formats that can include several images
+ in one file. For example gif, tiff, apng, cbr, cbz, etc.
*/
-#ifndef LOADERS_GP_LOADERS_H
-#define LOADERS_GP_LOADERS_H
+#ifndef LOADERS_GP_CONTAINER_H
+#define LOADERS_GP_CONTAINER_H
#include "core/GP_Context.h"
#include "core/GP_ProgressCallback.h"
-#include "GP_PNM.h"
-#include "GP_BMP.h"
-#include "GP_PNG.h"
-#include "GP_JPG.h"
-#include "GP_GIF.h"
-#include "GP_TIFF.h"
-#include "GP_PSP.h"
+struct GP_Container;
+
+struct GP_ContainerOps {
+ /*
+ * Loads next image from container, use the inline function defined
+ * bellow.
+ */
+ GP_Context *(*LoadNext)(struct GP_Container *self,
+ GP_ProgressCallback *callback);
+
+ /*
+ * Close callback, use the inline function defined bellow.
+ */
+ void (*Close)(struct GP_Container *self);
+
+ //TODO: Seek
+};
+
+typedef struct GP_Container {
+ /*
+ * Image counter. This is set to number of images, or to -1 if number
+ * of images in container is not known prior to parsing the whole
+ * file.
+ */
+ int img_count;
+ /*
+ * Current image counter, do not change from application.
+ */
+ int cur_img;
+
+ const struct GP_ContainerOps *ops;
+
+ char priv[];
+} GP_Container;
-#include "GP_TmpFile.h"
+#define GP_CONTAINER_PRIV(c) ((void*)(c)->priv)
-#include "GP_MetaData.h"
+/*
+ * Behaves just like GP_LoadImage, but takes pointer to opened container instead.
+ */
+static inline GP_Context *GP_ContainerLoadNext(GP_Container *self,
+ GP_ProgressCallback *callback)
+{
+ return self->ops->LoadNext(self, callback);
+}
-#include "GP_Loader.h"
+static inline void GP_ContainerClose(GP_Container *self)
+{
+ self->ops->Close(self);
+}
-#endif /* LOADERS_GP_LOADERS_H */
+#endif /* LOADERS_GP_CONTAINER_H */
diff --git a/include/loaders/GP_Loaders.h b/include/loaders/GP_Loaders.h
index 31066d3..c9e9c49 100644
--- a/include/loaders/GP_Loaders.h
+++ b/include/loaders/GP_Loaders.h
@@ -35,18 +35,21 @@
#include "core/GP_Context.h"
#include "core/GP_ProgressCallback.h"
-#include "GP_PNM.h"
-#include "GP_BMP.h"
-#include "GP_PNG.h"
-#include "GP_JPG.h"
-#include "GP_GIF.h"
-#include "GP_TIFF.h"
-#include "GP_PSP.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 "GP_TmpFile.h"
+#include "loaders/GP_TmpFile.h"
-#include "GP_MetaData.h"
+#include "loaders/GP_MetaData.h"
-#include "GP_Loader.h"
+#include "loaders/GP_Loader.h"
+
+#include "loaders/GP_Container.h"
+#include "loaders/GP_ZIP.h"
#endif /* LOADERS_GP_LOADERS_H */
diff --git a/include/loaders/GP_Loaders.h b/include/loaders/GP_ZIP.h
similarity index 74%
copy from include/loaders/GP_Loaders.h
copy to include/loaders/GP_ZIP.h
index 31066d3..06031e9 100644
--- a/include/loaders/GP_Loaders.h
+++ b/include/loaders/GP_ZIP.h
@@ -16,37 +16,24 @@
* 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.
+ Zip container, could be used to load images from cbz or from zip files.
*/
-#ifndef LOADERS_GP_LOADERS_H
-#define LOADERS_GP_LOADERS_H
+#ifndef LOADERS_GP_ZIP_H
+#define LOADERS_GP_ZIP_H
#include "core/GP_Context.h"
#include "core/GP_ProgressCallback.h"
-#include "GP_PNM.h"
-#include "GP_BMP.h"
-#include "GP_PNG.h"
-#include "GP_JPG.h"
-#include "GP_GIF.h"
-#include "GP_TIFF.h"
-#include "GP_PSP.h"
-
-#include "GP_TmpFile.h"
-
-#include "GP_MetaData.h"
+#include "loaders/GP_Container.h"
-#include "GP_Loader.h"
+GP_Container *GP_OpenZip(const char *path);
-#endif /* LOADERS_GP_LOADERS_H */
+#endif /* LOADERS_GP_ZIP_H */
diff --git a/libs/loaders/GP_ZIP.c b/libs/loaders/GP_ZIP.c
new file mode 100644
index 0000000..c5ab037
--- /dev/null
+++ b/libs/loaders/GP_ZIP.c
@@ -0,0 +1,437 @@
+/*****************************************************************************
+ * 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 <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include "../../config.h"
+
+#ifdef HAVE_ZLIB
+
+#include <zlib.h>
+
+#endif /* HAVE_ZLIB */
+
+#include "core/GP_Debug.h"
+
+#include "loaders/GP_ByteUtils.h"
+#include "loaders/GP_JPG.h"
+
+#include "loaders/GP_ZIP.h"
+
+#ifdef HAVE_ZLIB
+
+#define GEN_FLAG_ENCRYPTED 0x01
+
+struct zip_local_header {
+ uint16_t ver;
+ uint16_t bit_flags;
+ uint16_t comp_type;
+
+ uint32_t crc;
+ uint32_t comp_size;
+ uint32_t uncomp_size;
+
+ char *file_name;
+};
+
+enum compress_method {
+ COMPRESS_STORED = 0x00, /* no compression at all */
+ COMPRESS_SHRUNK = 0x01,
+ COMPRESS_REDUCE1 = 0x02,
+ COMPRESS_REDUCE2 = 0x03,
+ COMPRESS_REDUCE3 = 0x04,
+ COMPRESS_REDUCE4 = 0x05,
+ COMPRESS_IMPLODE = 0x06,
+ COMPRESS_RESERVED1 = 0x07,
+ COMPRESS_DEFLATE = 0x08,
+ COMPRESS_DEFLATE64 = 0x09,
+ COMPRESS_PKWARE_IMPLODE = 0x0a,
+ COMPRESS_RESERVED2 = 0x0b,
+ COMPRESS_BZIP2 = 0x0c,
+};
+
+const char *compress_method_names[] = {
+ "Stored (no compression)",
+ "Shrunk",
+ "Reduced with factor 1",
+ "Reduced with factor 2",
+ "Reduced with factor 3",
+ "Reduced with factor 4",
+ "Imploded",
+ "Reserved 1",
+ "Deflate",
+ "Deflate64",
+ "PKWARE Implode",
+ "Reserved 2",
+ "BZIP2",
+};
+
+static const char *compress_method_name(enum compress_method comp)
+{
+ if (comp > COMPRESS_BZIP2)
+ return "Unknown";
+
+ return compress_method_names[comp];
+}
+
+static int seek_bytes(FILE *f, uint32_t bytes)
+{
+ if (bytes == 0)
+ return 0;
+
+ GP_DEBUG(4, "Moving forward by %"PRIu32"bytes", bytes);
+
+ if (fseek(f, bytes, SEEK_CUR)) {
+ int err = errno;
+ GP_DEBUG(1, "Failed to seek: %s", strerror(errno));
+ return err;
+ }
+
+ return 0;
+}
+
+static void read_stored(FILE *f, struct zip_local_header *header)
+{
+ /* ignored for now */
+ seek_bytes(f, header->uncomp_size);
+}
+
+#define CHUNK 512
+
+struct deflate_inbuf {
+ struct zip_local_header *zip_header;
+ uint32_t to_read;
+ unsigned char buf[CHUNK];
+ FILE *f;
+};
+
+struct deflate_outbuf {
+ uint32_t crc;
+ uint32_t size;
+ FILE *f;
+};
+
+static unsigned deflate_in(void *in_desc, unsigned char **buf)
+{
+ struct deflate_inbuf *in = in_desc;
+ uint32_t chunk = in->to_read >= CHUNK ? CHUNK : in->to_read;
+
+ if (fread(in->buf, chunk, 1, in->f) != 1)
+ return 0;
+
+ *buf = in->buf;
+ in->to_read -= chunk;
+
+ return chunk;
+}
+
+static int deflate_out(void *out_desc, unsigned char *buf, unsigned len)
+{
+ struct deflate_outbuf *out = out_desc;
+
+ out->crc = crc32(out->crc, buf, len);
+ out->size += len;
+
+ if (fwrite(buf, len, 1, out->f) != 1) {
+ GP_DEBUG(1, "Failed to write temp file");
+ return 1;
+ }
+
+ return 0;
+}
+
+static int read_deflate(FILE *f, struct zip_local_header *header, FILE **res_f)
+{
+ uint8_t *window;
+ int err = 0, ret;
+ FILE *tf;
+
+ tf = tmpfile();
+
+ if (!tf) {
+ err = errno;
+ GP_DEBUG(1, "Failed to create temp file");
+ return err;
+ }
+
+ window = malloc(32 * 1024);
+
+ if (!window) {
+ err = ENOMEM;
+ goto err0;
+ }
+
+ z_stream strm = {
+ .zalloc = Z_NULL,
+ .zfree = Z_NULL,
+ .opaque = Z_NULL,
+ .next_in = Z_NULL,
+ };
+
+ if (inflateBackInit(&strm, 15, window) != Z_OK) {
+ GP_DEBUG(1, "Failed to initialize inflate stream");
+ //TODO: Better errno?
+ err = EIO;
+ goto err1;
+ }
+
+ struct deflate_outbuf outbuf = {
+ .crc = crc32(0, NULL, 0),
+ .size = 0,
+ .f = tf,
+ };
+
+ struct deflate_inbuf inbuf = {
+ .zip_header = header,
+ .f = f,
+ .to_read = header->comp_size,
+ };
+
+ ret = inflateBack(&strm, deflate_in, &inbuf, deflate_out, &outbuf);
+
+ if (ret != Z_STREAM_END) {
+ GP_DEBUG(1, "Failed to inflate stream %i", ret);
+ errno = EINVAL;
+ goto err2;
+ }
+
+ if (outbuf.crc != header->crc) {
+ GP_DEBUG(1, "CRC does not match");
+ err = EIO;
+ goto err2;
+ }
+
+ if (outbuf.size != header->uncomp_size) {
+ GP_DEBUG(1, "Decompressed size does not match");
+ err = EIO;
+ goto err2;
+ }
+
+ rewind(tf);
+ *res_f = tf;
+ return 0;
+err2:
+ inflateBackEnd(&strm);
+err1:
+ free(window);
+err0:
+ fclose(tf);
+ return err;
+}
+
+static int zip_next_file(FILE *f, FILE **res)
+{
+ uint16_t fname_len, extf_len;
+ struct zip_local_header header = {.file_name = NULL};
+ int ret, err = 0;
+
+ ret = GP_FRead(f, "0x50 0x4b 0x03 0x04 L2 L2 L2 I4 L4 L4 L4 L2 L2",
+ &header.ver, &header.bit_flags, &header.comp_type,
+ &header.crc, &header.comp_size, &header.uncomp_size,
+ &fname_len, &extf_len);
+
+ if (ret != 13) {
+ GP_DEBUG(1, "Failed to read header");
+ return EIO;
+ }
+
+ GP_DEBUG(1, "Have ZIP local header version %u.%u compression %s",
+ header.ver/10, header.ver%10,
+ compress_method_name(header.comp_type));
+
+ if (header.bit_flags & GEN_FLAG_ENCRYPTED) {
+ GP_DEBUG(1, "Can't handle encrypted files");
+ return ENOSYS;
+ }
+
+ /*
+ * If input was taken from stdin the fname_len is either set to zero or
+ * to one and filename is set to '-'.
+ */
+ if (fname_len) {
+ header.file_name = malloc(fname_len + 1);
+
+ if (!header.file_name)
+ return ENOMEM;
+
+ header.file_name[fname_len] = '0';
+
+ if (fread(header.file_name, fname_len, 1, f) != 1) {
+ GP_DEBUG(1, "Failed to read filename");
+ err = EIO;
+ goto err0;
+ }
+
+ GP_DEBUG(1, "Filename '%s' compressed size=%"PRIu32
+ " uncompressed size=%"PRIu32,
+ header.file_name, header.comp_size,
+ header.uncomp_size);
+ }
+
+ seek_bytes(f, extf_len);
+
+ switch (header.comp_type) {
+ case COMPRESS_STORED:
+ read_stored(f, &header);
+ break;
+ case COMPRESS_DEFLATE:
+ read_deflate(f, &header, res);
+ break;
+ default:
+ GP_DEBUG(1, "Unimplemented compression %s",
+ compress_method_name(header.comp_type));
+ return ENOSYS;
+ }
+
+ return 0;
+err0:
+ free(header.file_name);
+ return err;
+}
+
+struct zip_priv {
+ FILE *f;
+};
+
+static GP_Context *zip_load_next(GP_Container *self,
+ GP_ProgressCallback *callback)
+{
+ struct zip_priv *priv = GP_CONTAINER_PRIV(self);
+ FILE *res = NULL;
+ GP_Context *ret;
+ int err;
+
+ GP_DEBUG(1, "Trying to load next image from ZIP container");
+
+ do
+ err = zip_next_file(priv->f, &res);
+ while (!err && !res);
+
+ if (err) {
+ errno = err;
+ return NULL;
+ }
+
+ ret = GP_ReadJPG(res, callback);
+ err = errno;
+ fclose(res);
+ errno = err;
+
+ return ret;
+}
+
+static void zip_close(GP_Container *self)
+{
+ struct zip_priv *priv = GP_CONTAINER_PRIV(self);
+
+ GP_DEBUG(1, "Closing ZIP container");
+
+ fclose(priv->f);
+ free(self);
+}
+
+
+static int open_zip(const char *path, FILE **file)
+{
+ FILE *f;
+ int err = 0;
+
+ f = fopen(path, "rb");
+
+ if (f == NULL) {
+ err = errno;
+ GP_DEBUG(1, "Failed to open '%s': %s", path, strerror(errno));
+ if (!err)
+ err = EIO;
+ return err;
+ }
+
+ /* Check zip local file header and seek back */
+ if (GP_FRead(f, "0x50 0x4b 0x03 0x04") != 4) {
+ GP_DEBUG(1, "Invalid zip header");
+ err = EINVAL;
+ goto err0;
+ }
+
+ rewind(f);
+
+ *file = f;
+ return 0;
+err0:
+ fclose(f);
+ return err;
+}
+
+static const struct GP_ContainerOps zip_ops = {
+ .LoadNext = zip_load_next,
+ .Close = zip_close,
+};
+
+GP_Container *GP_OpenZip(const char *path)
+{
+ struct zip_priv *priv;
+ GP_Container *ret;
+ FILE *f;
+ int err;
+
+ if ((err = open_zip(path, &f))) {
+ errno = err;
+ return NULL;
+ }
+
+ ret = malloc(sizeof(GP_Container) + sizeof(struct zip_priv));
+
+ if (!ret) {
+ err = ENOMEM;
+ goto err0;
+ }
+
+ priv = GP_CONTAINER_PRIV(ret);
+
+ priv->f = f;
+
+ ret->img_count = -1;
+ ret->cur_img = 0;
+ ret->ops = &zip_ops;
+
+ return ret;
+err0:
+ fclose(f);
+ errno = err;
+ return NULL;
+}
+
+#else
+
+GP_Container *GP_OpenZip(const char *path)
+{
+ GP_FATAL("zlib support not compiled in");
+ errno = ENOSYS;
+ return NULL;
+}
+
+#endif /* HAVE_ZLIB */
+
http://repo.or.cz/w/gfxprim.git/commit/86c1e0faccd6228843fa35d6f7f2bf54ab57…
commit 86c1e0faccd6228843fa35d6f7f2bf54ab57fa11
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Tue Jul 9 20:03:34 2013 +0200
loaders: ByteUtils: Correct comments in header.
The comments in the header were wrongly defining
the return value as a number of bytes instead of
number of sucesful conversions.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/include/loaders/GP_ByteUtils.h b/include/loaders/GP_ByteUtils.h
index 8a26e9c..8916fd7 100644
--- a/include/loaders/GP_ByteUtils.h
+++ b/include/loaders/GP_ByteUtils.h
@@ -22,7 +22,7 @@
/*
- Utils to read/write bytes in specified endianity.
+ Utils to read/write values with specified endianity.
*/
@@ -58,16 +58,16 @@
*/
/*
- * Printf-like function to read bytes from a file.
+ * Printf-like function to read file headers.
*
- * Returns number of characters read.
+ * Returns number of items successfully matched/converted.
*/
int GP_FRead(FILE *f, const char *fmt, ...);
/*
- * Printf-like function to write bytes to a file.
+ * Printf-like function to write file headers.
*
- * Returns number of characters read.
+ * Returns number of items sucessfully written.
*/
int GP_FWrite(FILE *f, const char *fmt, ...);
http://repo.or.cz/w/gfxprim.git/commit/475c56e9cccddae51438fec2b1ddfb546fa8…
commit 475c56e9cccddae51438fec2b1ddfb546fa8b20a
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Tue Jul 9 18:55:31 2013 +0200
doc: compilation: Add libtiff to additional deps
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/doc/compilation.txt b/doc/compilation.txt
index 1ae82f6..bd8a1b3 100644
--- a/doc/compilation.txt
+++ b/doc/compilation.txt
@@ -18,6 +18,7 @@ Image loaders
* libjpeg
* libpng
* giflib
+* libtiff
Text rendering
^^^^^^^^^^^^^^
@@ -79,7 +80,7 @@ zypper in gcc make python-jinja2
.Install jpeg and png devel libraries
-------------------------------------------------------------------------------
-zypper in libjpeg-devel libpng-devel giflib-devel
+zypper in libjpeg-devel libpng-devel giflib-devel libtiff-devel
-------------------------------------------------------------------------------
.Install FreeType devel library
@@ -100,14 +101,15 @@ zypper in swig python-devel
.All in the one for the lazy
-------------------------------------------------------------------------------
zypper in gcc make python-Jinja2 libjpeg-devel libpng-devel giflib-devel
- freetype-devel libX11-devel libXext-devel swig python-devel
+ libtiff-devel freetype-devel libX11-devel libXext-devel swig
+ python-devel
-------------------------------------------------------------------------------
Debian
~~~~~~
Instruction to install required packages on link:http://www.debian.org[Debian]
-and other debian based distributions.
+and other Debian based distributions.
.Install basic tools
-------------------------------------------------------------------------------
@@ -116,7 +118,7 @@ apt-get install gcc make python-jinja2
.Install jpeg and png devel libraries
-------------------------------------------------------------------------------
-apt-get install libjpeg-dev libpng-dev libgif-dev
+apt-get install libjpeg-dev libpng-dev libgif-dev libtiff-dev
-------------------------------------------------------------------------------
.Install FreeType devel library
@@ -137,5 +139,6 @@ apt-get install swig python-dev
.All in the one for the lazy
-------------------------------------------------------------------------------
apt-get install gcc make python-jinja2 libjpeg-dev libpng-dev libgif-dev
- libfreetype6-dev libx11-dev libxext-dev swig python-dev
+ libtiff-dev libfreetype6-dev libx11-dev libxext-dev swig
+ python-dev
-------------------------------------------------------------------------------
-----------------------------------------------------------------------
Summary of changes:
configure | 5 +-
demos/c_simple/Makefile | 4 +-
demos/c_simple/{showimage.c => zip_container.c} | 76 +++-
demos/spiv/spiv.c | 11 +-
doc/compilation.txt | 13 +-
include/core/GP_Threads.h | 2 +-
include/loaders/GP_ByteUtils.h | 10 +-
include/loaders/{GP_PNM.h => GP_Container.h} | 93 +++--
include/loaders/GP_Loaders.h | 23 +-
include/{filters/GP_Filter.h => loaders/GP_ZIP.h} | 18 +-
libs/loaders/GP_ZIP.c | 437 +++++++++++++++++++++
11 files changed, 598 insertions(+), 94 deletions(-)
copy demos/c_simple/{showimage.c => zip_container.c} (58%)
copy include/loaders/{GP_PNM.h => GP_Container.h} (55%)
copy include/{filters/GP_Filter.h => loaders/GP_ZIP.h} (84%)
create mode 100644 libs/loaders/GP_ZIP.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
01 Jul '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 7fe49055375ddf8ad4216a8abf25146ee49a4859 (commit)
from 5381c2dcc328739b9d82e462da5e2135a8d23c2a (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/7fe49055375ddf8ad4216a8abf25146ee49a…
commit 7fe49055375ddf8ad4216a8abf25146ee49a4859
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Jul 1 23:15:58 2013 +0200
Remove a duplicity in the help message
Signed-off-by: Milan Vancura <milan(a)ucw.cz>
diff --git a/demos/spiv/spiv_help.c b/demos/spiv/spiv_help.c
index 4a80fd2..ca00a70 100644
--- a/demos/spiv/spiv_help.c
+++ b/demos/spiv/spiv_help.c
@@ -54,7 +54,6 @@ static const char *keys_help[] = {
"F1-F10 - execute action 0 - 9",
"",
"1 - resize spiv window to the image size",
- "1 - resize spiv window to the image size",
"2 - resize spiv window to the half of the image size",
"3 - resize spiv window to the third of the image size",
"...",
-----------------------------------------------------------------------
Summary of changes:
demos/spiv/spiv_help.c | 1 -
1 files changed, 0 insertions(+), 1 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