aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorAndrew Hannam <andrewh@inmarket.com.au>2013-04-03 13:51:43 +1000
committerAndrew Hannam <andrewh@inmarket.com.au>2013-04-03 13:51:43 +1000
commit64971549fd63d131f136a16913deaec3bdbcf2f3 (patch)
treecfd2698ff4ce1f207ba8f776d1c8fff73718c71f /include
parentb5dceeead44b0b825ee2ef7d2d7943bec8200e30 (diff)
downloaduGFX-64971549fd63d131f136a16913deaec3bdbcf2f3.tar.gz
uGFX-64971549fd63d131f136a16913deaec3bdbcf2f3.tar.bz2
uGFX-64971549fd63d131f136a16913deaec3bdbcf2f3.zip
New GDISP image handling with demo
Images currently support Native and BMP (except RLE4,8 and 16 bit - due to bugs) Supports reading from Memory, BaseFileStream or real files (only on the Win32 simulator). Move gdisp_pictures demo to better refect its purpose. Bug fixes for BMP RLE4,8 & 16 bit to come very soon GIF support very soon.
Diffstat (limited to 'include')
-rw-r--r--include/gdisp/gdisp.h4
-rw-r--r--include/gdisp/image.h355
-rw-r--r--include/gdisp/options.h49
3 files changed, 408 insertions, 0 deletions
diff --git a/include/gdisp/gdisp.h b/include/gdisp/gdisp.h
index 9e408578..85f9b4ea 100644
--- a/include/gdisp/gdisp.h
+++ b/include/gdisp/gdisp.h
@@ -966,6 +966,10 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
}
#endif
+#if GDISP_NEED_IMAGE || defined(__DOXYGEN__)
+ #include "gdisp/image.h"
+#endif
+
#endif /* GFX_USE_GDISP */
#endif /* _GDISP_H */
diff --git a/include/gdisp/image.h b/include/gdisp/image.h
new file mode 100644
index 00000000..8e71437b
--- /dev/null
+++ b/include/gdisp/image.h
@@ -0,0 +1,355 @@
+/*
+ ChibiOS/GFX - Copyright (C) 2012, 2013
+ Joel Bodenmann aka Tectu <joel@unormal.org>
+
+ This file is part of ChibiOS/GFX.
+
+ ChibiOS/GFX is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/GFX 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file include/gdisp/image.h
+ * @brief GDISP image header file.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_IMAGE_H
+#define _GDISP_IMAGE_H
+#if (GFX_USE_GDISP && GDISP_NEED_IMAGE) || defined(__DOXYGEN__)
+
+/**
+ * @brief The type of image
+ */
+typedef uint16_t gdispImageType;
+ #define GDISP_IMAGE_TYPE_UNKNOWN 0
+ #define GDISP_IMAGE_TYPE_NATIVE 1
+ #define GDISP_IMAGE_TYPE_GIF 2
+ #define GDISP_IMAGE_TYPE_BMP 3
+ #define GDISP_IMAGE_TYPE_JPG 4
+ #define GDISP_IMAGE_TYPE_PNG 5
+
+/**
+ * @brief An image error code
+ */
+typedef uint16_t gdispImageError;
+ #define GDISP_IMAGE_ERR_OK 0
+ #define GDISP_IMAGE_ERR_UNRECOVERABLE 0x8000
+ #define GDISP_IMAGE_ERR_BADFORMAT (GDISP_IMAGE_ERR_UNRECOVERABLE+1)
+ #define GDISP_IMAGE_ERR_BADDATA (GDISP_IMAGE_ERR_UNRECOVERABLE+2)
+ #define GDISP_IMAGE_ERR_UNSUPPORTED (GDISP_IMAGE_ERR_UNRECOVERABLE+3)
+ #define GDISP_IMAGE_ERR_UNSUPPORTED_OK 3
+ #define GDISP_IMAGE_ERR_NOMEMORY (GDISP_IMAGE_ERR_UNRECOVERABLE+4)
+
+/**
+ * @brief Image flags
+ */
+typedef uint16_t gdispImageFlags;
+ #define GDISP_IMAGE_FLG_TRANSPARENT 0x0001 /* The image has transparency */
+ #define GDISP_IMAGE_FLG_ANIMATED 0x0002 /* The image has animation */
+ #define GDISP_IMAGE_FLG_MULTIPAGE 0x0004 /* The image has multiple pages */
+
+struct gdispImageIO;
+
+/**
+ * @brief An image IO close function
+ *
+ * @param[in] pio Pointer to the io structure
+ * @param[in] desc The descriptor. A filename or an image structure pointer.
+ *
+ */
+typedef void (*gdispImageIOCloseFn)(struct gdispImageIO *pio);
+
+/**
+ * @brief An image IO read function
+ * @returns The number of bytes actually read or 0 on error
+ *
+ * @param[in] pio Pointer to the io structure
+ * @param[in] buf Where the results should be placed
+ * @param[in] len The number of bytes to read
+ *
+ */
+typedef size_t (*gdispImageIOReadFn)(struct gdispImageIO *pio, void *buf, size_t len);
+
+/**
+ * @brief An image IO seek function
+ *
+ * @param[in] pio Pointer to the io structure
+ * @param[in] pos Which byte to seek to relative to the start of the "file".
+ *
+ */
+typedef void (*gdispImageIOSeekFn)(struct gdispImageIO *pio, size_t pos);
+
+typedef struct gdispImageIOFunctions {
+ gdispImageIOReadFn read; /* @< The function to read input */
+ gdispImageIOSeekFn seek; /* @< The function to seek input */
+ gdispImageIOCloseFn close; /* @< The function to close input */
+ } gdispImageIOFunctions;
+
+/**
+ * @brief The structure defining the IO routines for image handling
+ */
+typedef struct gdispImageIO {
+ const void * fd; /* @< The "file" descriptor */
+ size_t pos; /* @< The current "file" position */
+ const gdispImageIOFunctions *fns; /* @< The current "file" functions */
+} gdispImageIO;
+
+/**
+ * @brief The structure for an image
+ */
+typedef struct gdispImage {
+ gdispImageType type; /* @< The image type */
+ gdispImageFlags flags; /* @< The image flags */
+ coord_t width, height; /* @< The image dimensions */
+ gdispImageIO io; /* @< The image IO functions */
+ uint32_t membytes; /* @< How much RAM has been allocated */
+ const struct gdispImageHandlers * fns; /* @< Don't mess with this! */
+ struct gdispImagePrivate * priv; /* @< Don't mess with this! */
+} gdispImage;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /**
+ * @brief Sets the io fields in the image structure to routines
+ * that support reading from an image stored in RAM or Flash.
+ *
+ * @return TRUE if the IO open function succeeds
+ *
+ * @param[in] img The image structure
+ * @param[in] memimage A pointer to the image in RAM or Flash
+ *
+ * @note Always returns TRUE for a Memory Reader
+ */
+ bool_t gdispImageSetMemoryReader(gdispImage *img, const char *memimage);
+
+ /**
+ * @brief Sets the io fields in the image structure to routines
+ * that support reading from an image stored on a BaseFileStream (eg SDCard).
+ *
+ * @return TRUE if the IO open function succeeds
+ *
+ * @param[in] img The image structure
+ * @param[in] BaseFileStreamPtr A pointer to the (open) BaseFileStream object.
+ *
+ */
+ bool_t gdispImageSetBaseFileStreamReader(gdispImage *img, void *BaseFileStreamPtr);
+
+ #if defined(WIN32) || defined(__DOXYGEN__)
+ /**
+ * @brief Sets the io fields in the image structure to routines
+ * that support reading from an image stored in Win32 simulators native
+ * file system.
+ * @pre Only available on the Win32 simulator
+ *
+ * @return TRUE if the IO open function succeeds
+ *
+ * @param[in] img The image structure
+ * @param[in] filename The filename to open
+ *
+ */
+ bool_t gdispImageSetSimulFileReader(gdispImage *img, const char *filename);
+ #endif
+
+ /**
+ * @brief Open an image ready for drawing
+ * @details Determine the image format and get ready to decode the first image frame
+ * @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
+ *
+ * @param[in] img The image structure
+ *
+ * @pre The io fields should be filled in before calling gdispImageOpen()
+ *
+ * @note This determines which decoder to use and then initialises all other fields
+ * in the gdispImage structure.
+ * @note There are three types of return - everything OK, partial success and unrecoverable
+ * failures. For everything OK it returns GDISP_IMAGE_ERR_OK. A partial success can
+ * be distinguished from a unrecoverable failure by testing the GDISP_IMAGE_ERR_UNRECOVERABLE
+ * bit in the error code.
+ * A partial success return code means an image can still be drawn but perhaps with
+ * reduced functionality eg only the first page of a multi-page image.
+ * @note @p gdispImageClose() can be called even after a failure to open the image to ensure
+ * that the IO close routine gets called.
+ */
+ gdispImageError gdispImageOpen(gdispImage *img);
+
+ /**
+ * @brief Close an image and release any dynamicly allocated working storage.
+ *
+ * @param[in] img The image structure
+ *
+ * @pre gdispImageOpen() must have returned successfully.
+ *
+ * @note Also calls the IO close function (if it hasn't already been called).
+ */
+ void gdispImageClose(gdispImage *img);
+
+ /**
+ * @brief Cache the image
+ * @details Decodes and caches the current frame into RAM.
+ * @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
+ *
+ * @param[in] img The image structure
+ *
+ * @pre gdispImageOpen() must have returned successfully.
+ *
+ * @note This can use a LOT of RAM!
+ * @note The decoder may choose to ignore the request for caching. If it does so it will
+ * return GDISP_IMAGE_ERR_UNSUPPORTED_OK.
+ * @note A fatal error here does not necessarily mean that drawing the image will fail. For
+ * example, a GDISP_IMAGE_ERR_NOMEMORY error simply means there isn't enough RAM to
+ * cache the image.
+ */
+ gdispImageError gdispImageCache(gdispImage *img);
+
+ /**
+ * @brief Draw the image
+ * @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
+ *
+ * @param[in] img The image structure
+ * @param[in] x,y The screen location to draw the image
+ * @param[in] cx,cy The area on the screen to draw
+ * @param[in] sx,sy The image position to start drawing at
+ *
+ * @pre gdispImageOpen() must have returned successfully.
+ *
+ * @note If sx,sy + cx,cy is outside the image boundaries the area outside the image
+ * is simply not drawn.
+ * @note If @p gdispImageCache() has been called first for this frame, this routine will draw using a
+ * fast blit from the cached frame. If not, it reads the input and decodes it as it
+ * is drawing. This may be significantly slower than if the image has been cached (but
+ * uses a lot less RAM)
+ */
+ gdispImageError gdispImageDraw(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+
+ /**
+ * @brief Prepare for the next frame/page in the image file.
+ * @return A time in milliseconds to keep displaying the current frame before trying to draw
+ * the next frame. Watch out for the special values TIME_IMMEDIATE and TIME_INFINITE.
+ *
+ * @param[in] img The image structure
+ *
+ * @pre gdispImageOpen() must have returned successfully.
+ *
+ * @note It will return TIME_IMMEDIATE if the first frame/page hasn't been drawn or if the next frame
+ * should be drawn immediately.
+ * @note It will return TIME_INFINITE if another image frame doesn't exist or an error has occurred.
+ * @note Images that support multiple pages (eg TIFF files) will return TIME_IMMEDIATE between pages
+ * and then TIME_INFINITE when there are no more pages.
+ * @note An image that displays a looped animation will never return TIME_INFINITE unless it
+ * gets an error.
+ * @note Calling gdispImageDraw() after getting a TIME_INFINITE will go back to drawing the first
+ * frame/page.
+ */
+ systime_t gdispImageNext(gdispImage *img);
+
+ #if GDISP_NEED_IMAGE_NATIVE
+ /**
+ * @brief The image drawing routines for a NATIVE format image.
+ *
+ * @note Only use these functions if you absolutely know the format
+ * of the image you are decoding. Generally you should use the
+ * generic functions and it will auto-detect the format.
+ * @note A NATIVE format image is defined as an 8 byte header described below, immediately
+ * followed by the bitmap data. The bitmap data is stored in the native format for
+ * the display controller. If the pixel format specified in the header does not
+ * match the controller native format then the image is rejected.
+ * @note The 8 byte header:
+ * { 'N', 'I', width.hi, width.lo, height.hi, height.lo, format.hi, format.lo }
+ * The format word = GDISP_PIXELFORMAT
+ * @{
+ */
+ gdispImageError gdispImageOpen_NATIVE(gdispImage *img);
+ void gdispImageClose_NATIVE(gdispImage *img);
+ gdispImageError gdispImageCache_NATIVE(gdispImage *img);
+ gdispImageError gdispImageDraw_NATIVE(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ systime_t gdispImageNext_NATIVE(gdispImage *img);
+ /* @} */
+ #endif
+
+ #if GDISP_NEED_IMAGE_GIF
+ /**
+ * @brief The image drawing routines for a GIF image.
+ * @note Only use these functions if you absolutely know the format
+ * of the image you are decoding. Generally you should use the
+ * generic functions and it will auto-detect the format.
+ * @{
+ */
+ gdispImageError gdispImageOpen_GIF(gdispImage *img);
+ void gdispImageClose_GIF(gdispImage *img);
+ gdispImageError gdispImageCache_GIF(gdispImage *img);
+ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ systime_t gdispImageNext_GIF(gdispImage *img);
+ /* @} */
+ #endif
+
+ #if GDISP_NEED_IMAGE_BMP
+ /**
+ * @brief The image drawing routines for a BMP image.
+ * @note Only use these functions if you absolutely know the format
+ * of the image you are decoding. Generally you should use the
+ * generic functions and it will auto-detect the format.
+ * @{
+ */
+ gdispImageError gdispImageOpen_BMP(gdispImage *img);
+ void gdispImageClose_BMP(gdispImage *img);
+ gdispImageError gdispImageCache_BMP(gdispImage *img);
+ gdispImageError gdispImageDraw_BMP(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ systime_t gdispImageNext_BMP(gdispImage *img);
+ /* @} */
+ #endif
+
+ #if GDISP_NEED_IMAGE_JPG
+ /**
+ * @brief The image drawing routines for a JPG image.
+ * @note Only use these functions if you absolutely know the format
+ * of the image you are decoding. Generally you should use the
+ * generic functions and it will auto-detect the format.
+ * @{
+ */
+ gdispImageError gdispImageOpen_JPG(gdispImage *img);
+ void gdispImageClose_JPG(gdispImage *img);
+ gdispImageError gdispImageCache_JPG(gdispImage *img);
+ gdispImageError gdispImageDraw_JPG(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ systime_t gdispImageNext_JPG(gdispImage *img);
+ /* @} */
+ #endif
+
+ #if GDISP_NEED_IMAGE_PNG
+ /**
+ * @brief The image drawing routines for a PNG image.
+ * @note Only use these functions if you absolutely know the format
+ * of the image you are decoding. Generally you should use the
+ * generic functions and it will auto-detect the format.
+ * @{
+ */
+ gdispImageError gdispImageOpen_PNG(gdispImage *img);
+ void gdispImageClose_PNG(gdispImage *img);
+ gdispImageError gdispImageCache_PNG(gdispImage *img);
+ gdispImageError gdispImageDraw_PNG(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ systime_t gdispImageNext_PNG(gdispImage *img);
+ /* @} */
+ #endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GFX_USE_GDISP && GDISP_NEED_IMAGE */
+#endif /* _GDISP_IMAGE_H */
+/** @} */
+
diff --git a/include/gdisp/options.h b/include/gdisp/options.h
index 78e48a0a..deacc036 100644
--- a/include/gdisp/options.h
+++ b/include/gdisp/options.h
@@ -131,6 +131,13 @@
#define GDISP_NEED_QUERY FALSE
#endif
/**
+ * @brief Is the image interface required.
+ * @details Defaults to FALSE
+ */
+ #ifndef GDISP_NEED_IMAGE
+ #define GDISP_NEED_IMAGE FALSE
+ #endif
+ /**
* @brief Is the messaging api interface required.
* @details Defaults to FALSE
*/
@@ -140,6 +147,48 @@
/**
* @}
*
+ * @name GDISP Image Options
+ * @pre GDISP_NEED_IMAGE must be TRUE
+ * @{
+ */
+ /**
+ * @brief Is native image decoding required.
+ * @details Defaults to FALSE
+ */
+ #ifndef GDISP_NEED_IMAGE_NATIVE
+ #define GDISP_NEED_IMAGE_NATIVE FALSE
+ #endif
+ /**
+ * @brief Is GIF image decoding required.
+ * @details Defaults to FALSE
+ */
+ #ifndef GDISP_NEED_IMAGE_GIF
+ #define GDISP_NEED_IMAGE_GIF FALSE
+ #endif
+ /**
+ * @brief Is BMP image decoding required.
+ * @details Defaults to FALSE
+ */
+ #ifndef GDISP_NEED_IMAGE_BMP
+ #define GDISP_NEED_IMAGE_BMP FALSE
+ #endif
+ /**
+ * @brief Is JPG image decoding required.
+ * @details Defaults to FALSE
+ */
+ #ifndef GDISP_NEED_IMAGE_JPG
+ #define GDISP_NEED_IMAGE_JPG FALSE
+ #endif
+ /**
+ * @brief Is PNG image decoding required.
+ * @details Defaults to FALSE
+ */
+ #ifndef GDISP_NEED_IMAGE_PNG
+ #define GDISP_NEED_IMAGE_PNG FALSE
+ #endif
+/**
+ * @}
+ *
* @name GDISP Multi-Threading Options
* @{
*/