version 2.8
gdisp_image.h
Go to the documentation of this file.
1 /*
2  * This file is subject to the terms of the GFX License. If a copy of
3  * the license was not distributed with this file, you can obtain one at:
4  *
5  * http://ugfx.org/license.html
6  */
7 
8 /**
9  * @file src/gdisp/gdisp_image.h
10  *
11  * @defgroup Image Image
12  * @ingroup GDISP
13  *
14  * @brief Sub-Module for image handling.
15  *
16  * @{
17  */
18 
19 #ifndef _GDISP_IMAGE_H
20 #define _GDISP_IMAGE_H
21 #if (GFX_USE_GDISP && GDISP_NEED_IMAGE) || defined(__DOXYGEN__)
22 
23 /**
24  * @brief The type of image
25  */
26 typedef uint16_t gdispImageType;
27  #define GDISP_IMAGE_TYPE_UNKNOWN 0
28  #define GDISP_IMAGE_TYPE_NATIVE 1
29  #define GDISP_IMAGE_TYPE_GIF 2
30  #define GDISP_IMAGE_TYPE_BMP 3
31  #define GDISP_IMAGE_TYPE_JPG 4
32  #define GDISP_IMAGE_TYPE_PNG 5
33 
34 /**
35  * @brief An image error code
36  */
37 typedef uint16_t gdispImageError;
38  #define GDISP_IMAGE_ERR_OK 0
39  #define GDISP_IMAGE_ERR_UNRECOVERABLE 0x8000
40  #define GDISP_IMAGE_ERR_BADFORMAT (GDISP_IMAGE_ERR_UNRECOVERABLE+1)
41  #define GDISP_IMAGE_ERR_BADDATA (GDISP_IMAGE_ERR_UNRECOVERABLE+2)
42  #define GDISP_IMAGE_ERR_UNSUPPORTED (GDISP_IMAGE_ERR_UNRECOVERABLE+3)
43  #define GDISP_IMAGE_ERR_UNSUPPORTED_OK 3
44  #define GDISP_IMAGE_ERR_NOMEMORY (GDISP_IMAGE_ERR_UNRECOVERABLE+4)
45  #define GDISP_IMAGE_ERR_NOSUCHFILE (GDISP_IMAGE_ERR_UNRECOVERABLE+5)
46  #define GDISP_IMAGE_ERR_NULLPOINTER (GDISP_IMAGE_ERR_UNRECOVERABLE+6)
47 
48 /**
49  * @brief Image flags
50  */
51 typedef uint16_t gdispImageFlags;
52  #define GDISP_IMAGE_FLG_TRANSPARENT 0x0001 /* The image has transparency */
53  #define GDISP_IMAGE_FLG_ANIMATED 0x0002 /* The image has animation */
54  #define GDISP_IMAGE_FLG_MULTIPAGE 0x0004 /* The image has multiple pages */
55 
56 /**
57  * @brief The structure for an image
58  */
59 typedef struct gdispImage {
60  gdispImageType type; /* @< The image type */
61  gdispImageFlags flags; /* @< The image flags */
62  color_t bgcolor; /* @< The default background color */
63  coord_t width, height; /* @< The image dimensions */
64  GFILE * f; /* @< The underlying GFILE */
65  #if GDISP_NEED_IMAGE_ACCOUNTING
66  uint32_t memused; /* @< How much RAM is currently allocated */
67  uint32_t maxmemused; /* @< How much RAM has been allocated (maximum) */
68  #endif
69  const struct gdispImageHandlers * fns; /* @< Don't mess with this! */
70  void * priv; /* @< Don't mess with this! */
71 } gdispImage;
72 
73 #ifdef __cplusplus
74 extern "C" {
75 #endif
76 
77  /**
78  * @brief Initialise a gdispImage object
79  *
80  * @param[in] img The image structure to initialise
81  *
82  */
83  void gdispImageInit(gdispImage *img);
84 
85  /**
86  * @brief Open an image using an open GFILE and get it ready for drawing
87  * @details Determine the image format and get ready to decode the first image frame
88  * @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
89  *
90  * @param[in] img The image structure
91  * @param[in] f The open GFILE stream.
92  *
93  * @pre The GFILE must be open for reading.
94  *
95  * @note This determines which decoder to use and then initialises all other fields
96  * in the gdispImage structure.
97  * @note The image background color is set to White.
98  * @note There are three types of return - everything OK, partial success and unrecoverable
99  * failures. For everything OK it returns GDISP_IMAGE_ERR_OK. A partial success can
100  * be distinguished from a unrecoverable failure by testing the GDISP_IMAGE_ERR_UNRECOVERABLE
101  * bit in the error code.
102  * A partial success return code means an image can still be drawn but perhaps with
103  * reduced functionality eg only the first page of a multi-page image.
104  * @note @p gdispImageClose() should be called when finished with the image. This will close
105  * the image and its underlying GFILE file. Note that images opened with partial success
106  * (eg GDISP_IMAGE_ERR_UNSUPPORTED_OK)
107  * still need to be closed when you are finished with them.
108  */
110 
111  /**
112  * @brief Open an image in a file and get it ready for drawing
113  * @details Determine the image format and get ready to decode the first image frame
114  * @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
115  *
116  * @pre You must have included the file-system support into GFILE that you want to use.
117  *
118  * @param[in] img The image structure
119  * @param[in] filename The filename to open
120  *
121  * @note This function just opens the GFILE using the filename and passes it to @p gdispImageOpenGFile().
122  */
123  #define gdispImageOpenFile(img, filename) gdispImageOpenGFile((img), gfileOpen((filename), "rb"))
124 
125  /**
126  * @brief Open an image in a ChibiOS basefilestream and get it ready for drawing
127  * @details Determine the image format and get ready to decode the first image frame
128  * @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
129  *
130  * @pre GFILE_NEED_CHIBIOSFS and GFX_USE_OS_CHIBIOS must be TRUE. This only makes sense on the ChibiOS
131  * operating system.
132  *
133  * @param[in] img The image structure
134  * @param[in] BaseFileStreamPtr A pointer to an open BaseFileStream
135  *
136  * @note This function just opens the GFILE using the basefilestream and passes it to @p gdispImageOpenGFile().
137  */
138  #define gdispImageOpenBaseFileStream(img, BaseFileStreamPtr) gdispImageOpenGFile((img), gfileOpenBaseFileStream((BaseFileStreamPtr), "rb"))
139 
140  /**
141  * @brief Open an image in memory and get it ready for drawing
142  * @details Determine the image format and get ready to decode the first image frame
143  * @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
144  *
145  * @pre GFILE_NEED_MEMFS must be TRUE
146  *
147  * @param[in] img The image structure
148  * @param[in] ptr A pointer to the image bytes in memory
149  *
150  * @note This function just opens the GFILE using the basefilestream and passes it to @p gdispImageOpenGFile().
151  */
152  #define gdispImageOpenMemory(img, ptr) gdispImageOpenGFile((img), gfileOpenMemory((void *)(ptr), "rb"))
153 
154  /**
155  * @brief Close an image and release any dynamically allocated working storage.
156  *
157  * @param[in] img The image structure
158  *
159  * @pre gdispImageOpenFile() must have returned successfully.
160  *
161  * @note Also calls the IO close function (if it hasn't already been called).
162  */
163  void gdispImageClose(gdispImage *img);
164 
165  /**
166  * @brief Is an image open.
167  * @return TRUE if the image is currently open.
168  *
169  * @param[in] img The image structure
170  *
171  * @note Be careful with calling this on an uninitialized image structure as the image
172  * will contain random data which may be interpreted as meaning the image
173  * is open. Clearing the Image structure to 0's will guarantee the image
174  * is seen as being closed.
175  */
176  bool_t gdispImageIsOpen(gdispImage *img);
177 
178  /**
179  * @brief Set the background color of the image.
180  *
181  * @param[in] img The image structure
182  * @param[in] bgcolor The background color to use
183  *
184  * @pre gdispImageOpen() must have returned successfully.
185  *
186  * @note This color is only used when an image has to restore part of the background before
187  * continuing with drawing that includes transparency eg some GIF animations.
188  */
189  void gdispImageSetBgColor(gdispImage *img, color_t bgcolor);
190 
191  /**
192  * @brief Cache the image
193  * @details Decodes and caches the current frame into RAM.
194  * @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
195  *
196  * @param[in] img The image structure
197  *
198  * @pre gdispImageOpen() must have returned successfully.
199  *
200  * @note This can use a LOT of RAM!
201  * @note The decoder may choose to ignore the request for caching. If it does so it will
202  * return GDISP_IMAGE_ERR_UNSUPPORTED_OK.
203  * @note A fatal error here does not necessarily mean that drawing the image will fail. For
204  * example, a GDISP_IMAGE_ERR_NOMEMORY error simply means there isn't enough RAM to
205  * cache the image.
206  */
208 
209  /**
210  * @brief Draw the image
211  * @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
212  *
213  * @param[in] g The display to draw on
214  * @param[in] img The image structure
215  * @param[in] x,y The screen location to draw the image
216  * @param[in] cx,cy The area on the screen to draw
217  * @param[in] sx,sy The image position to start drawing at
218  *
219  * @pre gdispImageOpen() must have returned successfully.
220  *
221  * @note If sx,sy + cx,cy is outside the image boundaries the area outside the image
222  * is simply not drawn.
223  * @note If @p gdispImageCache() has been called first for this frame, this routine will draw using a
224  * fast blit from the cached frame. If not, it reads the input and decodes it as it
225  * is drawing. This may be significantly slower than if the image has been cached (but
226  * uses a lot less RAM)
227  */
228  gdispImageError gdispGImageDraw(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
229  #define gdispImageDraw(img,x,y,cx,cy,sx,sy) gdispGImageDraw(GDISP,img,x,y,cx,cy,sx,sy)
230 
231  /**
232  * @brief Prepare for the next frame/page in the image file.
233  * @return A time in milliseconds to keep displaying the current frame before trying to draw
234  * the next frame. Watch out for the special values TIME_IMMEDIATE and TIME_INFINITE.
235  *
236  * @param[in] img The image structure
237  *
238  * @pre gdispImageOpen() must have returned successfully.
239  *
240  * @note It will return TIME_IMMEDIATE if the first frame/page hasn't been drawn or if the next frame
241  * should be drawn immediately.
242  * @note It will return TIME_INFINITE if another image frame doesn't exist or an error has occurred.
243  * @note Images that support multiple pages (eg TIFF files) will return TIME_IMMEDIATE between pages
244  * and then TIME_INFINITE when there are no more pages.
245  * @note An image that displays a looped animation will never return TIME_INFINITE unless it
246  * gets an error.
247  * @note Calling gdispImageDraw() after getting a TIME_INFINITE will go back to drawing the first
248  * frame/page.
249  */
250  delaytime_t gdispImageNext(gdispImage *img);
251 
252  /**
253  * @brief Get the number of entries in the color palette.
254  * @return The number of entries in the color palette or 0 if the image doesn't use a color palette.
255  *
256  * @param[in] img The image structure
257  *
258  * @pre gdispImageOpen() must have returned successfully.
259  */
260  uint16_t gdispImageGetPaletteSize(gdispImage *img);
261 
262  /**
263  * @brief Get an entry in the color palette.
264  * @return The color value at a given position in the color palette.
265  *
266  * @param[in] img The image structure
267  * @param[in] index The index of the color palette entry
268  *
269  * @pre gdispImageOpen() must have returned successfully.
270  *
271  * @note This function will return 0 if the index is out of bounds or if the image doesn't use a color palette.
272  */
273  color_t gdispImageGetPalette(gdispImage *img, uint16_t index);
274 
275  /**
276  * @brief Modify an entry in the color palette.
277  * @return @p TRUE on success, @p FALSE otherwise.
278  *
279  * @param[in] img The image structure
280  * @param[in] index The index of the color palette entry
281  * @param[in] newColor The new color value of the specified entry
282  *
283  * @pre gdispImageOpen() must have returned successfully.
284  * @note This function will return @p FALSE if the index is out of bounds or if the image doesn't use a color palette.
285  */
286  bool_t gdispImageAdjustPalette(gdispImage *img, uint16_t index, color_t newColor);
287 
288 #ifdef __cplusplus
289 }
290 #endif
291 
292 #endif /* GFX_USE_GDISP && GDISP_NEED_IMAGE */
293 #endif /* _GDISP_IMAGE_H */
294 /** @} */
295 
delaytime_t gdispImageNext(gdispImage *img)
Prepare for the next frame/page in the image file.
uint16_t gdispImageGetPaletteSize(gdispImage *img)
Get the number of entries in the color palette.
bool_t gdispImageIsOpen(gdispImage *img)
Is an image open.
int16_t coord_t
The type for a coordinate or length on the screen.
Definition: gdisp.h:39
void gdispImageClose(gdispImage *img)
Close an image and release any dynamically allocated working storage.
struct GFILE GFILE
A file pointer.
Definition: gfile.h:34
gdispImageError gdispImageCache(gdispImage *img)
Cache the image.
struct gdispImage gdispImage
The structure for an image.
void gdispImageSetBgColor(gdispImage *img, color_t bgcolor)
Set the background color of the image.
uint16_t gdispImageFlags
Image flags.
Definition: gdisp_image.h:51
gdispImageError gdispGImageDraw(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy)
Draw the image.
The structure for an image.
Definition: gdisp_image.h:59
COLOR_TYPE color_t
The color type definition.
Definition: gdisp_colors.h:412
bool_t gdispImageAdjustPalette(gdispImage *img, uint16_t index, color_t newColor)
Modify an entry in the color palette.
color_t gdispImageGetPalette(gdispImage *img, uint16_t index)
Get an entry in the color palette.
uint16_t gdispImageType
The type of image.
Definition: gdisp_image.h:26
void gdispImageInit(gdispImage *img)
Initialise a gdispImage object.
uint16_t gdispImageError
An image error code.
Definition: gdisp_image.h:37
gdispImageError gdispImageOpenGFile(gdispImage *img, GFILE *f)
Open an image using an open GFILE and get it ready for drawing.