diff --git a/pipi/Makefile.am b/pipi/Makefile.am index 19a2cd6..325589e 100644 --- a/pipi/Makefile.am +++ b/pipi/Makefile.am @@ -44,7 +44,7 @@ codec_sources = # Submodules paint_sources = \ paint/floodfill.c \ - paint/line.c paint/aline_template.h \ + paint/line.c \ paint/bezier.c \ paint/tile.c diff --git a/pipi/paint/aline_template.h b/pipi/paint/aline_template.h deleted file mode 100644 index 8a56e6a..0000000 --- a/pipi/paint/aline_template.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * libpipi Proper image processing implementation library - * Copyright (c) 2004-2008 Sam Hocevar - * 2008 Jean-Yves Lamoureux x1, y1 = s->y1, x2 = s->x2, y2 = s->y2; - float g, xd, yd, xgap, xend, yend, xf, yf, val1, val2; - int x, y, ix1, ix2, iy1, iy2; - - xd = x2 - x1; - yd = y2 - y1; - - /* "Horizontal" line (X greater than Y)*/ - if (fabsf(xd) > fabsf(yd)) - { - if (x1 > x2) - { - float tmp; - tmp = x1; x1 = x2; x2 = tmp; - tmp = y1; y1 = y2; y2 = tmp; - xd = (x2-x1); - yd = (y2-y1); - } - g = yd/xd; - - xend = truncf(x1+0.5); - yend = y1 + g*(xend-x1); - xgap = fractinvf(x1+0.5); - ix1 = (int)xend; - iy1 = (int)yend; - val1 = fractinvf(yend)*xgap; - val2 = fractf(yend)*xgap; - - PLOT(ix1, iy1, val1); - PLOT(ix1, (iy1+1) x2) - { - float tmp; - tmp = x1; x1 = x2; x2 = tmp; - tmp = y1; y1 = y2; y2 = tmp; - xd = (x2-x1); - yd = (y2-y1); - } - - g = xd/yd; - - xend = truncf(x1+0.5); - yend = y1 + g*(xend-x1); - xgap = fractf(x1+0.5); - ix1 = (int)xend; - iy1 = (int)yend; - val1 = fractinvf(yend)*xgap; - val2 = fractf(yend)*xgap; - - PLOT(ix1, iy1, val1); - PLOT(ix1, (iy1+1)>8)/255.0f; /* XXX FIXME */ s.colorf[0] = (c&0x000000FF)/255.0f; /* XXX FIXME */ s.buf_f = dstdata; - s.draw = draw_antialiased_line_float; + s.draw = antialiased_line; } } else if(img->last_modified == PIPI_PIXELS_Y_F) @@ -95,7 +101,7 @@ int pipi_draw_line(pipi_image_t *img , int x1, int y1, int x2, int y2, uint32_t dstdata = (float *)pipi_getpixels(img, PIPI_PIXELS_Y_F)->pixels; s.colorf[0] = (c & 0xff) / 255.0f; /* XXX FIXME */ s.buf_f = dstdata; - s.draw = aa==0?aliased_line_gray:draw_antialiased_line_gray; + s.draw = aa == 0 ? aliased_line_gray : antialiased_line_gray; } else { @@ -105,7 +111,7 @@ int pipi_draw_line(pipi_image_t *img , int x1, int y1, int x2, int y2, uint32_t s.colorf[1] = ((c&0x0000FF00)>>8)/255.0f; /* XXX FIXME */ s.colorf[0] = (c&0x000000FF)/255.0f; /* XXX FIXME */ s.buf_f = dstdata; - s.draw = aa==0?aliased_line:draw_antialiased_line_float; + s.draw = aa == 0 ? aliased_line : antialiased_line; } clip_line(img, &s); @@ -137,16 +143,16 @@ int pipi_draw_polyline(pipi_image_t *img, int const x[], int const y[], s.colorf[1] = ((c&0x0000FF00)>>8)/255.0f; /* XXX FIXME */ s.colorf[0] = (c&0x000000FF)/255.0f; /* XXX FIXME */ s.buf_f = dstdata; - s.draw = draw_antialiased_line_float; + s.draw = antialiased_line; } } else if(img->last_modified == PIPI_PIXELS_Y_F) { float *dstdata; dstdata = (float *)pipi_getpixels(img, PIPI_PIXELS_Y_F)->pixels; - s.colorf[0] = c/255.0f; /* XXX FIXME */ + s.colorf[0] = (c & 0xff) / 255.0f; /* XXX FIXME */ s.buf_f = dstdata; - s.draw = aa==0?aliased_line_gray:draw_antialiased_line_gray; + s.draw = aa == 0 ? aliased_line_gray : antialiased_line_gray; } else { @@ -156,7 +162,7 @@ int pipi_draw_polyline(pipi_image_t *img, int const x[], int const y[], s.colorf[1] = (c&0x0000FF00)/255.0f; /* XXX FIXME */ s.colorf[2] = (c&0x000000FF)/255.0f; /* XXX FIXME */ s.buf_f = dstdata; - s.draw = aa==0?aliased_line:draw_antialiased_line_float; + s.draw = aa == 0 ? aliased_line : antialiased_line; img->last_modified = PIPI_PIXELS_RGBA_F; } @@ -244,51 +250,176 @@ static uint8_t clip_bits(pipi_image_t *img, int x, int y) return b; } -/* Xiaolin Wu's line algorithm, as seen at http://portal.acm.org/citation.cfm?id=122734 */ +#else /* XXX: the following functions use the template system */ -/* math.h doesn't like y1 (sucker) */ -float floorf(float x); -float truncf(float x); -float fabsf(float x); +/* Xiaolin Wu's line algorithm, as seen at http://portal.acm.org/citation.cfm?id=122734 */ -static float fractf(float d) { return (d - floorf(d)); } -static float fractinvf(float d) { return (1 - (d - floorf(d))); } +#define PLOT(x, y, c) \ + if(FLAG_GRAY) \ + { \ + if(FLAG_8BIT) \ + { \ + /* TODO */ \ + } \ + else \ + { \ + s->buf_f[((int)(x))+((int)(y))*img->w] = \ + (c*s->colorf[0]) + (1-c) * s->buf_f[((int)(x))+((int)(y))*img->w]; \ + if(s->buf_f[((int)(x))+((int)(y))*img->w] > 1.0f) \ + s->buf_f[((int)(x))+((int)(y))*img->w] = 1.0f; \ + if(s->buf_f[((int)(x))+((int)(y))*img->w] < 0.0f) \ + s->buf_f[((int)(x))+((int)(y))*img->w] = 0.0f; \ + if(isnan(s->buf_f[((int)(x))+((int)(y))*img->w])) \ + s->buf_f[((int)(x))+((int)(y))*img->w] = 0.0f; \ + } \ + } \ + else \ + { \ + if(FLAG_8BIT) \ + { \ + /* TODO */ \ + } \ + else \ + { \ + int qwer = (((int)(x)*4))+((int)(y))*(img->w*4);\ + int qweg = (1+((int)(x)*4))+((int)(y))*(img->w*4); \ + int qweb = (2+((int)(x)*4))+((int)(y))*(img->w*4); \ + s->buf_f[qwer] = (c*s->colorf[0]) + (1-c) * s->buf_f[qwer]; \ + s->buf_f[qweg] = (c*s->colorf[1]) + (1-c) * s->buf_f[qweg]; \ + s->buf_f[qweb] = (c*s->colorf[2]) + (1-c) * s->buf_f[qweb]; \ + if(s->buf_f[qwer] > 1.0f) \ + s->buf_f[qwer] = 1.0f; \ + if(s->buf_f[qwer] < 0.0f || isnan(s->buf_f[qwer])) \ + s->buf_f[qwer] = 0.0f; \ + if(s->buf_f[qweg] > 1.0f) \ + s->buf_f[qweg] = 1.0f; \ + if(s->buf_f[qweg] < 0.0f || isnan(s->buf_f[qweg])) \ + s->buf_f[qweg] = 0.0f; \ + if(s->buf_f[qweb] > 1.0f) \ + s->buf_f[qweb] = 1.0f; \ + if(s->buf_f[qweb] < 0.0f || isnan(s->buf_f[qweb])) \ + s->buf_f[qweb] = 0.0f; \ + } \ + } -static void draw_antialiased_line_float(pipi_image_t *img, struct line* s) +static void SUFFIX(antialiased_line)(pipi_image_t *img, struct line* s) { -/* Is that an horrible mess ? Yes, it is. */ -#undef PLOT -#define PLOT(x, y, c) \ - { int qwer = (((int)(x)*4))+((int)(y))*(img->w*4);\ - int qweg = (1+((int)(x)*4))+((int)(y))*(img->w*4); \ - int qweb = (2+((int)(x)*4))+((int)(y))*(img->w*4); \ - s->buf_f[qwer] = (c*s->colorf[0]) + (1-c) * s->buf_f[qwer]; \ - s->buf_f[qweg] = (c*s->colorf[1]) + (1-c) * s->buf_f[qweg]; \ - s->buf_f[qweb] = (c*s->colorf[2]) + (1-c) * s->buf_f[qweb]; \ - if(s->buf_f[qwer] > 1.0f) s->buf_f[qwer] = 1.0f; \ - if(s->buf_f[qwer] < 0.0f || isnan(s->buf_f[qwer])) s->buf_f[qwer] = 0.0f; \ - if(s->buf_f[qweg] > 1.0f) s->buf_f[qweg] = 1.0f; \ - if(s->buf_f[qweg] < 0.0f || isnan(s->buf_f[qweg])) s->buf_f[qweg] = 0.0f; \ - if(s->buf_f[qweb] > 1.0f) s->buf_f[qweb] = 1.0f; \ - if(s->buf_f[qweb] < 0.0f || isnan(s->buf_f[qweb])) s->buf_f[qweb] = 0.0f; } - -#include "aline_template.h" -} + float x1 = s->x1, y1 = s->y1, x2 = s->x2, y2 = s->y2; + float g, xd, yd, xgap, xend, yend, xf, yf, val1, val2; + int x, y, ix1, ix2, iy1, iy2; + xd = x2 - x1; + yd = y2 - y1; -static void draw_antialiased_line_gray(pipi_image_t *img, struct line* s) -{ -#undef PLOT -#define PLOT(x, y, c) s->buf_f[((int)(x))+((int)(y))*img->w] = \ - (c*s->colorf[0]) + (1-c) * s->buf_f[((int)(x))+((int)(y))*img->w]; \ - if(s->buf_f[((int)(x))+((int)(y))*img->w] > 1.0f) s->buf_f[((int)(x))+((int)(y))*img->w] = 1.0f; \ - if(s->buf_f[((int)(x))+((int)(y))*img->w] < 0.0f) s->buf_f[((int)(x))+((int)(y))*img->w] = 0.0f; \ - if(isnan(s->buf_f[((int)(x))+((int)(y))*img->w])) s->buf_f[((int)(x))+((int)(y))*img->w] = 0.0f; - -#include "aline_template.h" + /* "Horizontal" line (X greater than Y)*/ + if (fabsf(xd) > fabsf(yd)) + { + if (x1 > x2) + { + float tmp; + tmp = x1; x1 = x2; x2 = tmp; + tmp = y1; y1 = y2; y2 = tmp; + xd = (x2-x1); + yd = (y2-y1); + } + g = yd/xd; + + xend = truncf(x1+0.5); + yend = y1 + g*(xend-x1); + xgap = fractinvf(x1+0.5); + ix1 = (int)xend; + iy1 = (int)yend; + val1 = fractinvf(yend)*xgap; + val2 = fractf(yend)*xgap; + + PLOT(ix1, iy1, val1); + PLOT(ix1, (iy1+1) x2) + { + float tmp; + tmp = x1; x1 = x2; x2 = tmp; + tmp = y1; y1 = y2; y2 = tmp; + xd = (x2-x1); + yd = (y2-y1); + } + + g = xd/yd; + + xend = truncf(x1+0.5); + yend = y1 + g*(xend-x1); + xgap = fractf(x1+0.5); + ix1 = (int)xend; + iy1 = (int)yend; + val1 = fractinvf(yend)*xgap; + val2 = fractf(yend)*xgap; + + PLOT(ix1, iy1, val1); + PLOT(ix1, (iy1+1)