Browse Source

* Big API reorganisation. Now libpipi can transparently convert between

colour spaces for a given image. For instance, if pipi_gaussian_blur is
    applied to a 32-bpp image, it is automatically converted to gamma-corrected
    32-bit floats beforehands, then converted back to normal.
  * TODO: clipping, regions of interest, more formats, getpixel macros...

git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2605 92316355-f0b4-4df1-b90c-862c8a59935f
remotes/tiles
sam 16 years ago
parent
commit
31328a14aa
12 changed files with 293 additions and 153 deletions
  1. +0
    -17
      pipi/codec.c
  2. +29
    -14
      pipi/codec/imlib.c
  3. +29
    -14
      pipi/codec/opencv.c
  4. +31
    -16
      pipi/codec/sdl.c
  5. +3
    -0
      pipi/dither.c
  6. +19
    -11
      pipi/filter/blur.c
  7. +40
    -0
      pipi/pipi.c
  8. +30
    -13
      pipi/pipi.h
  9. +13
    -5
      pipi/pipi_internals.h
  10. +56
    -40
      pipi/pixels.c
  11. +28
    -19
      pipi/resize.c
  12. +15
    -4
      pipi/test.c

+ 0
- 17
pipi/codec.c View File

@@ -49,23 +49,6 @@ pipi_image_t *pipi_new(int width, int height)
#endif #endif
} }


pipi_image_t *pipi_copy(pipi_image_t const *img)
{
pipi_image_t *dst;
int x, y;
dst = pipi_new(img->width, img->height);
for(y = 0; y < img->height; y++)
{
for(x = 0; x < img->width; x++)
{
double r, g, b;
pipi_getpixel(img, x, y, &r, &g, &b);
pipi_setpixel(dst, x, y, r, g, b);
}
}
return dst;
}

void pipi_free(pipi_image_t *img) void pipi_free(pipi_image_t *img)
{ {
#if USE_SDL #if USE_SDL


+ 29
- 14
pipi/codec/imlib.c View File

@@ -37,13 +37,20 @@ pipi_image_t *pipi_load_imlib2(const char *name)
return NULL; return NULL;


img = (pipi_image_t *)malloc(sizeof(pipi_image_t)); img = (pipi_image_t *)malloc(sizeof(pipi_image_t));
memset(img, 0, sizeof(pipi_image_t));

imlib_context_set_image(priv); imlib_context_set_image(priv);
img->width = imlib_image_get_width();
img->height = imlib_image_get_height();
img->pitch = 4 * imlib_image_get_width();
img->channels = 4;
img->pixels = (char *)imlib_image_get_data();
img->priv = (void *)priv;
img->w = imlib_image_get_width();
img->h = imlib_image_get_height();

img->p[PIPI_PIXELS_RGBA32].pixels = imlib_image_get_data();
img->p[PIPI_PIXELS_RGBA32].w = imlib_image_get_width();
img->p[PIPI_PIXELS_RGBA32].h = imlib_image_get_height();
img->p[PIPI_PIXELS_RGBA32].pitch = 4 * imlib_image_get_width();
img->last_modified = PIPI_PIXELS_RGBA32;

img->codec_priv = (void *)priv;
img->codec_format = PIPI_PIXELS_RGBA32;


return img; return img;
} }
@@ -57,20 +64,27 @@ pipi_image_t *pipi_new_imlib2(int width, int height)
return NULL; return NULL;


img = (pipi_image_t *)malloc(sizeof(pipi_image_t)); img = (pipi_image_t *)malloc(sizeof(pipi_image_t));
memset(img, 0, sizeof(pipi_image_t));

imlib_context_set_image(priv); imlib_context_set_image(priv);
img->width = imlib_image_get_width();
img->height = imlib_image_get_height();
img->pitch = 4 * imlib_image_get_width();
img->channels = 4;
img->pixels = (char *)imlib_image_get_data();
img->priv = (void *)priv;
img->w = imlib_image_get_width();
img->h = imlib_image_get_height();

img->p[PIPI_PIXELS_RGBA32].pixels = imlib_image_get_data();
img->p[PIPI_PIXELS_RGBA32].w = imlib_image_get_width();
img->p[PIPI_PIXELS_RGBA32].h = imlib_image_get_height();
img->p[PIPI_PIXELS_RGBA32].pitch = 4 * imlib_image_get_width();
img->last_modified = PIPI_PIXELS_RGBA32;

img->codec_priv = (void *)priv;
img->codec_format = PIPI_PIXELS_RGBA32;


return img; return img;
} }


void pipi_free_imlib2(pipi_image_t *img) void pipi_free_imlib2(pipi_image_t *img)
{ {
imlib_context_set_image(img->priv);
imlib_context_set_image(img->codec_priv);
imlib_free_image(); imlib_free_image();


free(img); free(img);
@@ -78,7 +92,8 @@ void pipi_free_imlib2(pipi_image_t *img)


void pipi_save_imlib2(pipi_image_t *img, const char *name) void pipi_save_imlib2(pipi_image_t *img, const char *name)
{ {
imlib_context_set_image(img->priv);
pipi_getpixels(img, img->codec_format);
imlib_context_set_image(img->codec_priv);
imlib_save_image(name); imlib_save_image(name);
} }



+ 29
- 14
pipi/codec/opencv.c View File

@@ -38,12 +38,19 @@ pipi_image_t *pipi_load_opencv(const char *name)
return NULL; return NULL;


img = (pipi_image_t *)malloc(sizeof(pipi_image_t)); img = (pipi_image_t *)malloc(sizeof(pipi_image_t));
img->width = priv->width;
img->height = priv->height;
img->pitch = priv->widthStep;
img->channels = priv->nChannels;
img->pixels = priv->imageData;
img->priv = (void *)priv;
memset(img, 0, sizeof(pipi_image_t));

img->w = priv->width;
img->h = priv->height;

img->p[PIPI_PIXELS_RGBA32].pixels = priv->imageData;
img->p[PIPI_PIXELS_RGBA32].w = priv->width;
img->p[PIPI_PIXELS_RGBA32].h = priv->height;
img->p[PIPI_PIXELS_RGBA32].pitch = priv->widthStep;
img->last_modified = PIPI_PIXELS_RGBA32;

img->codec_priv = (void *)priv;
img->codec_format = PIPI_PIXELS_RGBA32;


return img; return img;
} }
@@ -57,12 +64,19 @@ pipi_image_t *pipi_new_opencv(int width, int height)
return NULL; return NULL;


img = (pipi_image_t *)malloc(sizeof(pipi_image_t)); img = (pipi_image_t *)malloc(sizeof(pipi_image_t));
img->width = priv->width;
img->height = priv->height;
img->pitch = priv->widthStep;
img->channels = priv->nChannels;
img->pixels = priv->imageData;
img->priv = (void *)priv;
memset(img, 0, sizeof(pipi_image_t));

img->w = priv->width;
img->h = priv->height;

img->p[PIPI_PIXELS_RGBA32].pixels = priv->imageData;
img->p[PIPI_PIXELS_RGBA32].w = priv->width;
img->p[PIPI_PIXELS_RGBA32].h = priv->height;
img->p[PIPI_PIXELS_RGBA32].pitch = priv->widthStep;
img->last_modified = PIPI_PIXELS_RGBA32;

img->codec_priv = (void *)priv;
img->codec_format = PIPI_PIXELS_RGBA32;


return img; return img;
} }
@@ -70,7 +84,7 @@ pipi_image_t *pipi_new_opencv(int width, int height)
void pipi_free_opencv(pipi_image_t *img) void pipi_free_opencv(pipi_image_t *img)
{ {
IplImage *iplimg; IplImage *iplimg;
iplimg = (IplImage *)img->priv;
iplimg = (IplImage *)img->codec_priv;
cvReleaseImage(&iplimg); cvReleaseImage(&iplimg);


free(img); free(img);
@@ -78,6 +92,7 @@ void pipi_free_opencv(pipi_image_t *img)


void pipi_save_opencv(pipi_image_t *img, const char *name) void pipi_save_opencv(pipi_image_t *img, const char *name)
{ {
cvSaveImage(name, img->priv);
pipi_getpixels(img, img->codec_format);
cvSaveImage(name, img->codec_priv);
} }



+ 31
- 16
pipi/codec/sdl.c View File

@@ -36,21 +36,28 @@ pipi_image_t *pipi_load_sdl(const char *name)
if(!priv) if(!priv)
return NULL; return NULL;


if(priv->format->BytesPerPixel == 1)
if(priv->format->BytesPerPixel != 4)
{ {
img = pipi_new(priv->w, priv->h); img = pipi_new(priv->w, priv->h);
SDL_BlitSurface(priv, NULL, img->priv, NULL);
SDL_BlitSurface(priv, NULL, img->codec_priv, NULL);
SDL_FreeSurface(priv); SDL_FreeSurface(priv);
return img; return img;
} }


img = (pipi_image_t *)malloc(sizeof(pipi_image_t)); img = (pipi_image_t *)malloc(sizeof(pipi_image_t));
img->width = priv->w;
img->height = priv->h;
img->pitch = priv->pitch;
img->channels = priv->format->BytesPerPixel;
img->pixels = priv->pixels;
img->priv = (void *)priv;
memset(img, 0, sizeof(pipi_image_t));

img->w = priv->w;
img->h = priv->h;

img->p[PIPI_PIXELS_RGBA32].pixels = priv->pixels;
img->p[PIPI_PIXELS_RGBA32].w = priv->w;
img->p[PIPI_PIXELS_RGBA32].h = priv->h;
img->p[PIPI_PIXELS_RGBA32].pitch = priv->pitch;
img->last_modified = PIPI_PIXELS_RGBA32;

img->codec_priv = (void *)priv;
img->codec_format = PIPI_PIXELS_RGBA32;


return img; return img;
} }
@@ -78,25 +85,33 @@ pipi_image_t *pipi_new_sdl(int width, int height)
return NULL; return NULL;


img = (pipi_image_t *)malloc(sizeof(pipi_image_t)); img = (pipi_image_t *)malloc(sizeof(pipi_image_t));
img->width = priv->w;
img->height = priv->h;
img->pitch = priv->pitch;
img->channels = priv->format->BytesPerPixel;
img->pixels = priv->pixels;
img->priv = (void *)priv;
memset(img, 0, sizeof(pipi_image_t));

img->w = priv->w;
img->h = priv->h;

img->p[PIPI_PIXELS_RGBA32].pixels = priv->pixels;
img->p[PIPI_PIXELS_RGBA32].w = priv->w;
img->p[PIPI_PIXELS_RGBA32].h = priv->h;
img->p[PIPI_PIXELS_RGBA32].pitch = priv->pitch;
img->last_modified = PIPI_PIXELS_RGBA32;

img->codec_priv = (void *)priv;
img->codec_format = PIPI_PIXELS_RGBA32;


return img; return img;
} }


void pipi_free_sdl(pipi_image_t *img) void pipi_free_sdl(pipi_image_t *img)
{ {
SDL_FreeSurface(img->priv);
SDL_FreeSurface(img->codec_priv);


free(img); free(img);
} }


void pipi_save_sdl(pipi_image_t *img, const char *name) void pipi_save_sdl(pipi_image_t *img, const char *name)
{ {
SDL_SaveBMP(img->priv, name);
pipi_getpixels(img, img->codec_format);
SDL_SaveBMP(img->codec_priv, name);
} }



+ 3
- 0
pipi/dither.c View File

@@ -28,6 +28,8 @@


void pipi_dither_24to16(pipi_image_t *img) void pipi_dither_24to16(pipi_image_t *img)
{ {
/* XXX: disabled because this is not the right place... see pixels.c instead */
#if 0
int *error, *nexterror; int *error, *nexterror;
uint32_t *p32; uint32_t *p32;
int x, y; int x, y;
@@ -84,5 +86,6 @@ void pipi_dither_24to16(pipi_image_t *img)


free(error); free(error);
free(nexterror); free(nexterror);
#endif
} }



+ 19
- 11
pipi/filter/blur.c View File

@@ -27,15 +27,24 @@
#include "pipi.h" #include "pipi.h"
#include "pipi_internals.h" #include "pipi_internals.h"


pipi_image_t *pipi_gaussian_blur(pipi_image_t const *src, float radius)
pipi_image_t *pipi_gaussian_blur(pipi_image_t *src, float radius)
{ {
pipi_image_t *dst; pipi_image_t *dst;
pipi_pixels_t *srcp, *dstp;
float *srcdata, *dstdata;
double *kernel; double *kernel;
double K, L, t = 0.; double K, L, t = 0.;
int x, y, i, j, w, h, kr, kw; int x, y, i, j, w, h, kr, kw;


w = src->width;
h = src->height;
w = src->w;
h = src->h;

srcp = pipi_getpixels(src, PIPI_PIXELS_RGBA_F);
srcdata = (float *)srcp->pixels;

dst = pipi_new(w, h);
dstp = pipi_getpixels(dst, PIPI_PIXELS_RGBA_F);
dstdata = (float *)dstp->pixels;


kr = (int)(3. * radius + 0.99999); kr = (int)(3. * radius + 0.99999);
kw = 2 * kr + 1; kw = 2 * kr + 1;
@@ -52,8 +61,6 @@ pipi_image_t *pipi_gaussian_blur(pipi_image_t const *src, float radius)
for(i = -kr; i <= kr; i++) for(i = -kr; i <= kr; i++)
kernel[(j + kr) * kw + (i + kr)] /= t; kernel[(j + kr) * kw + (i + kr)] /= t;


dst = pipi_new(w, h);

for(y = 0; y < h; y++) for(y = 0; y < h; y++)
{ {
for(x = 0; x < w; x++) for(x = 0; x < w; x++)
@@ -63,15 +70,16 @@ pipi_image_t *pipi_gaussian_blur(pipi_image_t const *src, float radius)
for(j = -kr; j <= kr; j++) for(j = -kr; j <= kr; j++)
for(i = -kr; i <= kr; i++) for(i = -kr; i <= kr; i++)
{ {
double r, g, b, f = kernel[(j + kr) * kw + (i + kr)];
double f = kernel[(j + kr) * kw + (i + kr)];


pipi_getpixel(src, x + i, y + j, &r, &g, &b);
R += f * r;
G += f * g;
B += f * b;
R += f * srcdata[((y + j) * w + x + i) * 4];
G += f * srcdata[((y + j) * w + x + i) * 4 + 1];
B += f * srcdata[((y + j) * w + x + i) * 4 + 2];
} }


pipi_setpixel(dst, x, y, R, G, B);
dstdata[(y * w + x) * 4] = R;
dstdata[(y * w + x) * 4 + 1] = G;
dstdata[(y * w + x) * 4 + 2] = B;
} }
} }




+ 40
- 0
pipi/pipi.c View File

@@ -0,0 +1,40 @@
/*
* libpipi Proper image processing implementation library
* Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.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.
*/

/*
* pipi.c: core library routines
*/

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

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

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

/*
static int init = 0;

void _pipi_init(void)
{
if(init)
return;

_pipi_init_pixels();
}
*/


+ 30
- 13
pipi/pipi.h View File

@@ -24,25 +24,42 @@ extern "C"
{ {
#endif #endif


/* pipi_format_t: this enum is a list of all possible pixel formats for
* our internal images. RGBA32 is the most usual format when an image has
* just been loaded, but RGBA_F is a lot better for complex operations. */
typedef enum
{
PIPI_PIXELS_RGBA32 = 0,
PIPI_PIXELS_RGBA_F = 1,

PIPI_PIXELS_MAX = 2
}
pipi_format_t;

/* pipi_pixels_t: this structure stores a pixel view of an image. */
typedef struct
{
void *pixels;
int w, h, pitch;
}
pipi_pixels_t;

/* pipi_image_t: the main image type */
typedef struct pipi_image pipi_image_t; typedef struct pipi_image pipi_image_t;


extern pipi_image_t *pipi_load(const char *name);
extern pipi_image_t *pipi_new(int width, int height);
extern pipi_image_t *pipi_copy(const pipi_image_t *img);
extern void pipi_free(pipi_image_t *img);
extern void pipi_save(pipi_image_t *img, const char *name);


extern int pipi_getgray(pipi_image_t const *img, int x, int y, int *g);
extern int pipi_getpixel(pipi_image_t const *img,
int x, int y, double *r, double *g, double *b);
extern int pipi_setpixel(pipi_image_t *img, int x, int y,
double r, double g, double b);
extern pipi_image_t *pipi_load(const char *);
extern pipi_image_t *pipi_new(int, int);
extern void pipi_free(pipi_image_t *);
extern void pipi_save(pipi_image_t *, const char *);

extern pipi_pixels_t *pipi_getpixels(pipi_image_t *, pipi_format_t);


extern pipi_image_t *pipi_resize(pipi_image_t const *, int, int);
extern pipi_image_t *pipi_resize(pipi_image_t *, int, int);


extern pipi_image_t *pipi_gaussian_blur(pipi_image_t const *, float);
extern pipi_image_t *pipi_gaussian_blur(pipi_image_t *, float);


extern void pipi_dither_24to16(pipi_image_t *img);
extern void pipi_dither_24to16(pipi_image_t *);


extern void pipi_test(pipi_image_t *); extern void pipi_test(pipi_image_t *);




+ 13
- 5
pipi/pipi_internals.h View File

@@ -16,14 +16,22 @@
* pipi_internals.h: internal types * pipi_internals.h: internal types
*/ */


#ifndef __CACA_INTERNALS_H__
#define __CACA_INTERNALS_H__
#ifndef __PIPI_INTERNALS_H__
#define __PIPI_INTERNALS_H__


/* pipi_image_t: the image structure. This is probably going to be the most
* complex structure in the library, but right now it only has fairly normal
* stuff, like width and height and pointers to pixel areas. */
struct pipi_image struct pipi_image
{ {
int width, height, pitch, channels;
unsigned char *pixels;
void *priv;
int w, h, pitch;
pipi_format_t codec_format, last_modified;

/* List of all possible pixel formats */
pipi_pixels_t p[PIPI_PIXELS_MAX];

/* Private data used by the codec */
void *codec_priv;
}; };


#ifdef USE_IMLIB2 #ifdef USE_IMLIB2


+ 56
- 40
pipi/pixels.c View File

@@ -31,52 +31,68 @@
#define C2I(p) (pow(((double)p)/255., 2.2)) #define C2I(p) (pow(((double)p)/255., 2.2))
#define I2C(p) ((int)255.999*pow(((double)p), 1./2.2)) #define I2C(p) ((int)255.999*pow(((double)p), 1./2.2))


int pipi_getgray(pipi_image_t const *img, int x, int y, int *g)
/* Return a direct pointer to an image's pixels. */
pipi_pixels_t *pipi_getpixels(pipi_image_t *img, pipi_format_t type)
{ {
if(x < 0 || y < 0 || x >= img->width || y >= img->height)
{
*g = 255;
return -1;
}

*g = (unsigned char)img->pixels[y * img->pitch + x * img->channels + 1];
size_t bytes = 0;
int x, y, i;


return 0;
}

int pipi_getpixel(pipi_image_t const *img,
int x, int y, double *r, double *g, double *b)
{
uint8_t *pixel;
if(type < 0 || type >= PIPI_PIXELS_MAX)
return NULL;


if(x < 0) x = 0;
else if(x >= img->width) x = img->width - 1;

if(y < 0) y = 0;
else if(y >= img->height) y = img->height - 1;

pixel = img->pixels + y * img->pitch + x * img->channels;

*b = C2I((unsigned char)pixel[0]);
*g = C2I((unsigned char)pixel[1]);
*r = C2I((unsigned char)pixel[2]);

return 0;
}
if(img->last_modified == type)
return &img->p[type];


int pipi_setpixel(pipi_image_t *img, int x, int y, double r, double g, double b)
{
uint8_t *pixel;

if(x < 0 || y < 0 || x >= img->width || y >= img->height)
return -1;
/* Allocate pixels if necessary */
if(!img->p[type].pixels)
{
switch(type)
{
case PIPI_PIXELS_RGBA32:
bytes = img->w * img->h * 4 * sizeof(uint8_t);
break;
case PIPI_PIXELS_RGBA_F:
bytes = img->w * img->h * 4 * sizeof(float);
break;
default:
return NULL;
}

img->p[type].pixels = malloc(bytes);
}


pixel = img->pixels + y * img->pitch + x * img->channels;
/* Convert pixels */
if(img->last_modified == PIPI_PIXELS_RGBA32
&& type == PIPI_PIXELS_RGBA_F)
{
uint8_t *src = (uint8_t *)img->p[PIPI_PIXELS_RGBA32].pixels;
float *dest = (float *)img->p[type].pixels;

for(y = 0; y < img->h; y++)
for(x = 0; x < img->w; x++)
for(i = 0; i < 4; i++)
dest[4 * (y * img->w + x) + i]
= C2I(src[4 * (y * img->w + x) + i]);
}
else if(img->last_modified == PIPI_PIXELS_RGBA_F
&& type == PIPI_PIXELS_RGBA32)
{
float *src = (float *)img->p[PIPI_PIXELS_RGBA_F].pixels;
uint8_t *dest = (uint8_t *)img->p[type].pixels;

for(y = 0; y < img->h; y++)
for(x = 0; x < img->w; x++)
for(i = 0; i < 4; i++)
dest[4 * (y * img->w + x) + i]
= I2C(src[4 * (y * img->w + x) + i]);
}
else
{
memset(img->p[type].pixels, 0, bytes);
}


pixel[0] = I2C(b);
pixel[1] = I2C(g);
pixel[2] = I2C(r);
img->last_modified = type;


return 0;
return &img->p[type];
} }



+ 28
- 19
pipi/resize.c View File

@@ -25,46 +25,54 @@
#include "pipi.h" #include "pipi.h"
#include "pipi_internals.h" #include "pipi_internals.h"


pipi_image_t *pipi_resize(pipi_image_t const *src, int w, int h)
pipi_image_t *pipi_resize(pipi_image_t *src, int w, int h)
{ {
double *aline, *line;
float *srcdata, *dstdata, *aline, *line;
pipi_image_t *dst; pipi_image_t *dst;
pipi_pixels_t *srcp, *dstp;
int x, y, x0, y0, sw, dw, sh, dh, remy; int x, y, x0, y0, sw, dw, sh, dh, remy;


srcp = pipi_getpixels(src, PIPI_PIXELS_RGBA_F);
srcdata = (float *)srcp->pixels;

dst = pipi_new(w, h); dst = pipi_new(w, h);
dstp = pipi_getpixels(dst, PIPI_PIXELS_RGBA_F);
dstdata = (float *)dstp->pixels;


sw = src->width; sh = src->height;
dw = dst->width; dh = dst->height;
sw = src->w; sh = src->h;
dw = dst->w; dh = dst->h;


aline = malloc(3 * dw * sizeof(double));
line = malloc(3 * dw * sizeof(double));
aline = malloc(3 * dw * sizeof(float));
line = malloc(3 * dw * sizeof(float));


memset(line, 0, 3 * dw * sizeof(double));
memset(line, 0, 3 * dw * sizeof(float));
remy = 0; remy = 0;


for(y = 0, y0 = 0; y < dst->height; y++)
for(y = 0, y0 = 0; y < dh; y++)
{ {
int toty = 0, ny; int toty = 0, ny;


memset(aline, 0, 3 * dw * sizeof(double));
memset(aline, 0, 3 * dw * sizeof(float));


while(toty < sh) while(toty < sh)
{ {
if(remy == 0) if(remy == 0)
{ {
double r = 0, g = 0, b = 0;
float r = 0, g = 0, b = 0;
int remx = 0; int remx = 0;


for(x = 0, x0 = 0; x < dst->width; x++)
for(x = 0, x0 = 0; x < dw; x++)
{ {
double ar = 0, ag = 0, ab = 0;
float ar = 0, ag = 0, ab = 0;
int totx = 0, nx; int totx = 0, nx;


while(totx < sw) while(totx < sw)
{ {
if(remx == 0) if(remx == 0)
{ {
pipi_getpixel(src, x0, y0, &r, &g, &b);
r = srcdata[(y0 * sw + x0) * 4];
g = srcdata[(y0 * sw + x0) * 4 + 1];
b = srcdata[(y0 * sw + x0) * 4 + 2];
x0++; x0++;
remx = dw; remx = dw;
} }
@@ -85,7 +93,7 @@ pipi_image_t *pipi_resize(pipi_image_t const *src, int w, int h)
} }


ny = (toty + remy <= sh) ? remy : sh - toty; ny = (toty + remy <= sh) ? remy : sh - toty;
for(x = 0; x < dst->width; x++)
for(x = 0; x < dw; x++)
{ {
aline[3 * x] += ny * line[3 * x]; aline[3 * x] += ny * line[3 * x];
aline[3 * x + 1] += ny * line[3 * x + 1]; aline[3 * x + 1] += ny * line[3 * x + 1];
@@ -95,11 +103,12 @@ pipi_image_t *pipi_resize(pipi_image_t const *src, int w, int h)
remy -= ny; remy -= ny;
} }


for(x = 0; x < dst->width; x++)
pipi_setpixel(dst, x, y,
aline[3 * x] / (sw * sh),
aline[3 * x + 1] / (sw * sh),
aline[3 * x + 2] / (sw * sh));
for(x = 0; x < dw; x++)
{
dstdata[(y * dw + x) * 4] = aline[3 * x] / (sw * sh);
dstdata[(y * dw + x) * 4 + 1] = aline[3 * x + 1] / (sw * sh);
dstdata[(y * dw + x) * 4 + 2] = aline[3 * x + 2] / (sw * sh);
}
} }


free(aline); free(aline);


+ 15
- 4
pipi/test.c View File

@@ -27,15 +27,23 @@


void pipi_test(pipi_image_t *img) void pipi_test(pipi_image_t *img)
{ {
pipi_pixels_t *pixels;
float *data;
int x, y; int x, y;


for(y = 0; y < img->height; y++)
pixels = pipi_getpixels(img, PIPI_PIXELS_RGBA_F);
data = (float *)pixels->pixels;

for(y = 0; y < img->h; y++)
{ {
for(x = 0; x < img->width; x++)
for(x = 0; x < img->w; x++)
{ {
double r = 0, g = 0, b = 0; double r = 0, g = 0, b = 0;


pipi_getpixel(img, x, y, &r, &g, &b);
r = data[(y * img->w + x) * 4];
g = data[(y * img->w + x) * 4 + 1];
b = data[(y * img->w + x) * 4 + 2];

if(r + g + b == 0) if(r + g + b == 0)
r = g = b = 1. / 3; r = g = b = 1. / 3;
else if(r + g + b < 1.) else if(r + g + b < 1.)
@@ -53,7 +61,10 @@ void pipi_test(pipi_image_t *img)
double d = (-1. - r + g + b) / 3; double d = (-1. - r + g + b) / 3;
r += d; g -= d; b -= d; r += d; g -= d; b -= d;
} }
pipi_setpixel(img, x, y, r, g, b);

data[(y * img->w + x) * 4] = r;
data[(y * img->w + x) * 4 + 1] = g;
data[(y * img->w + x) * 4 + 2] = b;
} }
} }
} }


Loading…
Cancel
Save