Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3584 sourcerer 1
/*
2
 * Copyright 2010 Chris Young 
3
 *
4
 * This file is part of NetSurf, http://www.netsurf-browser.org/
5
 *
6
 * NetSurf is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; version 2 of the License.
9
 *
10
 * NetSurf is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program.  If not, see .
17
 */
18
 
19
/** \file
20
 * Content for image/webp (libwebp implementation).
21
 *
22
 */
23
 
24
#include 
25
#include 
26
#include 
27
#include 
28
#include "desktop/plotters.h"
29
#include "image/bitmap.h"
30
#include "content/content_protected.h"
31
#include "utils/log.h"
32
#include "utils/messages.h"
33
#include "utils/utils.h"
34
 
35
typedef struct webp_content
36
{
37
	struct content base;
38
 
39
	struct bitmap *bitmap;	/**< Created NetSurf bitmap */
40
} webp_content;
41
 
42
 
43
static nserror webp_create(const content_handler *handler,
44
		lwc_string *imime_type, const http_parameter *params,
45
		llcache_handle *llcache, const char *fallback_charset,
46
		bool quirks, struct content **c)
47
{
48
	webp_content *webp;
49
	nserror error;
50
 
51
	webp = calloc(1, sizeof(webp_content));
52
	if (webp == NULL)
53
		return NSERROR_NOMEM;
54
 
55
	error = content__init(&webp->base, handler, imime_type, params,
56
			llcache, fallback_charset, quirks);
57
	if (error != NSERROR_OK) {
58
		free(webp);
59
		return error;
60
	}
61
 
62
	*c = (struct content *) webp;
63
 
64
	return NSERROR_OK;
65
}
66
 
67
/**
68
 * Convert a CONTENT_WEBP for display.
69
 *
70
 * No conversion is necessary. We merely read the WebP dimensions.
71
 */
72
 
73
static bool webp_convert(struct content *c)
74
{
75
	webp_content *webp = (webp_content *)c;
76
	union content_msg_data msg_data;
77
	const uint8_t *data;
78
	unsigned char *imagebuf = NULL;
79
	unsigned long size;
80
	int width = 0, height = 0;
81
	char *title;
82
	int res = 0;
83
	uint8_t *res_p = NULL;
84
 
85
	data = (uint8_t *)content__get_source_data(c, &size);
86
 
87
	res = WebPGetInfo(data, size, &width, &height);
88
	if (res == 0) {
89
		msg_data.error = messages_get("NoMemory");
90
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
91
		return false;
92
	}
93
 
94
	webp->bitmap = bitmap_create(width, height, BITMAP_NEW | BITMAP_OPAQUE);
95
	if (!webp->bitmap) {
96
		msg_data.error = messages_get("NoMemory");
97
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
98
		return false;
99
	}
100
 
101
	imagebuf = bitmap_get_buffer(webp->bitmap);
102
	if (!imagebuf) {
103
		msg_data.error = messages_get("NoMemory");
104
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
105
		return false;
106
	}
107
	unsigned int row_width = bitmap_get_rowstride(webp->bitmap);
108
 
109
	res_p = WebPDecodeRGBAInto(data, size, imagebuf,
110
				row_width * height, row_width);
111
	if (res_p == NULL) {
112
		msg_data.error = messages_get("NoMemory");
113
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
114
		return false;
115
	}
116
 
117
	c->width = width;
118
	c->height = height;
119
 
120
	/* set title */
121
	title = messages_get_buff("WebPTitle",
122
			nsurl_access_leaf(llcache_handle_get_url(c->llcache)),
123
			c->width, c->height);
124
	if (title != NULL) {
125
		content__set_title(c, title);
126
		free(title);
127
	}
128
 
129
	bitmap_modified(webp->bitmap);
130
 
131
	content_set_ready(c);
132
	content_set_done(c);
133
 
134
	content_set_status(c, "");
135
	return true;
136
}
137
 
138
 
139
/**
140
 * Destroy a CONTENT_WEBP and free all resources it owns.
141
 */
142
 
143
static void webp_destroy(struct content *c)
144
{
145
	webp_content *webp = (webp_content *)c;
146
 
147
	if (webp->bitmap != NULL)
148
		bitmap_destroy(webp->bitmap);
149
}
150
 
151
 
152
/**
153
 * Redraw a CONTENT_WEBP.
154
 */
155
 
156
static bool webp_redraw(struct content *c, struct content_redraw_data *data,
157
		const struct rect *clip, const struct redraw_context *ctx)
158
{
159
	webp_content *webp = (webp_content *)c;
160
	bitmap_flags_t flags = BITMAPF_NONE;
161
 
162
	if (data->repeat_x)
163
		flags |= BITMAPF_REPEAT_X;
164
	if (data->repeat_y)
165
		flags |= BITMAPF_REPEAT_Y;
166
 
167
	return ctx->plot->bitmap(data->x, data->y, data->width, data->height,
168
			webp->bitmap, data->background_colour, flags);
169
}
170
 
171
 
172
static nserror webp_clone(const struct content *old, struct content **newc)
173
{
174
	webp_content *webp;
175
	nserror error;
176
 
177
	webp = calloc(1, sizeof(webp_content));
178
	if (webp == NULL)
179
		return NSERROR_NOMEM;
180
 
181
	error = content__clone(old, &webp->base);
182
	if (error != NSERROR_OK) {
183
		content_destroy(&webp->base);
184
		return error;
185
	}
186
 
187
	/* Simply replay convert */
188
	if (old->status == CONTENT_STATUS_READY ||
189
			old->status == CONTENT_STATUS_DONE) {
190
		if (webp_convert(&webp->base) == false) {
191
			content_destroy(&webp->base);
192
			return NSERROR_CLONE_FAILED;
193
		}
194
	}
195
 
196
	*newc = (struct content *) webp;
197
 
198
	return NSERROR_OK;
199
}
200
 
201
static void *webp_get_internal(const struct content *c, void *context)
202
{
203
	webp_content *webp = (webp_content *)c;
204
 
205
	return webp->bitmap;
206
}
207
 
208
static content_type webp_content_type(void)
209
{
210
	return CONTENT_IMAGE;
211
}
212
 
213
static const content_handler webp_content_handler = {
214
	.create = webp_create,
215
	.data_complete = webp_convert,
216
	.destroy = webp_destroy,
217
	.redraw = webp_redraw,
218
	.clone = webp_clone,
219
	.get_internal = webp_get_internal,
220
	.type = webp_content_type,
221
	.no_share = false,
222
};
223
 
224
static const char *webp_types[] = {
225
	"image/webp"
226
};
227
 
228
CONTENT_FACTORY_REGISTER_TYPES(webp, webp_types, webp_content_handler);
229