r9581 jmb - in /trunk/libnspng/src: internal.h liblzf/lzf.h liblzf/lzfP.h pngread.c
by netsurf@semichrome.net
Author: jmb
Date: Wed Sep 16 06:09:08 2009
New Revision: 9581
URL: http://source.netsurf-browser.org?rev=9581&view=rev
Log:
Provide the hashtable for lzf_compress to use. This means it actually gets initialised, and avoids the performance cost of creating and initialising it for every compression call.
Modified:
trunk/libnspng/src/internal.h
trunk/libnspng/src/liblzf/lzf.h
trunk/libnspng/src/liblzf/lzfP.h
trunk/libnspng/src/pngread.c
Modified: trunk/libnspng/src/internal.h
URL: http://source.netsurf-browser.org/trunk/libnspng/src/internal.h?rev=9581&...
==============================================================================
--- trunk/libnspng/src/internal.h (original)
+++ trunk/libnspng/src/internal.h Wed Sep 16 06:09:08 2009
@@ -13,6 +13,8 @@
#include <stdint.h>
#include <libnspng.h>
+
+#include "liblzf/lzf.h"
typedef enum nspng_state {
STATE_START,
@@ -151,6 +153,8 @@
z_stream zlib_stream;
+ LZF_STATE lzf_htab;
+
nspng_chunk chunk;
nspng_image image;
Modified: trunk/libnspng/src/liblzf/lzf.h
URL: http://source.netsurf-browser.org/trunk/libnspng/src/liblzf/lzf.h?rev=958...
==============================================================================
--- trunk/libnspng/src/liblzf/lzf.h (original)
+++ trunk/libnspng/src/liblzf/lzf.h Wed Sep 16 06:09:08 2009
@@ -49,6 +49,22 @@
#define LZF_VERSION 0x0105 /* 1.5, API version */
/*
+ * Size of hashtable is (1 << HLOG) * sizeof (char *)
+ * decompression is independent of the hash table size
+ * the difference between 15 and 14 is very small
+ * for small blocks (and 14 is usually a bit faster).
+ * For a low-memory/faster configuration, use HLOG == 13;
+ * For best compression, use 15 or 16 (or more, up to 23).
+ */
+#ifndef HLOG
+# define HLOG 16
+#endif
+
+typedef unsigned char u8;
+
+typedef const u8 *LZF_STATE[1 << (HLOG)];
+
+/*
* Compress in_len bytes stored at the memory block starting at
* in_data and write the result to out_data, up to a maximum length
* of out_len bytes.
@@ -75,7 +91,8 @@
*/
unsigned int
lzf_compress (const void *const in_data, unsigned int in_len,
- void *out_data, unsigned int out_len);
+ void *out_data, unsigned int out_len,
+ LZF_STATE htab);
/*
* Decompress data compressed with some version of the lzf_compress
Modified: trunk/libnspng/src/liblzf/lzfP.h
URL: http://source.netsurf-browser.org/trunk/libnspng/src/liblzf/lzfP.h?rev=95...
==============================================================================
--- trunk/libnspng/src/liblzf/lzfP.h (original)
+++ trunk/libnspng/src/liblzf/lzfP.h Wed Sep 16 06:09:08 2009
@@ -106,7 +106,7 @@
* NOTE: this breaks the prototype in lzf.h.
*/
#ifndef LZF_STATE_ARG
-# define LZF_STATE_ARG 0
+# define LZF_STATE_ARG 1
#endif
/*
@@ -123,10 +123,6 @@
/*****************************************************************************/
/* nothing should be changed below */
-
-typedef unsigned char u8;
-
-typedef const u8 *LZF_STATE[1 << (HLOG)];
#if !STRICT_ALIGN
/* for unaligned accesses we need a 16 bit datatype. */
Modified: trunk/libnspng/src/pngread.c
URL: http://source.netsurf-browser.org/trunk/libnspng/src/pngread.c?rev=9581&r...
==============================================================================
--- trunk/libnspng/src/pngread.c (original)
+++ trunk/libnspng/src/pngread.c Wed Sep 16 06:09:08 2009
@@ -14,8 +14,6 @@
#include <libnspng.h>
#include "internal.h"
-
-#include "liblzf/lzf.h"
typedef enum nspng_chunk_type {
CHUNK_IHDR = ('I' << 24) | ('H' << 16) | ('D' << 8) | 'R',
@@ -539,7 +537,8 @@
written = lzf_compress(src_scanline,
bps,
image->data + image->data_len,
- bps - 1);
+ bps - 1,
+ ctx->lzf_htab);
if (written == 0) {
/* Would be larger - use uncompressed */
memcpy(image->data + image->data_len,
13 years, 6 months
r9577 chris_y - in /trunk/netsurf/amiga: gui.c gui.h
by netsurf@semichrome.net
Author: chris_y
Date: Tue Sep 15 17:49:33 2009
New Revision: 9577
URL: http://source.netsurf-browser.org?rev=9577&view=rev
Log:
Modify bottom border status gadget so that it has a frame. When the gadget is
refreshed now it will erase the gadget area before redrawing, allowing to use
RefreshGList instead of RefreshWindowFrame. This is significantly faster as
RefreshWindowFrame redraws more than the function name suggests.
Modified:
trunk/netsurf/amiga/gui.c
trunk/netsurf/amiga/gui.h
Modified: trunk/netsurf/amiga/gui.c
URL: http://source.netsurf-browser.org/trunk/netsurf/amiga/gui.c?rev=9577&r1=9...
==============================================================================
--- trunk/netsurf/amiga/gui.c (original)
+++ trunk/netsurf/amiga/gui.c Tue Sep 15 17:49:33 2009
@@ -2172,11 +2172,29 @@
GA_Width, size1,
GA_DrawInfo, dri,
GA_BottomBorder, TRUE,
+ GA_ReadOnly, TRUE,
+ GA_Image, (struct Image *)NewObject(
+ NULL,
+ "frameiclass",
+ IA_FrameType, FRAME_DISPLAY,
+ IA_Simple, TRUE,
+ IA_Top, -(scrn->RastPort.TxHeight),
+ IA_Left, -1,
+ IA_Height, 1 + scrn->WBorBottom + scrn->RastPort.TxHeight,
+ IA_InBorder, TRUE,
+ TAG_DONE),
GA_Next, gwin->shared->gadgets[GID_HSCROLL],
TAG_DONE);
AddGList(gwin->shared->win, gwin->shared->gadgets[GID_STATUS],
(UWORD)~0, -1, NULL);
+
+ /* Apparently you can't set GA_Width on creation time for frbuttonclass */
+
+ SetGadgetAttrs(gwin->shared->gadgets[GID_STATUS],
+ gwin->shared->win, NULL,
+ GA_Width, size1,
+ TAG_DONE);
RefreshGadgets((APTR)gwin->shared->gadgets[GID_STATUS],
gwin->shared->win, NULL);
@@ -2223,7 +2241,7 @@
GA_Width, size1,
TAG_DONE);
- RefreshWindowFrame(gwin->win);
+ RefreshGList(gwin->gadgets[GID_STATUS], gwin->win, NULL, 2);
}
ULONG ami_get_border_gadget_balance(struct gui_window_2 *gwin, ULONG *size1, ULONG *size2)
@@ -2243,8 +2261,8 @@
gad1percent = option_toolbar_status_width / 10000.0;
- *size1 = (ULONG)available_width * gad1percent;
- *size2 = (ULONG)available_width * (1 - gad1percent);
+ *size1 = (ULONG)(available_width * gad1percent);
+ *size2 = (ULONG)(available_width * (1 - gad1percent));
return sz;
}
@@ -2348,34 +2366,39 @@
{
struct Node *node;
ULONG cur_tab = 0;
- STRPTR newtitle = NULL;
+ char *utf8title;
if(!g) return;
+ if(!title) return;
if(g->tab_node)
{
- node = g->tab_node;
-
- SetGadgetAttrs(g->shared->gadgets[GID_TABS],g->shared->win,NULL,
- CLICKTAB_Labels,~0,
- TAG_DONE);
- newtitle = ami_utf8_easy((char *)title);
- SetClickTabNodeAttrs(node,TNA_Text,newtitle,TAG_DONE);
- if(newtitle) ami_utf8_free(newtitle);
- RefreshSetGadgetAttrs(g->shared->gadgets[GID_TABS],g->shared->win,NULL,
- CLICKTAB_Labels,&g->shared->tab_list,
- TAG_DONE);
-
- if(ClickTabBase->lib_Version < 53)
- RethinkLayout(g->shared->gadgets[GID_TABLAYOUT],g->shared->win,NULL,TRUE);
-
- GetAttr(CLICKTAB_Current,g->shared->gadgets[GID_TABS],(ULONG *)&cur_tab);
- }
-
- if((cur_tab == g->tab) || (g->shared->tabs == 0))
- {
- if(g->shared->win->Title) ami_utf8_free(g->shared->win->Title);
- SetWindowTitles(g->shared->win,ami_utf8_easy((char *)title),nsscreentitle);
+ utf8title = ami_utf8_easy((char *)title);
+
+ if((g->shared->wintitle == NULL) || (strcmp(utf8title, g->shared->wintitle)))
+ {
+ node = g->tab_node;
+
+ SetGadgetAttrs(g->shared->gadgets[GID_TABS],g->shared->win,NULL,
+ CLICKTAB_Labels,~0,
+ TAG_DONE);
+ if(g->shared->wintitle) ami_utf8_free(g->shared->wintitle);
+ g->shared->wintitle = utf8title;
+ SetClickTabNodeAttrs(node,TNA_Text, g->shared->wintitle, TAG_DONE);
+ RefreshSetGadgetAttrs(g->shared->gadgets[GID_TABS],g->shared->win,NULL,
+ CLICKTAB_Labels,&g->shared->tab_list,
+ TAG_DONE);
+
+ if(ClickTabBase->lib_Version < 53)
+ RethinkLayout(g->shared->gadgets[GID_TABLAYOUT],g->shared->win,NULL,TRUE);
+
+ GetAttr(CLICKTAB_Current,g->shared->gadgets[GID_TABS],(ULONG *)&cur_tab);
+
+ if((cur_tab == g->tab) || (g->shared->tabs == 0))
+ {
+ SetWindowTitles(g->shared->win, g->shared->wintitle, nsscreentitle);
+ }
+ }
}
}
@@ -2802,7 +2825,7 @@
GA_Text, utf8text,
TAG_DONE);
- RefreshWindowFrame(g->shared->win);
+ RefreshGList(g->shared->gadgets[GID_STATUS],g->shared->win,NULL,1);
if(g->shared->status) ami_utf8_free(g->shared->status);
g->shared->status = utf8text;
Modified: trunk/netsurf/amiga/gui.h
URL: http://source.netsurf-browser.org/trunk/netsurf/amiga/gui.h?rev=9577&r1=9...
==============================================================================
--- trunk/netsurf/amiga/gui.h (original)
+++ trunk/netsurf/amiga/gui.h Tue Sep 15 17:49:33 2009
@@ -100,6 +100,7 @@
bool new_content;
char *svbuffer;
char *status;
+ char *wintitle;
};
struct gui_window
13 years, 6 months
r9576 jmb - /trunk/libnspng/src/pngrender.c
by netsurf@semichrome.net
Author: jmb
Date: Tue Sep 15 14:34:15 2009
New Revision: 9576
URL: http://source.netsurf-browser.org?rev=9576&view=rev
Log:
Optimise redraw for non-interlaced, non-paletted, 8bpc images.
Modified:
trunk/libnspng/src/pngrender.c
Modified: trunk/libnspng/src/pngrender.c
URL: http://source.netsurf-browser.org/trunk/libnspng/src/pngrender.c?rev=9576...
==============================================================================
--- trunk/libnspng/src/pngrender.c (original)
+++ trunk/libnspng/src/pngrender.c Tue Sep 15 14:34:15 2009
@@ -83,8 +83,8 @@
}
}
-static void process_scanline(nspng_ctx *ctx, const uint8_t *data, uint32_t len,
- uint32_t pass, uint8_t *rowbuf)
+static void process_scanline_slow(nspng_ctx *ctx, const uint8_t *data,
+ uint32_t len, uint32_t pass, uint8_t *rowbuf)
{
/* LUTs for interlacing */
/* Byte offsets for initial pixel in pass N */
@@ -101,8 +101,9 @@
const uint32_t step = pix_step[pass];
uint8_t *curpix = rowbuf + pix_init[pass];
uint32_t bytes_read_for_pixel = 0;
-
- for (uint32_t byte = 0; byte < len; byte++) {
+ uint32_t byte;
+
+ for (byte = 0; byte < len; byte++) {
/* Reconstruct original byte value */
const uint8_t x = data[byte];
@@ -154,6 +155,49 @@
}
}
+static void process_scanline(nspng_ctx *ctx, const uint8_t *data, uint32_t len,
+ uint32_t pass, uint8_t *rowbuf)
+{
+ const uint32_t colour_type = ctx->image.colour_type;
+ uint32_t byte;
+
+ /* Optimise for non-interlaced, non-paletted, 8bpc scanlines */
+ if (pass == 6 && ctx->image.bit_depth == 8 &&
+ colour_type != COLOUR_TYPE_INDEXED) {
+ if (colour_type == COLOUR_TYPE_RGBA) {
+ memcpy(rowbuf, data, len);
+ } else if (colour_type == COLOUR_TYPE_GREY_A) {
+ for (byte = 0; byte < len - 1; byte += 2) {
+ const uint8_t g = data[byte + 0];
+
+ *rowbuf++ = g;
+ *rowbuf++ = g;
+ *rowbuf++ = g;
+ *rowbuf++ = data[byte + 1];
+ }
+ } else if (colour_type == COLOUR_TYPE_RGB) {
+ for (byte = 0; byte < len - 2; byte += 3) {
+ *rowbuf++ = data[byte + 0];
+ *rowbuf++ = data[byte + 1];
+ *rowbuf++ = data[byte + 2];
+ *rowbuf++ = 0xff;
+ }
+ } else if (colour_type == COLOUR_TYPE_GREY) {
+ for (byte = 0; byte < len; byte++) {
+ const uint8_t g = data[byte];
+
+ *rowbuf++ = g;
+ *rowbuf++ = g;
+ *rowbuf++ = g;
+ *rowbuf++ = 0xff;
+ }
+ }
+ } else {
+ /* Fall back to the slow code for the unhelpful cases */
+ process_scanline_slow(ctx, data, len, pass, rowbuf);
+ }
+}
+
/******************************************************************************
* Public API *
******************************************************************************/
13 years, 6 months
r9575 jmb - /trunk/libnspng/src/pngread.c
by netsurf@semichrome.net
Author: jmb
Date: Tue Sep 15 13:27:50 2009
New Revision: 9575
URL: http://source.netsurf-browser.org?rev=9575&view=rev
Log:
Reduce calls to allocator.
If the filter for this scanline is NONE, then just use memcpy
Modified:
trunk/libnspng/src/pngread.c
Modified: trunk/libnspng/src/pngread.c
URL: http://source.netsurf-browser.org/trunk/libnspng/src/pngread.c?rev=9575&r...
==============================================================================
--- trunk/libnspng/src/pngread.c (original)
+++ trunk/libnspng/src/pngread.c Tue Sep 15 13:27:50 2009
@@ -448,8 +448,6 @@
nspng_adaptive_filter_type filter = ctx->scanline_filter;
uint32_t max_idx;
uint32_t i;
- int32_t aidx;
- uint32_t ppidx;
/* Clamp maximum bytes to that remaining for this scanline */
if (avail > bytes_remaining)
@@ -465,55 +463,57 @@
brfs++;
}
- /* Calculate initial indices for a and c */
- aidx = (int32_t) (brfs - 1 - fbo);
- ppidx = (brfs - 1) % fbo;
-
- /* Process remaining bytes, starting where we left off */
- for (i = brfs - 1; i < max_idx; i++) {
- uint32_t a, x = *(data++);
-
- /* Safe, as scanline points fbo bytes into scanline
- * buffer, buffer is fbo bytes oversized, and the
- * first fbo bytes are zero */
- a = src_scanline[aidx++];
-
- /* Reconstruct original byte value */
- if (filter == ADAPTIVE_FILTER_NONE) {
- /* Nothing to do */
- } else if (filter == ADAPTIVE_FILTER_SUB) {
- x += a;
- } else if (filter == ADAPTIVE_FILTER_UP) {
- uint32_t b = src_scanline[i];
- x += b;
- } else if (filter == ADAPTIVE_FILTER_AVERAGE) {
- uint32_t b = src_scanline[i];
- x += ((a + b) >> 1);
- } else if (filter == ADAPTIVE_FILTER_PAETH) {
- uint32_t b = src_scanline[i];
- uint32_t c = ppixel[ppidx];
- uint32_t p = a + b - c;
- uint32_t pa = abs(p - a);
- uint32_t pb = abs(p - b);
- uint32_t pc = abs(p - c);
-
- if (pa <= pb && pa <= pc) {
+ if (filter == ADAPTIVE_FILTER_NONE) {
+ memcpy(src_scanline + brfs - 1, data, avail - 1);
+ } else {
+ /* Calculate initial indices for a and c */
+ int32_t aidx = (int32_t) (brfs - 1 - fbo);
+ uint32_t ppidx = (brfs - 1) % fbo;
+
+ /* Process remaining bytes, starting where we left off */
+ for (i = brfs - 1; i < max_idx; i++) {
+ uint32_t a, x = *(data++);
+
+ /* Safe, as scanline points fbo bytes into scanline
+ * buffer, buffer is fbo bytes oversized, and the
+ * first fbo bytes are zero */
+ a = src_scanline[aidx++];
+
+ /* Reconstruct original byte value */
+ if (filter == ADAPTIVE_FILTER_SUB) {
x += a;
- } else if (pb <= pc) {
+ } else if (filter == ADAPTIVE_FILTER_UP) {
+ uint32_t b = src_scanline[i];
x += b;
- } else {
- x += c;
+ } else if (filter == ADAPTIVE_FILTER_AVERAGE) {
+ uint32_t b = src_scanline[i];
+ x += ((a + b) >> 1);
+ } else if (filter == ADAPTIVE_FILTER_PAETH) {
+ uint32_t b = src_scanline[i];
+ uint32_t c = ppixel[ppidx];
+ uint32_t p = a + b - c;
+ uint32_t pa = abs(p - a);
+ uint32_t pb = abs(p - b);
+ uint32_t pc = abs(p - c);
+
+ if (pa <= pb && pa <= pc) {
+ x += a;
+ } else if (pb <= pc) {
+ x += b;
+ } else {
+ x += c;
+ }
+
+ ppixel[ppidx] = b;
+
+ if (++ppidx == fbo) {
+ ppidx -= fbo;
+ }
}
- ppixel[ppidx] = b;
-
- if (++ppidx == fbo) {
- ppidx -= fbo;
- }
- }
-
- /* Write out calculated source byte */
- src_scanline[i] = x;
+ /* Write out calculated source byte */
+ src_scanline[i] = x;
+ }
}
if (max_idx + 1 > bps) {
@@ -521,7 +521,7 @@
uint32_t written;
/* Create/extend image buffer */
-#define OUTPUT_CHUNK_SIZE 8192
+#define OUTPUT_CHUNK_SIZE (16*1024)
while (image->data_len + bps > image->data_alloc) {
temp = ctx->alloc(image->data,
image->data_alloc + OUTPUT_CHUNK_SIZE,
13 years, 6 months
r9573 jmb - in /trunk/libnspng: src/internal.h src/pngrender.c test/pngview.c
by netsurf@semichrome.net
Author: jmb
Date: Tue Sep 15 10:53:36 2009
New Revision: 9573
URL: http://source.netsurf-browser.org?rev=9573&view=rev
Log:
Output rgba. This removes the braindead accumulation into a 32bit value.
Modified:
trunk/libnspng/src/internal.h
trunk/libnspng/src/pngrender.c
trunk/libnspng/test/pngview.c
Modified: trunk/libnspng/src/internal.h
URL: http://source.netsurf-browser.org/trunk/libnspng/src/internal.h?rev=9573&...
==============================================================================
--- trunk/libnspng/src/internal.h (original)
+++ trunk/libnspng/src/internal.h Tue Sep 15 10:53:36 2009
@@ -147,7 +147,7 @@
uint8_t prev_pixel[8];
uint8_t *src_scanline;
- uint32_t *rowbuf;
+ uint8_t *rowbuf;
z_stream zlib_stream;
Modified: trunk/libnspng/src/pngrender.c
URL: http://source.netsurf-browser.org/trunk/libnspng/src/pngrender.c?rev=9573...
==============================================================================
--- trunk/libnspng/src/pngrender.c (original)
+++ trunk/libnspng/src/pngrender.c Tue Sep 15 10:53:36 2009
@@ -84,24 +84,27 @@
}
static void process_scanline(nspng_ctx *ctx, const uint8_t *data, uint32_t len,
- uint32_t pass, uint32_t *rowbuf)
-{
- static const uint32_t pix_init[7] = { 0, 4, 0, 2, 0, 1, 0 };
- static const uint32_t pix_step[7] = { 8, 8, 4, 4, 2, 2, 1 };
+ uint32_t pass, uint8_t *rowbuf)
+{
+ /* LUTs for interlacing */
+ /* Byte offsets for initial pixel in pass N */
+ static const uint32_t pix_init[7] = { 0, 16, 0, 8, 0, 4, 0 };
+ /* Number of bytes to skip between pixels in pass N */
+ static const uint32_t pix_step[7] = { 28, 28, 12, 12, 4, 4, 0 };
+
const nspng_image *image = &ctx->image;
const uint32_t colour_type = image->colour_type;
const uint32_t bit_depth = image->bit_depth;
- const uint32_t width = image->width;
+ const uint32_t bytes_per_row = image->width * 4;
const uint32_t bytes_per_pixel = image->bits_per_pixel >> 3;
const uint32_t *palette = image->palette;
const uint32_t step = pix_step[pass];
- uint32_t *curpix = rowbuf + pix_init[pass];
+ uint8_t *curpix = rowbuf + pix_init[pass];
uint32_t bytes_read_for_pixel = 0;
- uint32_t rgba = 0;
for (uint32_t byte = 0; byte < len; byte++) {
/* Reconstruct original byte value */
- uint32_t x = data[byte];
+ const uint8_t x = data[byte];
/* Unpack pixel data from byte into rowbuf */
if (colour_type != COLOUR_TYPE_INDEXED && bit_depth >= 8) {
@@ -110,40 +113,41 @@
/* Taking only the even numbered bytes in the 16bpc
* case results in some rudimentary downsampling. */
if (bit_depth == 8 || (byte & 1) == 0) {
- rgba = (rgba << 8) | x;
+ *curpix++ = x;
+
+ /* Promote greyscale images to RGB */
+ if ((colour_type & COLOUR_BITS_TRUE) == 0 &&
+ bytes_read_for_pixel == 0) {
+ *curpix++ = x;
+ *curpix++ = x;
+ }
}
if (++bytes_read_for_pixel == bytes_per_pixel) {
/* Add default alpha if there isn't any */
if ((colour_type & COLOUR_BITS_ALPHA) == 0) {
- rgba = (rgba << 8) | 0xff;
+ *curpix++ = 0xff;
}
- /* Promote greyscale images to RGB */
- if ((colour_type & COLOUR_BITS_TRUE) == 0) {
- uint32_t g;
-
- /* Currently 00GA, want GGGA */
- g = (rgba & 0xff00) << 8;
- g = g | (g << 8);
- rgba |= g;
- }
-
- *curpix = rgba;
curpix += step;
- rgba = 0;
bytes_read_for_pixel = 0;
}
} else {
/* <8bpc greyscale or paletted images */
for (uint32_t bit = 0; bit < 8 &&
- (uint32_t) (curpix - rowbuf) < width;
+ (uint32_t) (curpix - rowbuf) < bytes_per_row;
bit += bit_depth) {
uint32_t index = (x >> (8 - bit - bit_depth)) &
((1 << bit_depth) - 1);
-
- *curpix = palette[index];
+ uint32_t value = palette[index];
+
+ /* Palette entries are RGBA */
+ *curpix++ = (value >> 24) & 0xff;
+ *curpix++ = (value >> 16) & 0xff;
+ *curpix++ = (value >> 8) & 0xff;
+ *curpix++ = (value >> 0) & 0xff;
+
curpix += step;
}
}
Modified: trunk/libnspng/test/pngview.c
URL: http://source.netsurf-browser.org/trunk/libnspng/test/pngview.c?rev=9573&...
==============================================================================
--- trunk/libnspng/test/pngview.c (original)
+++ trunk/libnspng/test/pngview.c Tue Sep 15 10:53:36 2009
@@ -33,17 +33,14 @@
UNUSED(pass);
for (col = 0; col != rowbytes >> 2; col++) {
- const void *ppix = row + col * 4;
- uint32_t pix = *((const uint32_t *) ppix);
- uint32_t r = (pix >> 24) & 0xff;
- uint32_t g = (pix >> 16) & 0xff;
- uint32_t b = (pix >> 8) & 0xff;
- uint32_t a = 0xff - ((pix >> 0) & 0xff); /* SDL is inverse */
+ const uint8_t *pix = row + col * 4;
- *(scanline + col) = (r << ctx->screen->format->Rshift) |
- (g << ctx->screen->format->Gshift) |
- (b << ctx->screen->format->Bshift) |
- (a << ctx->screen->format->Ashift);
+ *(scanline + col) = (pix[0] << ctx->screen->format->Rshift) |
+ (pix[1] << ctx->screen->format->Gshift) |
+ (pix[2] << ctx->screen->format->Bshift) |
+ /* SDL alpha is inverse */
+ ((0xff - pix[3]) <<
+ ctx->screen->format->Ashift);
}
return NSPNG_OK;
13 years, 6 months
r9572 jmb - in /trunk/libnspng: src/internal.h src/pngread.c src/pngrender.c test/pngread.c
by netsurf@semichrome.net
Author: jmb
Date: Tue Sep 15 08:24:56 2009
New Revision: 9572
URL: http://source.netsurf-browser.org?rev=9572&view=rev
Log:
After throwing a number of pngs at this (namely the contents of netsurfweb/about/screenshots), it turns out that applying the SUB filter to each scanline before compressing it results on *more* memory usage, on average. Slightly surprising, but there we go.
Given that undoing the SUB filter will also be more expensive than a raw data copy, there's no point in persisting with it.
Avoid unnecessary allocations in the redraw handler, too.
Modified:
trunk/libnspng/src/internal.h
trunk/libnspng/src/pngread.c
trunk/libnspng/src/pngrender.c
trunk/libnspng/test/pngread.c
Modified: trunk/libnspng/src/internal.h
URL: http://source.netsurf-browser.org/trunk/libnspng/src/internal.h?rev=9572&...
==============================================================================
--- trunk/libnspng/src/internal.h (original)
+++ trunk/libnspng/src/internal.h Tue Sep 15 08:24:56 2009
@@ -146,7 +146,8 @@
nspng_adaptive_filter_type scanline_filter;
uint8_t prev_pixel[8];
uint8_t *src_scanline;
- uint8_t *dst_scanline;
+
+ uint32_t *rowbuf;
z_stream zlib_stream;
Modified: trunk/libnspng/src/pngread.c
URL: http://source.netsurf-browser.org/trunk/libnspng/src/pngread.c?rev=9572&r...
==============================================================================
--- trunk/libnspng/src/pngread.c (original)
+++ trunk/libnspng/src/pngread.c Tue Sep 15 08:24:56 2009
@@ -444,7 +444,6 @@
const uint32_t bytes_remaining = bps + 1 - brfs;
/* Compensate for oversize buffer */
uint8_t *src_scanline = ctx->src_scanline + fbo;
- uint8_t *dst_scanline = ctx->dst_scanline;
uint8_t *ppixel = ctx->prev_pixel;
nspng_adaptive_filter_type filter = ctx->scanline_filter;
uint32_t max_idx;
@@ -515,9 +514,6 @@
/* Write out calculated source byte */
src_scanline[i] = x;
-
- /* Re-encode using SUB filter */
- dst_scanline[i] = x - a;
}
if (max_idx + 1 > bps) {
@@ -540,14 +536,14 @@
#undef OUTPUT_CHUNK_SIZE
/* Compress scanline into buffer */
- written = lzf_compress(dst_scanline,
+ written = lzf_compress(src_scanline,
bps,
image->data + image->data_len,
bps - 1);
if (written == 0) {
/* Would be larger - use uncompressed */
memcpy(image->data + image->data_len,
- dst_scanline,
+ src_scanline,
bps);
}
@@ -607,14 +603,6 @@
memset(ctx->src_scanline, 0, image->filtered_byte_offset);
}
- if (ctx->dst_scanline == NULL) {
- ctx->dst_scanline = ctx->alloc(NULL, image->bytes_per_scanline,
- ctx->pw);
- if (ctx->dst_scanline == NULL) {
- return NSPNG_NOMEM;
- }
- }
-
/* Set up the input */
ctx->zlib_stream.avail_in = chunk->length;
ctx->zlib_stream.next_in = chunk->data;
@@ -1037,8 +1025,8 @@
if (ctx->src_scanline != NULL)
ctx->alloc(ctx->src_scanline, 0, ctx->pw);
- if (ctx->dst_scanline != NULL)
- ctx->alloc(ctx->dst_scanline, 0, ctx->pw);
+ if (ctx->rowbuf != NULL)
+ ctx->alloc(ctx->rowbuf, 0, ctx->pw);
inflateEnd(&ctx->zlib_stream);
Modified: trunk/libnspng/src/pngrender.c
URL: http://source.netsurf-browser.org/trunk/libnspng/src/pngrender.c?rev=9572...
==============================================================================
--- trunk/libnspng/src/pngrender.c (original)
+++ trunk/libnspng/src/pngrender.c Tue Sep 15 08:24:56 2009
@@ -84,7 +84,7 @@
}
static void process_scanline(nspng_ctx *ctx, const uint8_t *data, uint32_t len,
- uint8_t *scanline, uint32_t pass, uint32_t *rowbuf)
+ uint32_t pass, uint32_t *rowbuf)
{
static const uint32_t pix_init[7] = { 0, 4, 0, 2, 0, 1, 0 };
static const uint32_t pix_step[7] = { 8, 8, 4, 4, 2, 2, 1 };
@@ -96,15 +96,12 @@
const uint32_t *palette = image->palette;
const uint32_t step = pix_step[pass];
uint32_t *curpix = rowbuf + pix_init[pass];
- int32_t aidx = 0 - image->filtered_byte_offset;
uint32_t bytes_read_for_pixel = 0;
uint32_t rgba = 0;
for (uint32_t byte = 0; byte < len; byte++) {
/* Reconstruct original byte value */
- uint32_t x = data[byte] + scanline[aidx++];
-
- scanline[byte] = x;
+ uint32_t x = data[byte];
/* Unpack pixel data from byte into rowbuf */
if (colour_type != COLOUR_TYPE_INDEXED && bit_depth >= 8) {
@@ -161,9 +158,7 @@
nspng_row_callback callback, void *pw)
{
const nspng_image *image = &ctx->image;
- uint8_t *scanline_buf;
uint8_t *scanline;
- uint32_t *rowbuf;
nspng_error error = NSPNG_OK;
if (ctx == NULL || clip == NULL || callback == NULL)
@@ -172,23 +167,15 @@
if (ctx->state != STATE_HAD_IEND)
return NSPNG_INVALID;
- /* Allocate filtered_byte_offset more bytes than needed, so there
- * is no need to check for indices being within the array bounds */
- scanline_buf = ctx->alloc(NULL,
- image->bytes_per_scanline + image->filtered_byte_offset,
- ctx->pw);
- if (scanline_buf == NULL)
- return NSPNG_NOMEM;
- /* Ensure these bytes are zero, as they are never written to */
- memset(scanline_buf, 0, image->filtered_byte_offset);
-
- rowbuf = ctx->alloc(NULL, image->width * sizeof(uint32_t), ctx->pw);
- if (rowbuf == NULL) {
- ctx->alloc(scanline_buf, 0, ctx->pw);
- return NSPNG_NOMEM;
- }
-
- scanline = scanline_buf + image->filtered_byte_offset;
+ scanline = ctx->src_scanline + image->filtered_byte_offset;
+
+ if (ctx->rowbuf == NULL) {
+ ctx->rowbuf = ctx->alloc(NULL,
+ image->width * sizeof(uint32_t), ctx->pw);
+ if (ctx->rowbuf == NULL) {
+ return NSPNG_NOMEM;
+ }
+ }
/* Process scanlines */
for (uint32_t row = clip->y0; row < clip->y1; row++) {
@@ -207,8 +194,8 @@
get_scanline_data(image, idx, scanline,
&data, &len);
- process_scanline(ctx, data, len, scanline,
- pass, rowbuf);
+ process_scanline(ctx, data, len, pass,
+ ctx->rowbuf);
}
} else {
/* Image is not interlaced */
@@ -217,11 +204,10 @@
/* Just use the logic for pass 7
* (i.e. all pixels in scanline) */
- process_scanline(ctx, data, len, scanline,
- 6, rowbuf);
- }
-
- error = callback((uint8_t *) rowbuf,
+ process_scanline(ctx, data, len, 6, ctx->rowbuf);
+ }
+
+ error = callback((uint8_t *) ctx->rowbuf,
image->width * sizeof(uint32_t),
row, 0, pw);
if (error != NSPNG_OK) {
@@ -229,9 +215,6 @@
}
}
- ctx->alloc(rowbuf, 0, ctx->pw);
- ctx->alloc(scanline_buf, 0, ctx->pw);
-
return error;
}
Modified: trunk/libnspng/test/pngread.c
URL: http://source.netsurf-browser.org/trunk/libnspng/test/pngread.c?rev=9572&...
==============================================================================
--- trunk/libnspng/test/pngread.c (original)
+++ trunk/libnspng/test/pngread.c Tue Sep 15 08:24:56 2009
@@ -6,6 +6,8 @@
#endif
#include <libnspng.h>
+
+#include "../src/internal.h"
#define UNUSED(x) ((x)=(x))
@@ -51,13 +53,15 @@
uint32_t height;
nspng_error error;
+ uint64_t full = 0, comp = 0;
+
UNUSED(argc);
- for (int i = 0; i < 20; i++) {
+ for (int i = 1; i < argc; i++) {
- fp = fopen(argv[1], "rb");
+ fp = fopen(argv[i], "rb");
if (fp == NULL) {
- printf("FAIL: couldn't open %s\n", argv[1]);
+ printf("FAIL: couldn't open %s\n", argv[i]);
return 1;
}
@@ -114,11 +118,26 @@
printf("Render : %d cs\n", endTime - startTime);
#endif
+ fseek(fp, 0, SEEK_END);
+ long fsize = ftell(fp);
+
+ full += ctx->image.height * ctx->image.bytes_per_scanline;
+ comp += ctx->image.data_len;
+
+ printf("%s: %lu (%u) -> %u = %.2f%%\n", argv[i], fsize,
+ ctx->image.height * ctx->image.bytes_per_scanline,
+ ctx->image.data_len,
+ (float) ctx->image.data_len * 100 /
+ (float) (ctx->image.height * ctx->image.bytes_per_scanline));
+
nspng_ctx_destroy(ctx);
fclose(fp);
}
+ printf("Mean: %lu -> %lu = %.2f%%\n", full, comp,
+ (float) comp * 100 / (float) full);
+
//printf("PASS\n");
return 0;
13 years, 6 months