1 /*
2  * Copyright 2006 Richard Wilson <richard.wilson@netsurf-browser.org>
3  * Copyright 2008 Sean Fox <dyntryx@gmail.com>
4  *
5  * This file is part of NetSurf's libnsbmp, http://www.netsurf-browser.org/
6  * Licenced under the MIT License,
7  *                http://www.opensource.org/licenses/mit-license.php
8  */
9 
10 /**
11  * \file
12  * Bitmap file decoding interface.
13  */
14 
15 #ifndef libnsbmp_h_
16 #define libnsbmp_h_
17 
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include <stddef.h>
21 
22 /* bmp flags */
23 #define BMP_NEW			0
24 /** image is opaque (as opposed to having an alpha mask) */
25 #define BMP_OPAQUE		(1 << 0)
26 /** memory should be wiped */
27 #define BMP_CLEAR_MEMORY	(1 << 1)
28 
29 /**
30  * error return values
31  */
32 typedef enum {
33         BMP_OK = 0,
34         BMP_INSUFFICIENT_MEMORY = 1,
35         BMP_INSUFFICIENT_DATA = 2,
36         BMP_DATA_ERROR = 3
37 } bmp_result;
38 
39 /**
40  * encoding types
41  */
42 typedef enum {
43         BMP_ENCODING_RGB = 0,
44         BMP_ENCODING_RLE8 = 1,
45         BMP_ENCODING_RLE4 = 2,
46         BMP_ENCODING_BITFIELDS = 3
47 } bmp_encoding;
48 
49 /* API for Bitmap callbacks */
50 typedef void* (*bmp_bitmap_cb_create)(int width, int height, unsigned int state);
51 typedef void (*bmp_bitmap_cb_destroy)(void *bitmap);
52 typedef unsigned char* (*bmp_bitmap_cb_get_buffer)(void *bitmap);
53 typedef size_t (*bmp_bitmap_cb_get_bpp)(void *bitmap);
54 
55 /**
56  * The Bitmap callbacks function table
57  */
58 typedef struct bmp_bitmap_callback_vt_s {
59         /** Callback to allocate bitmap storage. */
60         bmp_bitmap_cb_create bitmap_create;
61         /** Called to free bitmap storage. */
62         bmp_bitmap_cb_destroy bitmap_destroy;
63         /** Return a pointer to the pixel data in a bitmap. */
64         bmp_bitmap_cb_get_buffer bitmap_get_buffer;
65         /** Find the width of a pixel row in bytes. */
66         bmp_bitmap_cb_get_bpp bitmap_get_bpp;
67 } bmp_bitmap_callback_vt;
68 
69 /**
70  * bitmap image
71  */
72 typedef struct bmp_image {
73         /** callbacks for bitmap functions */
74         bmp_bitmap_callback_vt bitmap_callbacks;
75         /** pointer to BMP data */
76         uint8_t *bmp_data;
77         /** width of BMP (valid after _analyse) */
78         uint32_t width;
79         /** heigth of BMP (valid after _analyse) */
80         uint32_t height;
81         /** whether the image has been decoded */
82         bool decoded;
83         /** decoded image */
84         void *bitmap;
85 
86         /* Internal members are listed below */
87         /** total number of bytes of BMP data available */
88         uint32_t buffer_size;
89         /** pixel encoding type */
90         bmp_encoding encoding;
91         /** offset of bitmap data */
92         uint32_t bitmap_offset;
93         /** bits per pixel */
94         uint16_t bpp;
95         /** number of colours */
96         uint32_t colours;
97         /** colour table */
98         uint32_t *colour_table;
99         /** whether to use bmp's limited transparency */
100         bool limited_trans;
101         /** colour to display for "transparent" pixels when using limited
102          * transparency
103          */
104         uint32_t trans_colour;
105         /** scanlines are top to bottom */
106         bool reversed;
107         /** image is part of an ICO, mask follows */
108         bool ico;
109         /** true if the bitmap does not contain an alpha channel */
110         bool opaque;
111         /** four bitwise mask */
112         uint32_t mask[4];
113         /** four bitwise shifts */
114         int32_t shift[4];
115         /** colour representing "transparency" in the bitmap */
116         uint32_t transparent_index;
117 } bmp_image;
118 
119 typedef struct ico_image {
120         bmp_image bmp;
121         struct ico_image *next;
122 } ico_image;
123 
124 /**
125  * icon image collection
126  */
127 typedef struct ico_collection {
128         /** callbacks for bitmap functions */
129         bmp_bitmap_callback_vt bitmap_callbacks;
130         /** width of largest BMP */
131         uint16_t width;
132         /** heigth of largest BMP */
133         uint16_t height;
134 
135         /* Internal members are listed below */
136         /** pointer to ICO data */
137         uint8_t *ico_data;
138         /** total number of bytes of ICO data available */
139         uint32_t buffer_size;
140         /** root of linked list of images */
141         ico_image *first;
142 } ico_collection;
143 
144 /**
145  * Initialises bitmap ready for analysing the bitmap.
146  *
147  * \param bmp The Bitmap to initialise
148  * \param callbacks The callbacks the library will call on operations.
149  * \return BMP_OK on success or appropriate error code.
150  */
151 bmp_result bmp_create(bmp_image *bmp, bmp_bitmap_callback_vt *callbacks);
152 
153 /**
154  * Initialises icon ready for analysing the icon
155  *
156  * \param bmp The Bitmap to initialise
157  * \param callbacks The callbacks the library will call on operations.
158  * \return BMP_OK on success or appropriate error code.
159  */
160 bmp_result ico_collection_create(ico_collection *ico,
161                                  bmp_bitmap_callback_vt *callbacks);
162 
163 /**
164  * Analyse a BMP prior to decoding.
165  *
166  * This will scan the data provided and perform checks to ensure the data is a
167  * valid BMP and prepare the bitmap image structure ready for decode.
168  *
169  * This function must be called and resturn BMP_OK before bmp_decode() as it
170  * prepares the bmp internal state for the decode process.
171  *
172  * \param bmp the BMP image to analyse.
173  * \param size The size of data in cdata.
174  * \param data The bitmap source data.
175  * \return BMP_OK on success or error code on faliure.
176  */
177 bmp_result bmp_analyse(bmp_image *bmp, size_t size, uint8_t *data);
178 
179 /**
180  * Analyse an ICO prior to decoding.
181  *
182  * This function will scan the data provided and perform checks to ensure the
183  * data is a valid ICO.
184  *
185  * This function must be called before ico_find().
186  *
187  * \param ico the ICO image to analyse
188  * \param size The size of data in cdata.
189  * \param data The bitmap source data.
190  * \return BMP_OK on success
191  */
192 bmp_result ico_analyse(ico_collection *ico, size_t size, uint8_t *data);
193 
194 /**
195  * Decode a BMP
196  *
197  * This function decodes the BMP data such that bmp->bitmap is a valid
198  * image. The state of bmp->decoded is set to TRUE on exit such that it
199  * can easily be identified which BMPs are in a fully decoded state.
200  *
201  * \param bmp the BMP image to decode
202  * \return BMP_OK on success
203  */
204 bmp_result bmp_decode(bmp_image *bmp);
205 
206 /**
207  * Decode a BMP using "limited transparency"
208  *
209  * Bitmaps do not have native transparency support.  However, there is a
210  * "trick" that is used in some instances in which the first pixel of the
211  * bitmap becomes the "transparency index".  The decoding application can
212  * replace this index with whatever background colour it chooses to
213  * create the illusion of transparency.
214  *
215  * When to use transparency is at the discretion of the decoding
216  * application.
217  *
218  * \param bmp the BMP image to decode
219  * \param colour the colour to use as "transparent"
220  * \return BMP_OK on success
221  */
222 bmp_result bmp_decode_trans(bmp_image *bmp, uint32_t transparent_colour);
223 
224 /**
225  * Finds the closest BMP within an ICO collection
226  *
227  * This function finds the BMP with dimensions as close to a specified set
228  * as possible from the images in the collection.
229  *
230  * \param ico the ICO collection to examine
231  * \param width the preferred width (0 to use ICO header width)
232  * \param height the preferred height (0 to use ICO header height)
233  */
234 bmp_image *ico_find(ico_collection *ico, uint16_t width, uint16_t height);
235 
236 /**
237  * Finalise a BMP prior to destruction.
238  *
239  * \param bmp the BMP image to finalise.
240  */
241 void bmp_finalise(bmp_image *bmp);
242 
243 /**
244  * Finalise an ICO prior to destruction.
245  *
246  * \param ico the ICO image to finalise,
247  */
248 void ico_finalise(ico_collection *ico);
249 
250 #endif
251