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 fd437dffad5c449ae3dff083562b0db30ea1eb8e (commit) via b455c46c4d84d1ac66113db48722d9247cb2fc34 (commit) via 03e092e8d75543e3446afe498e359bb1e4be6856 (commit) via 03b001ae92a7ad29e60bcaa3ca1bb93e46963048 (commit) from 80d1a231acdf63c758e84a257c20aaffca6550e3 (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/fd437dffad5c449ae3dff083562b0db30ea1e...
commit fd437dffad5c449ae3dff083562b0db30ea1eb8e Author: Cyril Hrubis metan@ucw.cz Date: Sat Nov 10 16:49:36 2012 +0100
doc: Library core functions and macros docs.
diff --git a/doc/Makefile b/doc/Makefile index acdade4..19b89d2 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -1,6 +1,6 @@ SOURCES=general.txt context.txt loaders.txt filters.txt basic_types.txt drawing_api.txt backends.txt gamma.txt grabbers.txt - environment_variables.txt debug.txt + environment_variables.txt debug.txt core.txt
EXAMPLE_SOURCES=$(wildcard example_*.txt)
diff --git a/doc/api_links.txt b/doc/api_links.txt index 2e41996..3aff6f9 100644 --- a/doc/api_links.txt +++ b/doc/api_links.txt @@ -10,6 +10,10 @@ Also available in link:api.html[all in one page form]. Describes how colors and pixels are handled also describes progress callback in great detail. + +. link:core.html[Library Core overview] + + + Describes functions and macros in library core. + + . link:debug.html[Debug Messages] + Interface to debug layer. diff --git a/doc/core.txt b/doc/core.txt new file mode 100644 index 0000000..fdb8056 --- /dev/null +++ b/doc/core.txt @@ -0,0 +1,140 @@ +Library Core +------------ + +The core of the library contains the 'GP_Context' structure which describes +in-memory bitmap (see context) as well as the most basic functionality (i.e. +reading/writing pixels, gamma handling, blits, progress callback, debug +printing...). More complex parts of the core library are discussed in separate +pages. + +Some of the interfaces described here (most notably the allocator) are +semi-internal interfaces and as such the API may change in the future. + +Common Macros and Inline Functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +[source,c] +------------------------------------------------------------------------------- +#include <core/GP_Common.h> +/* or */ +#include <GP.h> + +GP_MIN(a, b); + +GP_MAX(a, b); + +GP_ABS(a); + +GP_SWAP(a, b); + +GP_SIGN(a); + +------------------------------------------------------------------------------- + +These common macros implements basic functions such as minimum, maximum, +absolute value, swap and sign. + +All macros use 'typeof()' in order to evaluate their arguments exactly once. + +[source,c] +------------------------------------------------------------------------------- +#include <core/GP_Clamp.h> + +/* + * Clamps integer value to 8 bit unsigned value. + */ +GP_CLAMP_INT_0_255(val); + +/* + * Clamps integer value. + */ +GP_CLAMP(val, min, max); + +------------------------------------------------------------------------------- + +Value clamping macros. + +NOTE: this header is not included by including the 'GP.h' header. + +Temporary Buffer Allocator +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Temporary buffer allocator is used to allocate temporary buffer needed for +certain operations (mostly used in image filters). + +The intended usage of temporary buffers is: + +* Count sum of the size needed for all buffers +* Allocate temporary buffer of this size +* Partition the buffer into smaller blocks +* Use the blocks as needed +* Once operation is done, free the buffer + +The allocator code greatly simplifies these steps. Moreover it avoids memory +fragmentation by creating small buffers on the process stack (current theshold +is set to 2kB) and by grouping the temporary buffers into one continuous +region. + +NOTE: The allocator itself does not align the resulting blocks. It's your + responsibility to allocate the buffers in a way that the result is + adequately aligned (hint: the start of the block is aligned, so + get blocks that needs to be aligned first). + +[source,c] +------------------------------------------------------------------------------- +#include <core/GP_TempAlloc.h> + +/* + * A macro that creates block allocator. + * + * The name must be unique among variable and functions names. + * + * The bsize is actual size of the block allocated. + */ +GP_TempAllocCreate(name, bsize); + +/* + * A macro that returns pointer to the start of a block of a bsize + * partioned from the block allocator passed as self argument. + */ +GP_TempAllocGet(self, bsize); + +/* + * Free the allocator memory. + */ +GP_TempAllocFree(self); +------------------------------------------------------------------------------- + +Example usage of the allocator: + +[source,c] +------------------------------------------------------------------------------- +#include <core/GP_TempAlloc.h> + +int foo(...) +{ + GP_TempAllocCreate(tmp, 3 * img->width); + + uint8_t *R = GP_TempAllocGet(tmp, img->width); + uint8_t *G = GP_TempAllocGet(tmp, img->width); + uint8_t *B = GP_TempAllocGet(tmp, img->width); + + /* start of the code that uses the buffers */ + + ... + + if (error) { + GP_TempAllocFree(self); + return -1; + } + + ... + + /* end of the code that uses the buffers */ + + GP_TempAllocFree(self); + + return 0; +} +------------------------------------------------------------------------------- +
http://repo.or.cz/w/gfxprim.git/commit/b455c46c4d84d1ac66113db48722d9247cb2f...
commit b455c46c4d84d1ac66113db48722d9247cb2fc34 Author: Cyril Hrubis metan@ucw.cz Date: Sat Nov 10 16:32:43 2012 +0100
doc: Update loaders documentation.
diff --git a/doc/Makefile b/doc/Makefile index bda6964..acdade4 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -2,6 +2,8 @@ SOURCES=general.txt context.txt loaders.txt filters.txt basic_types.txt drawing_api.txt backends.txt gamma.txt grabbers.txt environment_variables.txt debug.txt
+EXAMPLE_SOURCES=$(wildcard example_*.txt) + # # Names of generated images for cleanup # @@ -10,7 +12,7 @@ GENIMAGES=discrete_linear_1D_convolution_alg1 discrete_linear_1D_convolution_alg discrete_linear_convolution_alg2 laplacian_edge_sharpening laplacian_kernel
PAGES=$(subst .txt,.html,$(SOURCES)) - +PAGES+=$(subst .txt,.html,$(EXAMPLE_SOURCES))
all: api.html examples.html $(PAGES) api_links.html
diff --git a/doc/example_loader_registration.txt b/doc/example_loader_registration.txt new file mode 100644 index 0000000..b287560 --- /dev/null +++ b/doc/example_loader_registration.txt @@ -0,0 +1,7 @@ +Image Loader Registration Example +--------------------------------- + +[source,c] +------------------------------------------------------------------ +include::../demos/c_simple/loaders_register.c[] +------------------------------------------------------------------ diff --git a/doc/loaders.txt b/doc/loaders.txt index 99ed35d..e12c6f8 100644 --- a/doc/loaders.txt +++ b/doc/loaders.txt @@ -3,14 +3,25 @@ Context loaders This part of GFXprim library aims to create API to load and save images from/to common image file formats.
+Currently we support JPEG, PNG and some PNM images for loading and saving and +BMP, GIF and PSP for loading. + +Loaders API +~~~~~~~~~~~ + All loading functions returns a pointer to allocated and loaded image or upon -a failure 'NULL' and 'errno' is set. +a failure 'NULL'. + +All saving functions returns zero on success and non-zero on failure. If +image saving is aborted by a callback, the opened file is closed and removed +from a filesystem before the call returns. + +In case of a failure 'errno' is set.
-All saving functions returns zero on success and non-zero on failure and -'errno' is set. If image saving is aborted by a callback, the opened file is -closed and removed from a filesystem before the call returns. +The signature matching functions takes a 32 bytes long buffer and looks for a +valid image signature. If signature is found 1 is returned.
-The possible 'errno' values (for both loading and saving) are: +The possible 'errno' values are:
* anything returned by +open()+, +close()+, +lseek()+, +read()+, +write()+, ... - 'ENOENT' if file doesn't exist @@ -22,8 +33,11 @@ The possible 'errno' values (for both loading and saving) are: * 'EIO' invalid image data (wrong signature, header or image data) * 'ECANCELED' action canceled by returning non-zero from within a callback
-Common Loader -~~~~~~~~~~~~~ +You can get more information about the error condition by turning on GFXprim +debug messages. + +Image Loader +~~~~~~~~~~~~
[source,c] ------------------------------------------------------------------------------- @@ -34,9 +48,21 @@ Common Loader GP_Context *GP_LoadImage(const char *src_path, GP_ProgressCallback *callback); -------------------------------------------------------------------------------
-Loads image from a file. The format is now matched by an image file extension. -Fallback to file signature if file content doesn't match it's extension is on -the TODO. +Loads image from a file. + +The image format is first guessed by the file extension. If loader for the +file extension is found it's called and if it succedes the image data is +returned. + +If extension based guess fails either because the extension wasn't matched or +if the loader for the extension failed; the signature based method is used. +The loader loads several bytes (currently 32) from the file and calls +signature matching functions for each format that implements signature +matching. If image signature is found particular image loader it is called +and the result is returned. + +If file extension disagrees with file signature a warning is printed into the +stdout.
[source,c] ------------------------------------------------------------------------------- @@ -48,16 +74,115 @@ int GP_SaveImage(GP_Context *src, const char *dst_path, GP_ProgressCallback *callback); -------------------------------------------------------------------------------
-Saves a context into a file. The file format is matched accordingly to the -file extension, if extension is invalid or if support for requested image -format wasn't compiled in, non-zero is returned and 'errno' is set to -'ENOSYS'. +Saves a context into a file. + +The file format is matched accordingly to the file extension. If extension is +not found non-zero is returned and 'errno' is set to 'EINVAL'. If extension +was found but support for saving the image format is not implemented 'errno' +is set to 'ENOSYS'. + + +Advanced usage +^^^^^^^^^^^^^^ + +[source,c] +------------------------------------------------------------------------------- +typedef struct GP_Loader { + /* + * Loads an image. + * + * Returns allocated and initialized bitmap on success, NULL on failure + * and errno must be set. + */ + GP_Context *(*Load)(const char *src_path, GP_ProgressCallback *callback); + + /* + * Save an image. + * + * Returns zero on succes, non-zero on failure and errno must be set. + */ + int (*Save)(const GP_Context *src, const char *dst_path, + GP_ProgressCallback *callback); + + /* + * The buffer is filled with 32 bytes from an image start, returns 1 if + * image signature was found zero otherwise. + */ + int (*Match)(const void *buf); + + /* + * Short format name. + */ + const char *fmt_name; + + /* don't touch */ + struct GP_Loader *next; + + /* + * NULL terminated array of file extensions. + */ + const char *extensions[]; +} GP_Loader; + +/* + * List loaders into the stdout. + */ +void GP_ListLoaders(void); + +/* + * Register a loader. + */ +void GP_LoaderRegister(GP_Loader *self); + +/* + * Unregister loader. + */ +void GP_LoaderUnregister(GP_Loader *self); +------------------------------------------------------------------------------- + +The 'GP_Loader' structure describes an image loader. + +The 'Load', 'Save' and 'Match' functions could be 'NULL' if the particular +functionality is not implemented. + +The 'fmt_name' is a short string that describes the format. For example: +'Netbpm portable pixmap'. + +The extensions is 'NULL'-terminated array of strings that holds all possible +extensions that are commonly used for this image format. + +All internal loaders are all described in list of this structures which is +used to implement functions such as 'GP_LoadImage()'. + +You can print currently active loaders via the 'GP_ListLoaders()' register and +unregister your own loaders by 'GP_LoaderRegister()' and +'GP_LoaderUnregister()'. Once image loader is registered the generic loading +functions could use it to load and save images. + +For example usage see image loader registration +link:example_loader_registration.html[example]. + +[source,c] +------------------------------------------------------------------------------- +#include <loaders/GP_Loaders.h> +/* or */ +#include <GP.h> + +const GP_Loader *GP_MatchSignature(const void *buf) +------------------------------------------------------------------------------- + +Returns pointer to image loader accordingly to image signature or 'NULL' if no +suitable loader was found. The buf pointer must point to a buffer at least 32 +bytes long. + +WARNING: If you attempt to modify the content of the strucutre the behavior is + undefined. Most likely the program will crash.
-PNG -~~~ +PNG Loader +~~~~~~~~~~ The 'PNG' image support is implemented by the libpng library.
-WARNING: PNG images with alpha channel are not supported yet. +NOTE: PNG images with alpha channel are not supported yet.
[source,c] ------------------------------------------------------------------------------- @@ -114,8 +239,19 @@ Currently only 'RGB888' format is supported, you should convert the 'GP_Context' to 'RGB888' before calling this function otherwise non-zero is returned and 'errno' is set to 'ENOSYS'.
-JPEG -~~~~ +[source,c] +------------------------------------------------------------------------------- +#include <loaders/GP_PNG.h> +/* or */ +#include <GP.h> + +int GP_MatchPNG(const void *buf); +------------------------------------------------------------------------------- + +Matches a PNG signature. + +JPEG Loader +~~~~~~~~~~~ The 'JPEG' image support is implemented by the jpeg library.
[source,c] @@ -180,8 +316,19 @@ is closed and removed before the call returns non-zero and 'errno' is set to The 'JPG' format could store either 'G8' or 'RGB888' pixeltypes and you must convert the context into one of them before this functions is called.
-GIF -~~~ +[source,c] +------------------------------------------------------------------------------- +#include <loaders/GP_JPG.h> +/* or */ +#include <GP.h> + +int GP_MatchJPG(const void *buf); +------------------------------------------------------------------------------- + +Matches a JPG signature. + +GIF Loader +~~~~~~~~~~
The 'GIF' image support is implemented by the giflib library.
@@ -229,8 +376,19 @@ GP_Context *GP_LoadGIF(const char *src_path, GP_ProgressCallback *callback); Same as above but takes path to the file as a parameter and check for the signature. Basically this combines both of the calls above.
-BMP -~~~ +[source,c] +------------------------------------------------------------------------------- +#include <loaders/GP_GIF.h> +/* or */ +#include <GP.h> + +int GP_MatchGIF(const void *buf); +------------------------------------------------------------------------------- + +Matches a GIF signature. + +BMP Loader +~~~~~~~~~~
The 'BMP' loading support is nearly complete the only missing features should be fancy RGB compressions and RLE support. @@ -280,9 +438,72 @@ GP_Context *GP_LoadBMP(const char *src_path, GP_ProgressCallback *callback); Same as above but takes path to the file as a parameter and check for the signature. Basically this combines both of the calls above.
+ +[source,c] +------------------------------------------------------------------------------- +#include <loaders/GP_BMP.h> +/* or */ +#include <GP.h> + +int GP_MatchBMP(const void *buf); +------------------------------------------------------------------------------- + +Matches a BMP signature. + +PSP Loader +~~~~~~~~~~ + +The 'PSP' loader can load a composite image from a Paint Shop Pro Image Files. + +[source,c] +------------------------------------------------------------------------------- +#include <loaders/GP_PSP.h> +/* or */ +#include <GP.h> + +int GP_OpenPSP(const char *src_path, FILE **f); +------------------------------------------------------------------------------- + +Opens file and checks for 'PSP' signature. Upon successful return (file could +be opened, signature matches) zero is returned. Upon failure non-zero is +returned and 'errno' is set. + +[source,c] +------------------------------------------------------------------------------- +#include <loaders/GP_PSP.h> +/* or */ +#include <GP.h> + +GP_Context *GP_ReadPSP(FILE *f, GP_ProgressCallback *callback); +------------------------------------------------------------------------------- + +Reads 'PSP' image into a context. + +[source,c] +------------------------------------------------------------------------------- +#include <loaders/GP_PSP.h> +/* or */ +#include <GP.h> + +GP_Context *GP_LoadPSP(const char *src_path, GP_ProgressCallback *callback); +------------------------------------------------------------------------------- + +Same as above but takes path to the file as a parameter and check for the +signature. Basically this combines both of the calls above. + +[source,c] +------------------------------------------------------------------------------- +#include <loaders/GP_PSP.h> +/* or */ +#include <GP.h> + +int GP_MatchPSP(const void *buf); +------------------------------------------------------------------------------- + +Matches a PSP signature. + PBM, PGM, PPM ~~~~~~~~~~~~~
There is a code do load and write 'PBM', 'PGM' and 'PPM' images too. However it's not finished and its API is outdated. Use at your own risk. -
http://repo.or.cz/w/gfxprim.git/commit/03e092e8d75543e3446afe498e359bb1e4be6...
commit 03e092e8d75543e3446afe498e359bb1e4be6856 Author: Cyril Hrubis metan@ucw.cz Date: Sat Nov 10 15:07:30 2012 +0100
loaders: Add GP_MatchImage().
diff --git a/include/loaders/GP_Loader.h b/include/loaders/GP_Loader.h index ef7add1..6730613 100644 --- a/include/loaders/GP_Loader.h +++ b/include/loaders/GP_Loader.h @@ -102,6 +102,12 @@ typedef struct GP_Loader { const char *extensions[]; } GP_Loader;
+/* + * Takes pointer to buffer at least 32 bytes long and returns a pointer to + * matched loader or NULL. + */ +const GP_Loader *GP_MatchSignature(const void *buf); + void GP_LoaderRegister(GP_Loader *self);
void GP_LoaderUnregister(GP_Loader *self); diff --git a/libs/loaders/GP_Loader.c b/libs/loaders/GP_Loader.c index b1769be..3d626a6 100644 --- a/libs/loaders/GP_Loader.c +++ b/libs/loaders/GP_Loader.c @@ -199,13 +199,13 @@ static struct GP_Loader *loader_by_filename(const char *path) return loader_by_extension(ext); }
-static struct GP_Loader *loader_by_signature(const char *path) +static const GP_Loader *loader_by_signature(const char *path) { uint8_t buf[32]; FILE *f; int err;
- GP_DEBUG(1, "Trying to match file signature"); + GP_DEBUG(1, "Trying to load a file by signature");
f = fopen(path, "rb");
@@ -224,16 +224,7 @@ static struct GP_Loader *loader_by_signature(const char *path)
fclose(f);
- struct GP_Loader *i; - - for (i = loaders; i != NULL; i = i->next) { - if (i->Match && i->Match(buf)) { - GP_DEBUG(1, "Found loader '%s'", i->fmt_name); - return i; - } - } - - return NULL; + return GP_MatchSignature(buf); }
GP_Context *GP_LoadImage(const char *src_path, GP_ProgressCallback *callback) @@ -253,7 +244,7 @@ GP_Context *GP_LoadImage(const char *src_path, GP_ProgressCallback *callback) } GP_Context *img; - struct GP_Loader *ext_load = NULL, *sig_load; + const GP_Loader *ext_load = NULL, *sig_load;
ext_load = loader_by_filename(src_path);
@@ -431,3 +422,19 @@ int GP_SaveImage(const GP_Context *src, const char *dst_path, errno = ENOSYS; return 1; } + +const GP_Loader *GP_MatchSignature(const void *buf) +{ + struct GP_Loader *i; + + for (i = loaders; i != NULL; i = i->next) { + if (i->Match && i->Match(buf) == 1) { + GP_DEBUG(1, "Found loader '%s'", i->fmt_name); + return i; + } + } + + GP_DEBUG(1, "Loader not found"); + + return NULL; +}
http://repo.or.cz/w/gfxprim.git/commit/03b001ae92a7ad29e60bcaa3ca1bb93e46963...
commit 03b001ae92a7ad29e60bcaa3ca1bb93e46963048 Author: Cyril Hrubis metan@ucw.cz Date: Sat Nov 10 14:39:44 2012 +0100
loaders: Now we aren't fooled by wrong filename extension.
diff --git a/libs/loaders/GP_Loader.c b/libs/loaders/GP_Loader.c index 0ef1024..b1769be 100644 --- a/libs/loaders/GP_Loader.c +++ b/libs/loaders/GP_Loader.c @@ -236,6 +236,48 @@ static struct GP_Loader *loader_by_signature(const char *path) return NULL; }
+GP_Context *GP_LoadImage(const char *src_path, GP_ProgressCallback *callback) +{ + int saved_errno; + + if (access(src_path, R_OK)) { + + saved_errno = errno; + + GP_DEBUG(1, "Failed to access file '%s' : %s", + src_path, strerror(errno)); + + errno = saved_errno; + + return NULL; + } + + GP_Context *img; + struct GP_Loader *ext_load = NULL, *sig_load; + + ext_load = loader_by_filename(src_path); + + if (ext_load != NULL) { + img = ext_load->Load(src_path, callback); + + if (img) + return img; + } + + sig_load = loader_by_signature(src_path); + + if (ext_load && sig_load) { + GP_WARN("File '%s': Extension says %s but signature %s", + src_path, ext_load->fmt_name, sig_load->fmt_name); + } + + if (sig_load) + return sig_load->Load(src_path, callback); + + errno = ENOSYS; + return NULL; +} + enum GP_ImageFmt { GP_FMT_UNKNOWN, GP_FMT_PNG, @@ -341,61 +383,6 @@ enum GP_ImageFmt filename_to_fmt(const char *path) return GP_FMT_UNKNOWN; }
-GP_Context *GP_LoadImage(const char *src_path, GP_ProgressCallback *callback) -{ - int saved_errno; - - if (access(src_path, R_OK)) { - - saved_errno = errno; - - GP_DEBUG(1, "Failed to access file '%s' : %s", - src_path, strerror(errno)); - - errno = saved_errno; - - return NULL; - } - - enum GP_ImageFmt fmt = filename_to_fmt(src_path); - - switch (fmt) { - case GP_FMT_JPG: - return GP_LoadJPG(src_path, callback); - case GP_FMT_PNG: - return GP_LoadPNG(src_path, callback); - case GP_FMT_GIF: - return GP_LoadGIF(src_path, callback); - case GP_FMT_PSP: - return GP_LoadPSP(src_path, callback); - case GP_FMT_BMP: - return GP_LoadBMP(src_path, callback); - case GP_FMT_PBM: - return GP_LoadPBM(src_path, callback); - case GP_FMT_PGM: - return GP_LoadPGM(src_path, callback); - case GP_FMT_PPM: - return GP_LoadPPM(src_path, callback); - case GP_FMT_UNKNOWN: - break; - } - - struct GP_Loader *l; - - l = loader_by_filename(src_path); - - if (l != NULL) - return l->Load(src_path, callback); - - l = loader_by_signature(src_path); - - if (l != NULL) - return l->Load(src_path, callback); - - errno = ENOSYS; - return NULL; -} - int GP_LoadMetaData(const char *src_path, GP_MetaData *data) { int saved_errno;
-----------------------------------------------------------------------
Summary of changes: doc/Makefile | 6 +- doc/api_links.txt | 4 + doc/core.txt | 140 ++++++++++++++++++ doc/example_loader_registration.txt | 7 + doc/loaders.txt | 269 +++++++++++++++++++++++++++++++--- include/loaders/GP_Loader.h | 6 + libs/loaders/GP_Loader.c | 120 ++++++++-------- 7 files changed, 463 insertions(+), 89 deletions(-) create mode 100644 doc/core.txt create mode 100644 doc/example_loader_registration.txt
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos@gmail.com if you want to unsubscribe, or site admin admin@repo.or.cz if you receive no reply.