瀏覽代碼

* Added simple Bresenham line drawing routines (RGBA_32, RGBA_F, Y_F)

git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2776 92316355-f0b4-4df1-b90c-862c8a59935f
remotes/tiles
jylam 16 年之前
父節點
當前提交
971efb124e
共有 6 個檔案被更改,包括 335 行新增2 行删除
  1. +3
    -1
      examples/Makefile.am
  2. +47
    -0
      examples/line.c
  3. +1
    -0
      pipi/Makefile.am
  4. +224
    -0
      pipi/paint/line.c
  5. +57
    -0
      pipi/paint/line_template.c
  6. +3
    -1
      pipi/pipi.h

+ 3
- 1
examples/Makefile.am 查看文件

@@ -2,7 +2,7 @@

AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/pipi

bin_PROGRAMS = edd img2rubik sharpen floodfill
bin_PROGRAMS = edd img2rubik sharpen floodfill line

edd_SOURCES = edd.c
edd_LDADD = ../pipi/libpipi.la
@@ -16,3 +16,5 @@ sharpen_LDADD = ../pipi/libpipi.la
floodfill_SOURCES = floodfill.c
floodfill_LDADD = ../pipi/libpipi.la

line_SOURCES = line.c
line_LDADD = ../pipi/libpipi.la

+ 47
- 0
examples/line.c 查看文件

@@ -0,0 +1,47 @@
#include "config.h"
#include "common.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <pipi.h>

int main(int argc, char *argv[])
{
char *srcname = NULL, *dstname = NULL;
pipi_image_t *img, *newimg;
int count = 1000;
int ret = 0;
if(argc < 2)
{
fprintf(stderr, "%s: too few arguments\n", argv[0]);
fprintf(stderr, "Usage: %s <src> <dest>\n", argv[0]);
return EXIT_FAILURE;
}

srcname = argv[1];
dstname = argv[2];

img = pipi_load(srcname);

if(!img) {
fprintf(stderr, "Can't open %s for reading\n", srcname);
}

newimg = pipi_copy(img);
pipi_free(img);

while(count--) {
pipi_draw_line(newimg,
rand() % 500, rand() % 500,
rand() % 500, rand() % 500,
rand());
}
pipi_save(newimg, dstname);

pipi_free(newimg);

return ret;
}


+ 1
- 0
pipi/Makefile.am 查看文件

@@ -43,6 +43,7 @@ codec_sources =
# Submodules
paint_sources = \
paint/floodfill.c \
paint/line.c \
paint/tile.c

render_sources = \


+ 224
- 0
pipi/paint/line.c 查看文件

@@ -0,0 +1,224 @@
/*
* libpipi Proper image processing implementation library
* Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org>
* 2008 Jean-Yves Lamoureux <jylam@lnxscene.org
* All Rights Reserved
*
* $Id$
*
* This library is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

/*
* line.c: line rendering functions
*/

#include "config.h"
#include "common.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "pipi.h"
#include "pipi_internals.h"

struct line
{
int x1, y1;
int x2, y2;
void (*draw) (pipi_image_t*, struct line*);
union {
uint32_t color32;
float colorf[3];
};

union {
uint32_t *buf_u32;
float *buf_f;
};

};
static void clip_line(pipi_image_t*, struct line*);
static uint8_t clip_bits(pipi_image_t*, int, int);
static void draw_aliased_line_u32(pipi_image_t*, struct line*);
static void draw_aliased_line_gray(pipi_image_t *img, struct line* s);
static void draw_aliased_line_float(pipi_image_t *img, struct line* s);



int pipi_draw_line(pipi_image_t *img , int x1, int y1, int x2, int y2, uint32_t c)
{
struct line s;
s.x1 = x1;
s.y1 = y1;
s.x2 = x2;
s.y2 = y2;

if(img->last_modified == PIPI_PIXELS_RGBA_C) {
uint32_t *dstdata;
dstdata = (uint32_t *)pipi_getpixels(img, PIPI_PIXELS_RGBA_C)->pixels;
s.color32 = c;
s.buf_u32 = dstdata;
s.draw = draw_aliased_line_u32;
} 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.buf_f = dstdata;
s.draw = draw_aliased_line_gray;


} else {
float *dstdata;
dstdata = (float *)pipi_getpixels(img, PIPI_PIXELS_RGBA_F)->pixels;
s.colorf[0] = (c&0x00FF0000)/255.0f; /* XXX FIXME */
s.colorf[1] = (c&0x0000FF00)/255.0f; /* XXX FIXME */
s.colorf[2] = (c&0x000000FF)/255.0f; /* XXX FIXME */
s.buf_f = dstdata;
s.draw = draw_aliased_line_float;
}

clip_line(img, &s);
return 0;
}


int pipi_draw_polyline(pipi_image_t *img, int const x[], int const y[],
int n, uint32_t c)
{
int i;
struct line s;

if(img->last_modified == PIPI_PIXELS_RGBA_C) {
uint32_t *dstdata;
dstdata = (uint32_t *)pipi_getpixels(img, PIPI_PIXELS_RGBA_C)->pixels;
s.color32 = c;
s.buf_u32 = dstdata;
s.draw = draw_aliased_line_u32;
} else {
float *dstdata;
dstdata = (float *)pipi_getpixels(img, PIPI_PIXELS_RGBA_F)->pixels;
s.colorf[0] = (c&0x00FF0000)/255.0f; /* XXX FIXME */
s.colorf[1] = (c&0x0000FF00)/255.0f; /* XXX FIXME */
s.colorf[2] = (c&0x000000FF)/255.0f; /* XXX FIXME */
s.buf_f = dstdata;
s.draw = draw_aliased_line_float;
img->last_modified = PIPI_PIXELS_RGBA_F;
}

for(i = 0; i < n; i++)
{
s.x1 = x[i];
s.y1 = y[i];
s.x2 = x[i+1];
s.y2 = y[i+1];
clip_line(img, &s);
}
return 0;
}





/*
* XXX: The following functions are local.
*/
/* Generic Cohen-Sutherland line clipping function. */
static void clip_line(pipi_image_t *img, struct line* s)
{
uint8_t bits1, bits2;

bits1 = clip_bits(img, s->x1, s->y1);
bits2 = clip_bits(img, s->x2, s->y2);

if(bits1 & bits2)
return;

if(bits1 == 0)
{
if(bits2 == 0)
s->draw(img, s);
else
{
int tmp;
tmp = s->x1; s->x1 = s->x2; s->x2 = tmp;
tmp = s->y1; s->y1 = s->y2; s->y2 = tmp;
clip_line(img, s);
}
return;
}

if(bits1 & (1<<0))
{
s->y1 = s->y2 - (s->x2 - 0) * (s->y2 - s->y1) / (s->x2 - s->x1);
s->x1 = 0;
}
else if(bits1 & (1<<1))
{
int xmax = img->w - 1;
s->y1 = s->y2 - (s->x2 - xmax) * (s->y2 - s->y1) / (s->x2 - s->x1);
s->x1 = xmax;
}
else if(bits1 & (1<<2))
{
s->x1 = s->x2 - (s->y2 - 0) * (s->x2 - s->x1) / (s->y2 - s->y1);
s->y1 = 0;
}
else if(bits1 & (1<<3))
{
int ymax = img->h - 1;
s->x1 = s->x2 - (s->y2 - ymax) * (s->x2 - s->x1) / (s->y2 - s->y1);
s->y1 = ymax;
}

clip_line(img, s);
}

/* Helper function for clip_line(). */
static uint8_t clip_bits(pipi_image_t *img, int x, int y)
{
uint8_t b = 0;

if(x < 0)
b |= (1<<0);
else if(x >= (int)img->w)
b |= (1<<1);

if(y < 0)
b |= (1<<2);
else if(y >= (int)img->h)
b |= (1<<3);

return b;
}



/* Solid line drawing function, using Bresenham's mid-point line
* scan-conversion algorithm. */
static void draw_aliased_line_u32(pipi_image_t *img, struct line* s)
{
#undef ASSIGN
#define ASSIGN(x, y, w) s->buf_u32[x+y*w] = s->color32;
#include "line_template.c"
}
static void draw_aliased_line_float(pipi_image_t *img, struct line* s)
{
#undef ASSIGN
#define ASSIGN(x, y, w) s->buf_f[(x*4)+y*(w*4)] = s->colorf[0]; \
s->buf_f[1 + (x*4)+y*(w*4)] = s->colorf[1]; \
s->buf_f[2 + (x*4)+y*(w*4)] = s->colorf[2];
#include "line_template.c"
}
static void draw_aliased_line_gray(pipi_image_t *img, struct line* s)
{
#undef ASSIGN
#define ASSIGN(x, y, w) s->buf_f[x+y*w] = s->colorf[0];
#include "line_template.c"
}

+ 57
- 0
pipi/paint/line_template.c 查看文件

@@ -0,0 +1,57 @@
int x1, y1, x2, y2;
int dx, dy;
int xinc, yinc;

x1 = s->x1; y1 = s->y1; x2 = s->x2; y2 = s->y2;

dx = abs(x2 - x1);
dy = abs(y2 - y1);

xinc = (x1 > x2) ? -1 : 1;
yinc = (y1 > y2) ? -1 : 1;

if(dx >= dy)
{
int dpr = dy << 1;
int dpru = dpr - (dx << 1);
int delta = dpr - dx;

for(; dx>=0; dx--)
{
ASSIGN(x1, y1, img->w);

if(delta > 0)
{
x1 += xinc;
y1 += yinc;
delta += dpru;
}
else
{
x1 += xinc;
delta += dpr;
}
}
}
else
{
int dpr = dx << 1;
int dpru = dpr - (dy << 1);
int delta = dpr - dy;

for(; dy >= 0; dy--)
{
ASSIGN(x1, y1, img->w);
if(delta > 0)
{
x1 += xinc;
y1 += yinc;
delta += dpru;
}
else
{
y1 += yinc;
delta += dpr;
}
}
}

+ 3
- 1
pipi/pipi.h 查看文件

@@ -150,7 +150,9 @@ extern pipi_image_t *pipi_erode(pipi_image_t *);
extern pipi_image_t *pipi_tile(pipi_image_t *, int, int);
extern int pipi_flood_fill(pipi_image_t *,
int, int, float, float, float, float);

extern int pipi_draw_line(pipi_image_t *, int, int, int, int, uint32_t);
extern int pipi_draw_polyline(pipi_image_t *, int const[], int const[],
int , uint32_t);
extern pipi_image_t *pipi_reduce(pipi_image_t *, int, double const *);

extern pipi_image_t *pipi_dither_ediff(pipi_image_t *, pipi_image_t *,


Loading…
取消
儲存