NetSurf
bmp.c
Go to the documentation of this file.
1/*
2 * Copyright 2006 Richard Wilson <info@tinct.net>
3 * Copyright 2008 Sean Fox <dyntryx@gmail.com>
4 *
5 * This file is part of NetSurf, http://www.netsurf-browser.org/
6 *
7 * NetSurf is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * NetSurf is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/**
21 * \file
22 * implementation of content handler for BMP images.
23 */
24
25#include <stdbool.h>
26#include <stdlib.h>
27#include <libnsbmp.h>
28
29#include "utils/utils.h"
30#include "utils/messages.h"
31#include "netsurf/plotters.h"
32#include "netsurf/bitmap.h"
33#include "netsurf/content.h"
34#include "content/llcache.h"
38#include "desktop/bitmap.h"
39
40#include "image/bmp.h"
41
42/** bmp context. */
43typedef struct nsbmp_content {
44 struct content base;
45
46 bmp_image *bmp; /** BMP image data */
47
48 struct bitmap *bitmap; /**< Created NetSurf bitmap */
50
51/**
52 * Callback for libnsbmp; forwards the call to bitmap_create()
53 *
54 * \param width width of image in pixels
55 * \param height width of image in pixels
56 * \param bmp_state A flag word indicating the initial state
57 * \return An opaque struct bitmap, or NULL on memory exhaustion
58 */
59static void *nsbmp_bitmap_create(int width, int height, unsigned int bmp_state)
60{
61 unsigned int bitmap_state = BITMAP_NONE;
62
63 /* set bitmap state based on bmp state */
64 bitmap_state |= (bmp_state & BMP_OPAQUE) ? BITMAP_OPAQUE : 0;
65 bitmap_state |= (bmp_state & BMP_CLEAR_MEMORY) ?
66 BITMAP_CLEAR : 0;
67
68 /* return the created bitmap */
69 return guit->bitmap->create(width, height, bitmap_state);
70}
71
73{
74 bmp_bitmap_callback_vt bmp_bitmap_callbacks = {
75 .bitmap_create = nsbmp_bitmap_create,
76 .bitmap_destroy = guit->bitmap->destroy,
77 .bitmap_get_buffer = guit->bitmap->get_buffer,
78 };
79
80 bmp->bmp = calloc(sizeof(struct bmp_image), 1);
81 if (bmp->bmp == NULL) {
83 return NSERROR_NOMEM;
84 }
85
86 bmp_create(bmp->bmp, &bmp_bitmap_callbacks);
87
88 return NSERROR_OK;
89}
90
91static nserror
92nsbmp_create(const struct content_handler *handler,
93 lwc_string *imime_type,
94 const struct http_parameter *params,
96 const char *fallback_charset,
97 bool quirks,
98 struct content **c)
99{
100 nsbmp_content *bmp;
101 nserror error;
102
103 bmp = calloc(1, sizeof(nsbmp_content));
104 if (bmp == NULL)
105 return NSERROR_NOMEM;
106
107 error = content__init(&bmp->base, handler, imime_type, params,
108 llcache, fallback_charset, quirks);
109 if (error != NSERROR_OK) {
110 free(bmp);
111 return error;
112 }
113
114 error = nsbmp_create_bmp_data(bmp);
115 if (error != NSERROR_OK) {
116 free(bmp);
117 return error;
118 }
119
120 *c = (struct content *) bmp;
121
122 return NSERROR_OK;
123}
124
125static bool nsbmp_convert(struct content *c)
126{
127 nsbmp_content *bmp = (nsbmp_content *) c;
128 bmp_result res;
129 uint32_t swidth;
130 const uint8_t *data;
131 size_t size;
132 char *title;
133
134 /* set the bmp data */
135 data = content__get_source_data(c, &size);
136
137 /* analyse the BMP */
138 res = bmp_analyse(bmp->bmp, size, (unsigned char *) data);
139 switch (res) {
140 case BMP_OK:
141 break;
142 case BMP_INSUFFICIENT_MEMORY:
144 return false;
145 case BMP_INSUFFICIENT_DATA:
146 case BMP_DATA_ERROR:
148 return false;
149 }
150
151 /* Store our content width and description */
152 c->width = bmp->bmp->width;
153 c->height = bmp->bmp->height;
154 swidth = sizeof(uint32_t) * bmp->bmp->width;
155 c->size += (swidth * bmp->bmp->height) + 16 + 44;
156
157 /* set title text */
158 title = messages_get_buff("BMPTitle",
160 c->width, c->height);
161 if (title != NULL) {
163 free(title);
164 }
165
166 /* exit as a success */
167 bmp->bitmap = bmp->bmp->bitmap;
168
171
172 /* Done: update status bar */
173 content_set_status(c, "");
174 return true;
175}
176
177static bool nsbmp_redraw(struct content *c, struct content_redraw_data *data,
178 const struct rect *clip, const struct redraw_context *ctx)
179{
180 nsbmp_content *bmp = (nsbmp_content *) c;
182
183 if (bmp->bmp->decoded == false) {
184 bmp_result res;
185 res = bmp_decode(bmp->bmp);
186 /* allow short or incomplete image data giving a partial image*/
187 if ((res != BMP_OK) &&
188 (res != BMP_INSUFFICIENT_DATA) &&
189 (res != BMP_DATA_ERROR)) {
190 return false;
191 }
192
194 .layout = BITMAP_LAYOUT_R8G8B8A8,
195 });
196 guit->bitmap->modified(bmp->bitmap);
197 }
198
199 if (data->repeat_x)
200 flags |= BITMAPF_REPEAT_X;
201 if (data->repeat_y)
202 flags |= BITMAPF_REPEAT_Y;
203
204 return (ctx->plot->bitmap(ctx,
205 bmp->bitmap,
206 data->x, data->y,
207 data->width, data->height,
208 data->background_colour,
209 flags) == NSERROR_OK);
210}
211
212
213static void nsbmp_destroy(struct content *c)
214{
215 nsbmp_content *bmp = (nsbmp_content *) c;
216
217 bmp_finalise(bmp->bmp);
218 free(bmp->bmp);
219}
220
221
222static nserror nsbmp_clone(const struct content *old, struct content **newc)
223{
224 nsbmp_content *new_bmp;
225 nserror error;
226
227 new_bmp = calloc(1, sizeof(nsbmp_content));
228 if (new_bmp == NULL)
229 return NSERROR_NOMEM;
230
231 error = content__clone(old, &new_bmp->base);
232 if (error != NSERROR_OK) {
233 content_destroy(&new_bmp->base);
234 return error;
235 }
236
237 /* We "clone" the old content by replaying creation and conversion */
238 error = nsbmp_create_bmp_data(new_bmp);
239 if (error != NSERROR_OK) {
240 content_destroy(&new_bmp->base);
241 return error;
242 }
243
244 if (old->status == CONTENT_STATUS_READY ||
245 old->status == CONTENT_STATUS_DONE) {
246 if (nsbmp_convert(&new_bmp->base) == false) {
247 content_destroy(&new_bmp->base);
249 }
250 }
251
252 *newc = (struct content *) new_bmp;
253
254 return NSERROR_OK;
255}
256
257static void *nsbmp_get_internal(const struct content *c, void *context)
258{
259 nsbmp_content *bmp = (nsbmp_content *)c;
260
261 return bmp->bitmap;
262}
263
265{
266 return CONTENT_IMAGE;
267}
268
269static bool nsbmp_content_is_opaque(struct content *c)
270{
271 nsbmp_content *bmp = (nsbmp_content *)c;
272
273 if (bmp->bitmap != NULL) {
274 return guit->bitmap->get_opaque(bmp->bitmap);
275 }
276
277 return false;
278}
279
282 .data_complete = nsbmp_convert,
283 .destroy = nsbmp_destroy,
284 .redraw = nsbmp_redraw,
285 .clone = nsbmp_clone,
286 .get_internal = nsbmp_get_internal,
287 .type = nsbmp_content_type,
288 .is_opaque = nsbmp_content_is_opaque,
289 .no_share = false,
290};
291
292static const char *nsbmp_types[] = {
293 "application/bmp",
294 "application/preview",
295 "application/x-bmp",
296 "application/x-win-bitmap",
297 "image/bmp",
298 "image/ms-bmp",
299 "image/x-bitmap",
300 "image/x-bmp",
301 "image/x-ms-bmp",
302 "image/x-win-bitmap",
303 "image/x-windows-bmp",
304 "image/x-xbitmap"
305};
306
static void * nsbmp_get_internal(const struct content *c, void *context)
Definition: bmp.c:257
CONTENT_FACTORY_REGISTER_TYPES(nsbmp, nsbmp_types, nsbmp_content_handler)
static nserror nsbmp_create_bmp_data(nsbmp_content *bmp)
Definition: bmp.c:72
static bool nsbmp_convert(struct content *c)
Definition: bmp.c:125
static bool nsbmp_content_is_opaque(struct content *c)
Definition: bmp.c:269
struct nsbmp_content nsbmp_content
bmp context.
static void * nsbmp_bitmap_create(int width, int height, unsigned int bmp_state)
Callback for libnsbmp; forwards the call to bitmap_create()
Definition: bmp.c:59
static void nsbmp_destroy(struct content *c)
Definition: bmp.c:213
static const content_handler nsbmp_content_handler
Definition: bmp.c:280
static bool nsbmp_redraw(struct content *c, struct content_redraw_data *data, const struct rect *clip, const struct redraw_context *ctx)
Definition: bmp.c:177
static nserror nsbmp_create(const struct content_handler *handler, lwc_string *imime_type, const struct http_parameter *params, llcache_handle *llcache, const char *fallback_charset, bool quirks, struct content **c)
Definition: bmp.c:92
static content_type nsbmp_content_type(void)
Definition: bmp.c:264
static const char * nsbmp_types[]
Definition: bmp.c:292
static nserror nsbmp_clone(const struct content *old, struct content **newc)
Definition: bmp.c:222
interface to image/bmp content handler initialisation.
void content_destroy(struct content *c)
Destroy and free a content.
Definition: content.c:354
void content_set_done(struct content *c)
Put a content in status CONTENT_STATUS_DONE.
Definition: content.c:299
bool content__set_title(struct content *c, const char *title)
Set title associated with content.
Definition: content.c:1090
nserror content__init(struct content *c, const content_handler *handler, lwc_string *imime_type, const struct http_parameter *params, llcache_handle *llcache, const char *fallback_charset, bool quirks)
Definition: content.c:190
const uint8_t * content__get_source_data(struct content *c, size_t *size)
Retrieve source of content.
Definition: content.c:1216
nserror content__clone(const struct content *c, struct content *nc)
Clone a content's data members.
Definition: content.c:1382
void content_set_ready(struct content *c)
Put a content in status CONTENT_STATUS_READY and unlock the content.
Definition: content.c:285
void content_set_status(struct content *c, const char *status_message)
Updates content with new status.
Definition: content.c:270
void content_broadcast_error(struct content *c, nserror errorcode, const char *msg)
Send an error message to all users.
Definition: content.c:769
Protected interface to Content handling.
@ CONTENT_STATUS_READY
Some parts of content still being loaded, but can be displayed.
Definition: content_type.h:92
@ CONTENT_STATUS_DONE
Content has completed all processing.
Definition: content_type.h:95
content_type
The type of a content.
Definition: content_type.h:53
@ CONTENT_IMAGE
All images.
Definition: content_type.h:67
Internal core bitmap interface.
static void bitmap_format_to_client(void *bitmap, const bitmap_fmt_t *current_fmt)
Convert a bitmap to the client bitmap format.
Definition: bitmap.h:117
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_BMP_ERROR
A BMP error occurred.
Definition: errors.h:39
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_CLONE_FAILED
Failed to clone handle.
Definition: errors.h:37
@ NSERROR_OK
No error.
Definition: errors.h:30
struct netsurf_table * guit
The global interface table.
Definition: gui_factory.c:49
Interface to core interface table.
Generic bitmap handling interface.
@ BITMAP_CLEAR
memory should be wiped to 0
Definition: bitmap.h:39
@ BITMAP_OPAQUE
image is opaque
Definition: bitmap.h:38
@ BITMAP_NONE
Definition: bitmap.h:37
Public content interface.
Target independent plotting interface.
#define BITMAPF_REPEAT_X
Definition: plotters.h:38
#define BITMAPF_REPEAT_Y
Definition: plotters.h:39
unsigned long bitmap_flags_t
Definition: plotters.h:36
#define BITMAPF_NONE
Definition: plotters.h:37
static struct llcache_s * llcache
low level cache state
Definition: llcache.c:267
nsurl * llcache_handle_get_url(const llcache_handle *handle)
Retrieve the post-redirect URL of a low-level cache object.
Definition: llcache.c:4195
Low-level resource cache (interface)
char * messages_get_buff(const char *key,...)
Formatted message from a key in the global message hash.
Definition: messages.c:205
Localised message support (interface).
const char * nsurl_access_leaf(const nsurl *url)
Access a URL's path leaf as a string.
int width
Definition: gui.c:159
int height
Definition: gui.c:160
Bitmap format specifier.
Definition: bitmap.h:95
RISC OS wimp toolkit bitmap.
Definition: bitmap.c:68
Content operation function table.
nserror(* create)(const struct content_handler *handler, lwc_string *imime_type, const struct http_parameter *params, struct llcache_handle *llcache, const char *fallback_charset, bool quirks, struct content **c)
parameters to content redraw
Definition: content.h:40
int height
vertical dimension
Definition: content.h:48
bool repeat_y
whether content is tiled in y direction
Definition: content.h:59
bool repeat_x
whether content is tiled in x direction
Definition: content.h:58
int y
coordinate for top-left of redraw
Definition: content.h:42
int x
coordinate for top-left of redraw
Definition: content.h:41
colour background_colour
The background colour.
Definition: content.h:51
int width
dimensions to render content at (for scaling contents with intrinsic dimensions)
Definition: content.h:47
Content which corresponds to a single URL.
int height
Height dimension, if applicable.
int width
Width dimension, if applicable.
struct llcache_handle * llcache
Low-level cache object.
struct textsearch_context * context
content_status status
Current status.
unsigned int size
Estimated size of all data associated with this content.
char * title
Title for browser window.
void(* destroy)(void *bitmap)
Destroy a bitmap.
Definition: bitmap.h:143
void *(* create)(int width, int height, enum gui_bitmap_flags flags)
Create a new bitmap.
Definition: bitmap.h:136
bool(* get_opaque)(void *bitmap)
Get the opacity of a bitmap.
Definition: bitmap.h:159
void(* modified)(void *bitmap)
Marks a bitmap as modified.
Definition: bitmap.h:200
unsigned char *(* get_buffer)(void *bitmap)
Get the image buffer from a bitmap.
Definition: bitmap.h:169
Representation of an HTTP parameter.
Definition: parameter.c:31
Handle to low-level cache object.
Definition: llcache.c:76
struct gui_bitmap_table * bitmap
Bitmap table.
Definition: gui_table.h:144
bmp context.
Definition: bmp.c:43
struct bitmap * bitmap
BMP image data.
Definition: bmp.c:48
struct content base
Definition: bmp.c:44
bmp_image * bmp
Definition: bmp.c:46
nserror(* bitmap)(const struct redraw_context *ctx, struct bitmap *bitmap, int x, int y, int width, int height, colour bg, bitmap_flags_t flags)
Plot a bitmap.
Definition: plotters.h:257
Rectangle coordinates.
Definition: types.h:40
Redraw context.
Definition: plotters.h:51
const struct plotter_table * plot
Current plot operation table.
Definition: plotters.h:73
Interface to a number of general purpose functionality.
static nserror clip(const struct redraw_context *ctx, const struct rect *clip)
Sets a clip rectangle for subsequent plot operations.
Definition: plot.c:357