NetSurf
png.c
Go to the documentation of this file.
1/*
2 * Copyright 2004 James Bursa <bursa@users.sourceforge.net>
3 * Copyright 2004 Richard Wilson <not_ginger_matt@hotmail.com>
4 * Copyright 2008 Daniel Silverstone <dsilvers@netsurf-browser.org>
5 *
6 * This file is part of NetSurf, http://www.netsurf-browser.org/
7 *
8 * NetSurf is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * NetSurf is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <stdbool.h>
22#include <string.h>
23#include <stdlib.h>
24#include <png.h>
25
26#include "netsurf/inttypes.h"
27#include "utils/utils.h"
28#include "utils/log.h"
29#include "utils/messages.h"
30#include "netsurf/bitmap.h"
31#include "content/llcache.h"
35#include "desktop/bitmap.h"
36
37#include "image/image_cache.h"
38#include "image/png.h"
39
40/* accommodate for old versions of libpng (beware security holes!) */
41
42#ifndef png_jmpbuf
43#warning you have an antique libpng
44#define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
45#endif
46
47#if PNG_LIBPNG_VER < 10209
48#define png_set_expand_gray_1_2_4_to_8(png) png_set_gray_1_2_4_to_8(png)
49#endif
50
51typedef struct nspng_content {
52 struct content base; /**< base content type */
53
54 bool no_process_data; /**< Do not continue to process data as it arrives */
55 png_structp png;
56 png_infop info;
58 struct bitmap *bitmap; /**< Created NetSurf bitmap */
59 size_t rowstride, bpp; /**< Bitmap rowstride and bpp */
60 size_t rowbytes; /**< Number of bytes per row */
62
63static unsigned int interlace_start[8] = {0, 16, 0, 8, 0, 4, 0};
64static unsigned int interlace_step[8] = {28, 28, 12, 12, 4, 4, 0};
65static unsigned int interlace_row_start[8] = {0, 0, 4, 0, 2, 0, 1};
66static unsigned int interlace_row_step[8] = {8, 8, 8, 4, 4, 2, 2};
67
68/** Callbak error numbers*/
70 CBERR_NONE = 0, /* no error */
71 CBERR_LIBPNG, /* error from png library */
72 CBERR_NOPRE, /* no pre-conversion performed */
73};
74
75/**
76 * nspng_warning -- callback for libpng warnings
77 */
78static void nspng_warning(png_structp png_ptr, png_const_charp warning_message)
79{
80 NSLOG(netsurf, INFO, "%s", warning_message);
81}
82
83/**
84 * nspng_error -- callback for libpng errors
85 */
86static void nspng_error(png_structp png_ptr, png_const_charp error_message)
87{
88 NSLOG(netsurf, INFO, "%s", error_message);
89 longjmp(png_jmpbuf(png_ptr), CBERR_LIBPNG);
90}
91
92static void nspng_setup_transforms(png_structp png_ptr, png_infop info_ptr)
93{
94 int bit_depth, color_type, intent;
95 double gamma;
96
97 bit_depth = png_get_bit_depth(png_ptr, info_ptr);
98 color_type = png_get_color_type(png_ptr, info_ptr);
99
100 /* Set up our transformations */
101 if (color_type == PNG_COLOR_TYPE_PALETTE) {
102 png_set_palette_to_rgb(png_ptr);
103 }
104
105 if ((color_type == PNG_COLOR_TYPE_GRAY) && (bit_depth < 8)) {
107 }
108
109 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
110 png_set_tRNS_to_alpha(png_ptr);
111 }
112
113 if (bit_depth == 16) {
114 png_set_strip_16(png_ptr);
115 }
116
117 if (color_type == PNG_COLOR_TYPE_GRAY ||
118 color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
119 png_set_gray_to_rgb(png_ptr);
120 }
121
122 switch (bitmap_fmt.layout) {
123 case BITMAP_LAYOUT_B8G8R8A8: /* Fall through. */
125 png_set_bgr(png_ptr);
126 break;
127 default:
128 /* RGB is the default. */
129 break;
130 }
131
132 if (!(color_type & PNG_COLOR_MASK_ALPHA)) {
133 switch (bitmap_fmt.layout) {
134 case BITMAP_LAYOUT_A8R8G8B8: /* Fall through. */
136 png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
137 break;
138
139 default:
140 png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
141 break;
142 }
143 } else {
144 switch (bitmap_fmt.layout) {
145 case BITMAP_LAYOUT_A8R8G8B8: /* Fall through. */
147 png_set_swap_alpha(png_ptr);
148 break;
149 default:
150 /* Alpha as final component is the default. */
151 break;
152 }
153 }
154
155 /* gamma correction - we use 2.2 as our screen gamma
156 * this appears to be correct (at least in respect to !Browse)
157 * see http://www.w3.org/Graphics/PNG/all_seven.html for a test case
158 */
159 if (png_get_sRGB(png_ptr, info_ptr, &intent)) {
160 png_set_gamma(png_ptr, 2.2, 0.45455);
161 } else {
162 if (png_get_gAMA(png_ptr, info_ptr, &gamma)) {
163 png_set_gamma(png_ptr, 2.2, gamma);
164 } else {
165 png_set_gamma(png_ptr, 2.2, 0.45455);
166 }
167 }
168
169 png_read_update_info(png_ptr, info_ptr);
170}
171
172/**
173 * info_callback -- PNG header has been completely received, prepare to process
174 * image data
175 */
176static void info_callback(png_structp png_s, png_infop info)
177{
178 int interlace;
179 png_uint_32 width, height;
180 nspng_content *png_c = png_get_progressive_ptr(png_s);
181
182 width = png_get_image_width(png_s, info);
183 height = png_get_image_height(png_s, info);
184 interlace = png_get_interlace_type(png_s, info);
185
186 png_c->base.width = width;
187 png_c->base.height = height;
188 png_c->base.size += width * height * 4;
189
190 /* see if progressive-conversion should continue */
191 if (image_cache_speculate((struct content *)png_c) == false) {
192 longjmp(png_jmpbuf(png_s), CBERR_NOPRE);
193 }
194
195 /* Claim the required memory for the converted PNG */
197 if (png_c->bitmap == NULL) {
198 /* Failed to create bitmap skip pre-conversion */
199 longjmp(png_jmpbuf(png_s), CBERR_NOPRE);
200 }
201
202 png_c->rowstride = guit->bitmap->get_rowstride(png_c->bitmap);
203 png_c->bpp = sizeof(uint32_t);
204
205 nspng_setup_transforms(png_s, info);
206
207 png_c->rowbytes = png_get_rowbytes(png_s, info);
208 png_c->interlace = (interlace == PNG_INTERLACE_ADAM7);
209
210 NSLOG(netsurf, INFO, "size %li * %li, rowbytes %"PRIsizet,
211 (unsigned long)width, (unsigned long)height, png_c->rowbytes);
212}
213
214static void row_callback(png_structp png_s, png_bytep new_row,
215 png_uint_32 row_num, int pass)
216{
217 nspng_content *png_c = png_get_progressive_ptr(png_s);
218 unsigned long rowbytes = png_c->rowbytes;
219 unsigned char *buffer, *row;
220
221 /* Give up if there's no bitmap */
222 if (png_c->bitmap == NULL)
223 return;
224
225 /* Abort if we've not got any data */
226 if (new_row == NULL)
227 return;
228
229 /* Get bitmap buffer */
230 buffer = guit->bitmap->get_buffer(png_c->bitmap);
231 if (buffer == NULL) {
232 /* No buffer, bail out */
233 longjmp(png_jmpbuf(png_s), 1);
234 }
235
236 /* Calculate address of row start */
237 row = buffer + (png_c->rowstride * row_num);
238
239 /* Handle interlaced sprites using the Adam7 algorithm */
240 if (png_c->interlace) {
241 unsigned long dst_off;
242 unsigned long src_off = 0;
243 unsigned int start, step;
244
245 start = interlace_start[pass];
246 step = interlace_step[pass];
247 row_num = interlace_row_start[pass] +
248 interlace_row_step[pass] * row_num;
249
250 /* Copy the data to our current row taking interlacing
251 * into consideration */
252 row = buffer + (png_c->rowstride * row_num);
253
254 for (dst_off = start; dst_off < rowbytes; dst_off += step) {
255 row[dst_off++] = new_row[src_off++];
256 row[dst_off++] = new_row[src_off++];
257 row[dst_off++] = new_row[src_off++];
258 row[dst_off++] = new_row[src_off++];
259 }
260 } else {
261 /* Do a fast memcpy of the row data */
262 memcpy(row, new_row, rowbytes);
263 }
264}
265
266
267static void end_callback(png_structp png_s, png_infop info)
268{
269}
270
272{
273 png_c->bitmap = NULL;
274
275 png_c->png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
276 if (png_c->png == NULL) {
278 return NSERROR_NOMEM;
279 }
280
281 png_set_error_fn(png_c->png, NULL, nspng_error, nspng_warning);
282
283 png_c->info = png_create_info_struct(png_c->png);
284 if (png_c->info == NULL) {
285 png_destroy_read_struct(&png_c->png, &png_c->info, 0);
286
288 return NSERROR_NOMEM;
289 }
290
291 if (setjmp(png_jmpbuf(png_c->png))) {
292 png_destroy_read_struct(&png_c->png, &png_c->info, 0);
293 NSLOG(netsurf, INFO, "Failed to set callbacks");
294 png_c->png = NULL;
295 png_c->info = NULL;
296
298 return NSERROR_NOMEM;
299 }
300
301 png_set_progressive_read_fn(png_c->png, png_c,
303
304 return NSERROR_OK;
305}
306
307static nserror
309 lwc_string *imime_type,
310 const struct http_parameter *params,
311 struct llcache_handle *llcache,
312 const char *fallback_charset,
313 bool quirks,
314 struct content **c)
315{
316 nspng_content *png_c;
317 nserror error;
318
319 png_c = calloc(1, sizeof(nspng_content));
320 if (png_c == NULL)
321 return NSERROR_NOMEM;
322
323 error = content__init(&png_c->base,
324 handler,
325 imime_type,
326 params,
327 llcache,
328 fallback_charset,
329 quirks);
330 if (error != NSERROR_OK) {
331 free(png_c);
332 return error;
333 }
334
335 error = nspng_create_png_data(png_c);
336 if (error != NSERROR_OK) {
337 free(png_c);
338 return error;
339 }
340
341 *c = (struct content *)png_c;
342
343 return NSERROR_OK;
344}
345
346
347static bool nspng_process_data(struct content *c, const char *data,
348 unsigned int size)
349{
350 nspng_content *png_c = (nspng_content *)c;
351 volatile bool ret = true;
352
353 if (png_c->no_process_data) {
354 return ret;
355 }
356
357 switch (setjmp(png_jmpbuf(png_c->png))) {
358 case CBERR_NONE: /* direct return */
359 png_process_data(png_c->png, png_c->info, (uint8_t *)data, size);
360 break;
361
362 case CBERR_NOPRE: /* not going to progressive convert */
363 png_c->no_process_data = true;
364 break;
365
366 default: /* fatal error from library processing png */
367 if (png_c->bitmap != NULL) {
368 /* A bitmap managed to get created so
369 * operation is past header and possibly some
370 * conversion happened before faliure.
371 *
372 * In this case keep the partial
373 * conversion. This is usually seen if a png
374 * has been truncated (often jsut lost its
375 * last byte and hence end of image marker)
376 */
377 png_c->no_process_data = true;
378 } else {
379 /* not managed to progress past header, clean
380 * up png conversion and signal the content
381 * error
382 */
383 NSLOG(netsurf, INFO,
384 "Fatal PNG error during header, error content");
385
386 png_destroy_read_struct(&png_c->png, &png_c->info, 0);
387 png_c->png = NULL;
388 png_c->info = NULL;
389
391
392 ret = false;
393
394 }
395 break;
396 }
397
398 return ret;
399}
400
402 const uint8_t *data;
403 size_t size;
404};
405
406/** PNG library read fucntion to read data from a memory array
407 */
408static void
409png_cache_read_fn(png_structp png_ptr, png_bytep data, png_size_t length)
410{
411 struct png_cache_read_data_s *png_cache_read_data;
412 png_cache_read_data = png_get_io_ptr(png_ptr);
413
414 if (length > png_cache_read_data->size) {
415 length = png_cache_read_data->size;
416 }
417
418 if (length == 0) {
419 png_error(png_ptr, "Read Error");
420 }
421
422 memcpy(data, png_cache_read_data->data, length);
423
424 png_cache_read_data->data += length;
425 png_cache_read_data->size -= length;
426}
427
428/** calculate an array of row pointers into a bitmap data area
429 */
430static png_bytep *calc_row_pointers(struct bitmap *bitmap)
431{
433 unsigned char *buffer= guit->bitmap->get_buffer(bitmap);
434 size_t rowstride = guit->bitmap->get_rowstride(bitmap);
435 png_bytep *row_ptrs;
436 int hloop;
437
438 /* The buffer allocation may occour when the buffer is aquired
439 * and therefore may fail.
440 */
441 if (buffer == NULL) {
442 return NULL;
443 }
444
445 row_ptrs = malloc(sizeof(png_bytep) * height);
446
447 if (row_ptrs != NULL) {
448 for (hloop = 0; hloop < height; hloop++) {
449 row_ptrs[hloop] = buffer + (rowstride * hloop);
450 }
451 }
452
453 return row_ptrs;
454}
455
456/** PNG content to bitmap conversion.
457 *
458 * This routine generates a bitmap object from a PNG image content
459 */
460static struct bitmap *
462{
463 png_structp png_ptr;
464 png_infop info_ptr;
465 png_infop end_info_ptr;
466 volatile struct bitmap * volatile bitmap = NULL;
467 struct png_cache_read_data_s png_cache_read_data;
468 png_uint_32 width, height;
469 volatile png_bytep * volatile row_pointers = NULL;
470
471 png_cache_read_data.data =
472 content__get_source_data(c, &png_cache_read_data.size);
473
474 if ((png_cache_read_data.data == NULL) ||
475 (png_cache_read_data.size <= 8)) {
476 return NULL;
477 }
478
479 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
481 if (png_ptr == NULL) {
482 return NULL;
483 }
484
485 info_ptr = png_create_info_struct(png_ptr);
486 if (info_ptr == NULL) {
487 png_destroy_read_struct(&png_ptr, NULL, NULL);
488 return NULL;
489 }
490
491 end_info_ptr = png_create_info_struct(png_ptr);
492 if (end_info_ptr == NULL) {
493 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
494 return NULL;
495 }
496
497 /* setup error exit path */
498 if (setjmp(png_jmpbuf(png_ptr))) {
499 /* cleanup and bail */
500 goto png_cache_convert_error;
501 }
502
503 /* read from a buffer instead of stdio */
504 png_set_read_fn(png_ptr, &png_cache_read_data, png_cache_read_fn);
505
506 /* ensure the png info structure is populated */
507 png_read_info(png_ptr, info_ptr);
508
509 /* setup output transforms */
510 nspng_setup_transforms(png_ptr, info_ptr);
511
512 width = png_get_image_width(png_ptr, info_ptr);
513 height = png_get_image_height(png_ptr, info_ptr);
514
515 /* Claim the required memory for the converted PNG */
517 if (bitmap == NULL) {
518 /* cleanup and bail */
519 goto png_cache_convert_error;
520 }
521
522 row_pointers = calc_row_pointers((struct bitmap *) bitmap);
523
524 if (row_pointers != NULL) {
525 png_read_image(png_ptr, (png_bytep *) row_pointers);
526 } else {
527 guit->bitmap->destroy((struct bitmap *)bitmap);
528 bitmap = NULL;
529 }
530
531png_cache_convert_error:
532
533 /* cleanup png read */
534 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr);
535
536 if (row_pointers != NULL) {
537 free((png_bytep *) row_pointers);
538 }
539
540 if (bitmap != NULL) {
541 bool opaque = bitmap_test_opaque((void *)bitmap);
542 guit->bitmap->set_opaque((void *)bitmap, opaque);
544 .layout = bitmap_fmt.layout,
545 .pma = opaque ? bitmap_fmt.pma : false,
546 });
547 guit->bitmap->modified((void *)bitmap);
548 }
549
550 return (struct bitmap *)bitmap;
551}
552
553static bool nspng_convert(struct content *c)
554{
555 nspng_content *png_c = (nspng_content *) c;
556 char *title;
557
558 assert(png_c->png != NULL);
559 assert(png_c->info != NULL);
560
561 /* clean up png structures */
562 png_destroy_read_struct(&png_c->png, &png_c->info, 0);
563
564 /* set title text */
565 title = messages_get_buff("PNGTitle",
567 c->width, c->height);
568 if (title != NULL) {
569 content__set_title(c, title);
570 free(title);
571 }
572
573 if (png_c->bitmap != NULL) {
574 bool opaque = bitmap_test_opaque(png_c->bitmap);
575 guit->bitmap->set_opaque(png_c->bitmap, opaque);
577 .layout = bitmap_fmt.layout,
578 .pma = opaque ? bitmap_fmt.pma : false,
579 });
580 guit->bitmap->modified(png_c->bitmap);
581 }
582
584
587 content_set_status(c, "");
588
589 return true;
590}
591
592
593static nserror nspng_clone(const struct content *old_c, struct content **new_c)
594{
595 nspng_content *clone_png_c;
596 nserror error;
597 const uint8_t *data;
598 size_t size;
599
600 clone_png_c = calloc(1, sizeof(nspng_content));
601 if (clone_png_c == NULL)
602 return NSERROR_NOMEM;
603
604 error = content__clone(old_c, &clone_png_c->base);
605 if (error != NSERROR_OK) {
606 content_destroy(&clone_png_c->base);
607 return error;
608 }
609
610 /* Simply replay create/process/convert */
611 error = nspng_create_png_data(clone_png_c);
612 if (error != NSERROR_OK) {
613 content_destroy(&clone_png_c->base);
614 return error;
615 }
616
617 data = content__get_source_data(&clone_png_c->base, &size);
618 if (size > 0) {
619 if (nspng_process_data(&clone_png_c->base, (const char *)data, size) == false) {
620 content_destroy(&clone_png_c->base);
621 return NSERROR_NOMEM;
622 }
623 }
624
625 if ((old_c->status == CONTENT_STATUS_READY) ||
626 (old_c->status == CONTENT_STATUS_DONE)) {
627 if (nspng_convert(&clone_png_c->base) == false) {
628 content_destroy(&clone_png_c->base);
630 }
631 }
632
633 *new_c = (struct content *)clone_png_c;
634
635 return NSERROR_OK;
636}
637
640 .process_data = nspng_process_data,
641 .data_complete = nspng_convert,
642 .clone = nspng_clone,
643 .destroy = image_cache_destroy,
644 .redraw = image_cache_redraw,
645 .get_internal = image_cache_get_internal,
647 .is_opaque = image_cache_is_opaque,
648 .no_share = false,
649};
650
651static const char *nspng_types[] = {
652 "image/png",
653 "image/x-png"
654};
655
static osspriteop_area * buffer
The buffer characteristics.
Definition: buffer.c:55
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
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_PNG_ERROR
A PNG error occurred.
Definition: errors.h:42
@ 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:50
Interface to core interface table.
content_type image_cache_content_type(void)
Definition: image_cache.c:873
void * image_cache_get_internal(const struct content *c, void *context)
Definition: image_cache.c:856
bool image_cache_redraw(struct content *c, struct content_redraw_data *data, const struct rect *clip, const struct redraw_context *ctx)
Generic content redraw callback.
Definition: image_cache.c:798
bool image_cache_speculate(struct content *c)
Decide if a content should be speculatively converted.
Definition: image_cache.c:377
void image_cache_destroy(struct content *content)
Definition: image_cache.c:841
nserror image_cache_add(struct content *content, struct bitmap *bitmap, image_cache_convert_fn *convert)
adds an image content to be cached.
Definition: image_cache.c:510
bool image_cache_is_opaque(struct content *c)
Definition: image_cache.c:862
The image content handler intermediate image cache.
Generic bitmap handling interface.
bool bitmap_test_opaque(void *bitmap)
Test whether a bitmap is completely opaque (no transparency).
Definition: bitmap.c:316
@ BITMAP_NONE
Definition: bitmap.h:37
@ BITMAP_LAYOUT_B8G8R8A8
Bite-wise BGRA: Byte order: 0xBB, 0xGG, 0xRR, 0xAA.
Definition: bitmap.h:53
@ BITMAP_LAYOUT_A8B8G8R8
Bite-wise ABGR: Byte order: 0xAA, 0xBB, 0xGG, 0xRR.
Definition: bitmap.h:59
@ BITMAP_LAYOUT_A8R8G8B8
Bite-wise ARGB: Byte order: 0xAA, 0xRR, 0xGG, 0xBB.
Definition: bitmap.h:56
Netsurf additional integer type formatting macros.
#define PRIsizet
c99 standard printf formatting for size_t type
Definition: inttypes.h:53
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)
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
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.
static void nspng_error(png_structp png_ptr, png_const_charp error_message)
nspng_error – callback for libpng errors
Definition: png.c:86
static unsigned int interlace_row_start[8]
Definition: png.c:65
static void end_callback(png_structp png_s, png_infop info)
Definition: png.c:267
CONTENT_FACTORY_REGISTER_TYPES(nspng, nspng_types, nspng_content_handler)
struct nspng_content nspng_content
static void png_cache_read_fn(png_structp png_ptr, png_bytep data, png_size_t length)
PNG library read fucntion to read data from a memory array.
Definition: png.c:409
static const content_handler nspng_content_handler
Definition: png.c:638
static nserror nspng_create_png_data(nspng_content *png_c)
Definition: png.c:271
static unsigned int interlace_start[8]
Definition: png.c:63
static const char * nspng_types[]
Definition: png.c:651
nspng_cberr
Callbak error numbers.
Definition: png.c:69
@ CBERR_NONE
Definition: png.c:70
@ CBERR_LIBPNG
Definition: png.c:71
@ CBERR_NOPRE
Definition: png.c:72
#define png_jmpbuf(png_ptr)
Definition: png.c:44
#define png_set_expand_gray_1_2_4_to_8(png)
Definition: png.c:48
static nserror nspng_create(const 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)
Definition: png.c:308
static void row_callback(png_structp png_s, png_bytep new_row, png_uint_32 row_num, int pass)
Definition: png.c:214
static void nspng_warning(png_structp png_ptr, png_const_charp warning_message)
nspng_warning – callback for libpng warnings
Definition: png.c:78
static png_bytep * calc_row_pointers(struct bitmap *bitmap)
calculate an array of row pointers into a bitmap data area
Definition: png.c:430
static void info_callback(png_structp png_s, png_infop info)
info_callback – PNG header has been completely received, prepare to process image data
Definition: png.c:176
static unsigned int interlace_step[8]
Definition: png.c:64
static struct bitmap * png_cache_convert(struct content *c)
PNG content to bitmap conversion.
Definition: png.c:461
static unsigned int interlace_row_step[8]
Definition: png.c:66
static void nspng_setup_transforms(png_structp png_ptr, png_infop info_ptr)
Definition: png.c:92
static nserror nspng_clone(const struct content *old_c, struct content **new_c)
Definition: png.c:593
static bool nspng_convert(struct content *c)
Definition: png.c:553
static bool nspng_process_data(struct content *c, const char *data, unsigned int size)
Definition: png.c:347
int width
Definition: gui.c:160
int height
Definition: gui.c:161
Interface to utility string handling.
Bitmap format specifier.
Definition: bitmap.h:95
bool pma
Premultiplied alpha.
Definition: bitmap.h:97
enum bitmap_layout layout
Colour component layout.
Definition: bitmap.h:96
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)
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.
content_status status
Current status.
unsigned int size
Estimated size of all data associated with this content.
void(* set_opaque)(void *bitmap, bool opaque)
Set the opacity of a bitmap.
Definition: bitmap.h:151
int(* get_height)(void *bitmap)
Get the bitmap height.
Definition: bitmap.h:193
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
size_t(* get_rowstride)(void *bitmap)
Get the number of bytes per row of the image.
Definition: bitmap.h:177
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:153
size_t rowbytes
Number of bytes per row.
Definition: png.c:60
png_structp png
Definition: png.c:55
bool no_process_data
Do not continue to process data as it arrives.
Definition: png.c:54
struct bitmap * bitmap
Created NetSurf bitmap.
Definition: png.c:58
int interlace
Definition: png.c:57
struct content base
base content type
Definition: png.c:52
png_infop info
Definition: png.c:56
size_t bpp
Bitmap rowstride and bpp.
Definition: png.c:59
size_t rowstride
Definition: png.c:59
const uint8_t * data
Definition: png.c:402
Interface to a number of general purpose functionality.
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