NetSurf
dt_anim.c
Go to the documentation of this file.
1/*
2 * Copyright 2011 Chris Young <chris@unsatisfactorysoftware.co.uk>
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 <http://www.gnu.org/licenses/>.
17 */
18
19/** \file
20 * DataTypes animation handler (implementation)
21*/
22
23#ifdef WITH_AMIGA_DATATYPES
24#include "amiga/os3support.h"
25
26#include <stdlib.h>
27#include <proto/datatypes.h>
28#include <proto/dos.h>
29#include <proto/exec.h>
30#include <proto/intuition.h>
31#include <datatypes/animationclass.h>
32#include <datatypes/pictureclass.h>
33#ifdef __amigaos4__
34#include <graphics/blitattr.h>
35#endif
36#include <intuition/classusr.h>
37
38#include "utils/log.h"
39#include "utils/messages.h"
40#include "netsurf/plotters.h"
41#include "netsurf/bitmap.h"
42#include "netsurf/content.h"
43#include "content/content.h"
46#include "content/llcache.h"
47
48#include "amiga/bitmap.h"
49#include "amiga/filetype.h"
50#include "amiga/datatypes.h"
51#include "amiga/plotters.h"
52
53typedef struct amiga_dt_anim_content {
54 struct content base;
55
56 struct bitmap *bitmap; /**< Created NetSurf bitmap */
57
58 Object *dto;
59 int x;
60 int y;
61 int w;
62 int h;
63} amiga_dt_anim_content;
64
65static APTR ami_colormap_to_clut(struct ColorMap *cmap);
66
67static nserror amiga_dt_anim_create(const content_handler *handler,
68 lwc_string *imime_type, const struct http_parameter *params,
69 llcache_handle *llcache, const char *fallback_charset,
70 bool quirks, struct content **c);
71static bool amiga_dt_anim_convert(struct content *c);
72static void amiga_dt_anim_reformat(struct content *c, int width, int height);
73static void amiga_dt_anim_destroy(struct content *c);
74static bool amiga_dt_anim_redraw(struct content *c,
75 struct content_redraw_data *data, const struct rect *clip,
76 const struct redraw_context *ctx);
77static nserror amiga_dt_anim_open(struct content *c, struct browser_window *bw,
78 struct content *page, struct object_params *params);
79static nserror amiga_dt_anim_close(struct content *c);
80static nserror amiga_dt_anim_clone(const struct content *old, struct content **newc);
81static content_type amiga_dt_anim_content_type(void);
82
83static void *amiga_dt_anim_get_internal(const struct content *c, void *context)
84{
85 amiga_dt_anim_content *adta_c = (amiga_dt_anim_content *)c;
86
87 return adta_c->bitmap;
88}
89
90static const content_handler amiga_dt_anim_content_handler = {
91 .create = amiga_dt_anim_create,
92 .data_complete = amiga_dt_anim_convert,
93 .reformat = amiga_dt_anim_reformat,
94 .destroy = amiga_dt_anim_destroy,
95 .redraw = amiga_dt_anim_redraw,
96 .open = amiga_dt_anim_open,
97 .close = amiga_dt_anim_close,
98 .clone = amiga_dt_anim_clone,
99 .get_internal = amiga_dt_anim_get_internal,
100 .type = amiga_dt_anim_content_type,
101 .no_share = false,
102};
103
104nserror amiga_dt_anim_init(void)
105{
106 struct DataType *dt, *prevdt = NULL;
107 lwc_string *type;
108 nserror error;
109 struct Node *node = NULL;
110
111 while((dt = ObtainDataType(DTST_RAM, NULL,
112 DTA_DataType, prevdt,
113 DTA_GroupID, GID_ANIMATION,
114 TAG_DONE)) != NULL)
115 {
116 ReleaseDataType(prevdt);
117 prevdt = dt;
118
119 do {
120 node = ami_mime_from_datatype(dt, &type, node);
121
122 if(node)
123 {
125 lwc_string_data(type),
126 &amiga_dt_anim_content_handler);
127
128 if (error != NSERROR_OK)
129 return error;
130 }
131
132 }while (node != NULL);
133
134 }
135
136 ReleaseDataType(prevdt);
137
138 return NSERROR_OK;
139}
140
141nserror amiga_dt_anim_create(const content_handler *handler,
142 lwc_string *imime_type, const struct http_parameter *params,
143 llcache_handle *llcache, const char *fallback_charset,
144 bool quirks, struct content **c)
145{
146 amiga_dt_anim_content *plugin;
147 nserror error;
148
149 plugin = calloc(1, sizeof(amiga_dt_anim_content));
150 if (plugin == NULL)
151 return NSERROR_NOMEM;
152
153 error = content__init(&plugin->base, handler, imime_type, params,
154 llcache, fallback_charset, quirks);
155 if (error != NSERROR_OK) {
156 free(plugin);
157 return error;
158 }
159
160 *c = (struct content *) plugin;
161
162 return NSERROR_OK;
163}
164
165bool amiga_dt_anim_convert(struct content *c)
166{
167 NSLOG(netsurf, INFO, "amiga_dt_anim_convert");
168
169 amiga_dt_anim_content *plugin = (amiga_dt_anim_content *) c;
170 union content_msg_data msg_data;
171 int width, height;
172 const uint8_t *data;
173 size_t size;
174 UBYTE *bm_buffer;
175 struct BitMapHeader *bmh;
176 unsigned int bm_flags = BITMAP_OPAQUE;
177 struct adtFrame adt_frame;
178 APTR clut;
179
180 data = content__get_source_data(c, &size);
181
182 if((plugin->dto = NewDTObject(NULL,
183 DTA_SourceType, DTST_MEMORY,
184 DTA_SourceAddress, data,
185 DTA_SourceSize, size,
186 DTA_GroupID, GID_ANIMATION,
187 TAG_DONE))) {
188 if(GetDTAttrs(plugin->dto, PDTA_BitMapHeader, &bmh, TAG_DONE)) {
189 width = (int)bmh->bmh_Width;
190 height = (int)bmh->bmh_Height;
191
192 plugin->bitmap = amiga_bitmap_create(width, height, bm_flags);
193 if (!plugin->bitmap) {
194 msg_data.errordata.errorcode = NSERROR_NOMEM;
195 msg_data.errordata.errormsg = messages_get("NoMemory");
197 return false;
198 }
199
200 bm_buffer = amiga_bitmap_get_buffer(plugin->bitmap);
201
202 adt_frame.MethodID = ADTM_LOADFRAME;
203 adt_frame.alf_TimeStamp = 0;
204 IDoMethodA(plugin->dto, (Msg)&adt_frame);
205
206 clut = ami_colormap_to_clut(adt_frame.alf_CMap);
207#ifdef __amigaos4__
208 BltBitMapTags(
209 BLITA_Width, width,
210 BLITA_Height, height,
211 BLITA_Source, adt_frame.alf_BitMap,
212 BLITA_SrcType, BLITT_BITMAP,
213 BLITA_Dest, bm_buffer,
214 BLITA_DestType, BLITT_RGB24,
215 BLITA_DestBytesPerRow, width,
216 BLITA_CLUT, clut,
217 TAG_DONE);
218#else
219#warning FIXME: Need to use a different blitter function for OS3!
220#endif
221 free(clut);
222
223 adt_frame.MethodID = ADTM_UNLOADFRAME;
224 IDoMethodA(plugin->dto, (Msg)&adt_frame);
225 }
226 else return false;
227 }
228 else return false;
229
230 c->width = width;
231 c->height = height;
232
233/*
234 snprintf(title, sizeof(title), "image (%lux%lu, %lu bytes)",
235 width, height, size);
236 content__set_title(c, title);
237*/
238
239 amiga_bitmap_modified(plugin->bitmap);
240
243
244 content_set_status(c, "");
245 return true;
246}
247
248void amiga_dt_anim_destroy(struct content *c)
249{
250 amiga_dt_anim_content *plugin = (amiga_dt_anim_content *) c;
251
252 NSLOG(netsurf, INFO, "amiga_dt_anim_destroy");
253
254 if (plugin->bitmap != NULL)
255 amiga_bitmap_destroy(plugin->bitmap);
256
257 DisposeDTObject(plugin->dto);
258
259 return;
260}
261
262bool amiga_dt_anim_redraw(struct content *c,
263 struct content_redraw_data *data, const struct rect *clip,
264 const struct redraw_context *ctx)
265{
266 amiga_dt_anim_content *plugin = (amiga_dt_anim_content *) c;
268
269 NSLOG(netsurf, INFO, "amiga_dt_anim_redraw");
270
271 if (data->repeat_x)
272 flags |= BITMAPF_REPEAT_X;
273 if (data->repeat_y)
274 flags |= BITMAPF_REPEAT_Y;
275
276 return (ctx->plot->bitmap(ctx, plugin->bitmap,
277 data->x, data->y,
278 data->width, data->height,
279 data->background_colour,
280 flags) == NSERROR_OK);
281}
282
283/**
284 * Handle a window containing a CONTENT_PLUGIN being opened.
285 *
286 * \param c content that has been opened
287 * \param bw browser window containing the content
288 * \param page content of type CONTENT_HTML containing c, or 0 if not an
289 * object within a page
290 * \param box box containing c, or 0 if not an object
291 * \param params object parameters, or 0 if not an object
292 */
293nserror amiga_dt_anim_open(struct content *c, struct browser_window *bw,
294 struct content *page, struct object_params *params)
295{
296 NSLOG(netsurf, INFO, "amiga_dt_anim_open");
297
298 return NSERROR_OK;
299}
300
301nserror amiga_dt_anim_close(struct content *c)
302{
303 NSLOG(netsurf, INFO, "amiga_dt_anim_close");
304 return NSERROR_OK;
305}
306
307void amiga_dt_anim_reformat(struct content *c, int width, int height)
308{
309 NSLOG(netsurf, INFO, "amiga_dt_anim_reformat");
310 return;
311}
312
313nserror amiga_dt_anim_clone(const struct content *old, struct content **newc)
314{
315 amiga_dt_anim_content *plugin;
316 nserror error;
317
318 NSLOG(netsurf, INFO, "amiga_dt_anim_clone");
319
320 plugin = calloc(1, sizeof(amiga_dt_anim_content));
321 if (plugin == NULL)
322 return NSERROR_NOMEM;
323
324 error = content__clone(old, &plugin->base);
325 if (error != NSERROR_OK) {
326 content_destroy(&plugin->base);
327 return error;
328 }
329
330 /* We "clone" the old content by replaying conversion */
331 if (old->status == CONTENT_STATUS_READY ||
332 old->status == CONTENT_STATUS_DONE) {
333 if (amiga_dt_anim_convert(&plugin->base) == false) {
334 content_destroy(&plugin->base);
336 }
337 }
338
339 *newc = (struct content *) plugin;
340
341 return NSERROR_OK;
342}
343
344content_type amiga_dt_anim_content_type(void)
345{
346 return CONTENT_IMAGE;
347}
348
349static APTR ami_colormap_to_clut(struct ColorMap *cmap)
350{
351 int i;
352 UBYTE *clut = calloc(1, 256 * 4);
353 ULONG colr[256 * 4];
354
355 if(!clut) return NULL;
356
357 /* Get the palette from the ColorMap */
358 GetRGB32(cmap, 0, 256, (ULONG *)&colr);
359
360 /* convert it to a table of ARGB values */
361 for(i = 0; i < 1024; i += 4)
362 {
363 clut[i] = (0xff << 24) |
364 ((colr[i] & 0xff000000) >> 8) |
365 ((colr[i + 1] & 0xff000000) >> 16) |
366 ((colr[i + 2] & 0xff000000) >> 24);
367 }
368
369 return clut;
370}
371
372#endif
struct Node * ami_mime_from_datatype(struct DataType *dt, lwc_string **mimetype, struct Node *start_node)
Return a MIME Type matching a DataType.
Definition: filetype.c:455
Content handling interface.
void content_destroy(struct content *c)
Destroy and free a content.
Definition: content.c:354
void content_broadcast(struct content *c, content_msg msg, const union content_msg_data *data)
Send a message to all users.
Definition: content.c:752
void content_set_done(struct content *c)
Put a content in status CONTENT_STATUS_DONE.
Definition: content.c:299
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
nserror content_factory_register_handler(const char *mime_type, const content_handler *handler)
Register a handler with the content factory.
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
@ CONTENT_MSG_ERROR
error occurred
Definition: content_type.h:122
nserror
Enumeration of error codes.
Definition: errors.h:29
@ 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
const char * type
Definition: filetype.cpp:44
void * amiga_bitmap_create(int width, int height, enum gui_bitmap_flags flags)
Create a bitmap.
Definition: bitmap.c:111
void amiga_bitmap_modified(void *bitmap)
The bitmap image has changed, so flush any persistant cache.
Definition: bitmap.c:280
unsigned char * amiga_bitmap_get_buffer(void *bitmap)
Return a pointer to the pixel data in a bitmap.
Definition: bitmap.c:174
void amiga_bitmap_destroy(void *bitmap)
Free a bitmap.
Definition: bitmap.c:213
Generic bitmap handling interface.
@ BITMAP_OPAQUE
image is opaque
Definition: bitmap.h:38
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
Low-level resource cache (interface)
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
const char * messages_get(const char *key)
Fast lookup of a message by key from the standard Messages hash.
Definition: messages.c:241
Localised message support (interface).
Minimal compatibility header for AmigaOS 3.
#define IDoMethodA
Definition: os3support.h:170
@ base
Definition: punycode.c:19
int width
Definition: gui.c:160
int height
Definition: gui.c:161
RISC OS wimp toolkit bitmap.
Definition: bitmap.c:68
Object * dto
Definition: bitmap.c:80
Browser window data.
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.
content_status status
Current status.
Representation of an HTTP parameter.
Definition: parameter.c:31
Handle to low-level cache object.
Definition: llcache.c:76
Parameters for object element and similar elements.
Definition: box.h:164
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
Extra data for some content_msg messages.
Definition: content.h:60
static 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: plot.c:857
static nserror clip(const struct redraw_context *ctx, const struct rect *clip)
Sets a clip rectangle for subsequent plot operations.
Definition: plot.c:357