diff options
author | Michael Drake <tlsa@netsurf-browser.org> | 2012-09-28 11:19:34 +0100 |
---|---|---|
committer | Michael Drake <tlsa@netsurf-browser.org> | 2012-09-28 11:19:34 +0100 |
commit | 0804bb7e067e66d4b05a6c45f9736b1e20505b96 (patch) | |
tree | e6b5e4ac559963dd0767e2ed39c878202f056c0f /src/plot | |
parent | 46f3c9ea3793d146337c81bf8858d99238c05e86 (diff) | |
download | libnsfb-0804bb7e067e66d4b05a6c45f9736b1e20505b96.tar.gz libnsfb-0804bb7e067e66d4b05a6c45f9736b1e20505b96.tar.bz2 |
Add error diffusion to palette based rendering. Only used for bitmap and scaled bitmap plots. Doesn't do serpentine path, since that would need changes to the common bitmap rendering code.
Diffstat (limited to 'src/plot')
-rw-r--r-- | src/plot/8bpp.c | 2 | ||||
-rw-r--r-- | src/plot/common.c | 69 |
2 files changed, 50 insertions, 21 deletions
diff --git a/src/plot/8bpp.c b/src/plot/8bpp.c index 05574d8..0245542 100644 --- a/src/plot/8bpp.c +++ b/src/plot/8bpp.c @@ -39,7 +39,7 @@ static uint8_t colour_to_pixel(nsfb_t *nsfb, nsfb_colour_t c) if (nsfb->palette == NULL) return 0; - return nsfb_palette_best_match(nsfb->palette, c); + return nsfb_palette_best_match_dither(nsfb->palette, c); } #define PLOT_TYPE uint8_t diff --git a/src/plot/common.c b/src/plot/common.c index 185e323..c9f9dc1 100644 --- a/src/plot/common.c +++ b/src/plot/common.c @@ -16,6 +16,8 @@ #error PLOT_LINELEN must be a macro to increment a line length #endif +#include "palette.h" + #define SIGN(x) ((x<0) ? -1 : ((x>0) ? 1 : 0)) static bool @@ -249,8 +251,7 @@ static bool bitmap_scaled(nsfb_t *nsfb, const nsfb_bbox_t *loc, nsfb_bbox_t clipped; /* clipped display */ /* The part of the scaled image actually displayed is cropped to the - * current context. - */ + * current context. */ clipped.x0 = x; clipped.y0 = y; clipped.x1 = x + width; @@ -271,6 +272,10 @@ static bool bitmap_scaled(nsfb_t *nsfb, const nsfb_bbox_t *loc, else rwidth = width; + if (nsfb->palette != NULL) { + nsfb_palette_dither_init(nsfb->palette, rwidth); + } + /* get veritcal (y) and horizontal (x) scale factors; both integer * part and remainder */ dx = bmp_width / width; @@ -299,7 +304,8 @@ static bool bitmap_scaled(nsfb_t *nsfb, const nsfb_bbox_t *loc, pvideo = get_xy_loc(nsfb, clipped.x0, clipped.y0); pvideo_limit = pvideo + PLOT_LINELEN(nsfb->linelen) * rheight; if (alpha) { - for (; pvideo < pvideo_limit; pvideo += PLOT_LINELEN(nsfb->linelen)) { + for (; pvideo < pvideo_limit; + pvideo += PLOT_LINELEN(nsfb->linelen)) { /* looping through render area vertically */ xoff = xoffs; rx = rxs; @@ -322,7 +328,8 @@ static bool bitmap_scaled(nsfb_t *nsfb, const nsfb_bbox_t *loc, xloop))); } /* plot pixel */ - *(pvideo + xloop) = colour_to_pixel(nsfb, abpixel); + *(pvideo + xloop) = colour_to_pixel( + nsfb, abpixel); } /* handle horizontal interpolation */ xoff += dx; @@ -341,7 +348,8 @@ static bool bitmap_scaled(nsfb_t *nsfb, const nsfb_bbox_t *loc, } } } else { - for (; pvideo < pvideo_limit; pvideo += PLOT_LINELEN(nsfb->linelen)) { + for (; pvideo < pvideo_limit; + pvideo += PLOT_LINELEN(nsfb->linelen)) { /* looping through render area vertically */ xoff = xoffs; rx = rxs; @@ -350,7 +358,8 @@ static bool bitmap_scaled(nsfb_t *nsfb, const nsfb_bbox_t *loc, /* get value of source pixel in question */ abpixel = pixel[yoff + xoff]; /* plot pixel */ - *(pvideo + xloop) = colour_to_pixel(nsfb, abpixel); + *(pvideo + xloop) = colour_to_pixel( + nsfb, abpixel); /* handle horizontal interpolation */ xoff += dx; @@ -369,6 +378,11 @@ static bool bitmap_scaled(nsfb_t *nsfb, const nsfb_bbox_t *loc, } } } + + if (nsfb->palette != NULL) { + nsfb_palette_dither_fini(nsfb->palette); + } + return true; } @@ -391,17 +405,16 @@ bitmap(nsfb_t *nsfb, int height = loc->y1 - loc->y0; nsfb_bbox_t clipped; /* clipped display */ - if (width == 0 || height == 0) - return true; + if (width == 0 || height == 0) + return true; /* Scaled bitmaps are handled by a separate function */ if (width != bmp_width || height != bmp_height) return bitmap_scaled(nsfb, loc, pixel, bmp_width, bmp_height, bmp_stride, alpha); - /* The part of the scaled image actually displayed is cropped to the - * current context. - */ + /* The part of the image actually displayed is cropped to the + * current context. */ clipped.x0 = x; clipped.y0 = y; clipped.x1 = x + width; @@ -416,6 +429,10 @@ bitmap(nsfb_t *nsfb, if (width > (clipped.x1 - clipped.x0)) width = (clipped.x1 - clipped.x0); + if (nsfb->palette != NULL) { + nsfb_palette_dither_init(nsfb->palette, width); + } + xoff = clipped.x0 - x; yoff = (clipped.y0 - y) * bmp_stride; height = height * bmp_stride + yoff; @@ -428,16 +445,22 @@ bitmap(nsfb_t *nsfb, for (xloop = 0; xloop < width; xloop++) { abpixel = pixel[yloop + xloop + xoff]; if ((abpixel & 0xFF000000) != 0) { - /* pixel is not transparent; have to - * plot something */ - if ((abpixel & 0xFF000000) != 0xFF000000) { - /* pixel is not opaque; need to - * blend */ - abpixel = nsfb_plot_ablend(abpixel, - pixel_to_colour(nsfb, *(pvideo + xloop))); + /* pixel is not transparent; have to + * plot something */ + if ((abpixel & 0xFF000000) != + 0xFF000000) { + /* pixel is not opaque; need to + * blend */ + abpixel = nsfb_plot_ablend( + abpixel, + pixel_to_colour( + nsfb, + *(pvideo + + xloop))); } - *(pvideo + xloop) = colour_to_pixel(nsfb, abpixel); + *(pvideo + xloop) = colour_to_pixel( + nsfb, abpixel); } } pvideo += PLOT_LINELEN(nsfb->linelen); @@ -446,11 +469,17 @@ bitmap(nsfb_t *nsfb, for (yloop = yoff; yloop < height; yloop += bmp_stride) { for (xloop = 0; xloop < width; xloop++) { abpixel = pixel[yloop + xloop + xoff]; - *(pvideo + xloop) = colour_to_pixel(nsfb, abpixel); + *(pvideo + xloop) = colour_to_pixel( + nsfb, abpixel); } pvideo += PLOT_LINELEN(nsfb->linelen); } } + + if (nsfb->palette != NULL) { + nsfb_palette_dither_fini(nsfb->palette); + } + return true; } |