Skip to content
This repository has been archived by the owner on Jul 20, 2020. It is now read-only.

Commit

Permalink
Made main use the new "array system".
Browse files Browse the repository at this point in the history
  • Loading branch information
JulianKniephoff committed Jan 15, 2011
1 parent 9af5d12 commit 5143748
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 110 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
seamless: main.c energy_functions.c
seamless: main.c energy_functions.c pixel_access.c array_image.c
gcc -Wall -Werror -pedantic-errors -std=c99 `sdl-config --cflags --libs` -lSDL_image energy_functions.c pixel_access.c array_image.c main.c -o seamless -O3
2 changes: 1 addition & 1 deletion array_image.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ array_to_surface (Uint8 * array, Uint32 flags, int width, int height,
put_pixel (surface, x, y,
SDL_MapRGB (surface->format, pixel[0], pixel[1],
pixel[2]));
array += 3;
pixel += 3;
}
}

Expand Down
2 changes: 2 additions & 0 deletions array_image.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#define array_g(array, w, x, y) ((array)[3 * ((w) * (y) + (x)) + 1])
#define array_b(array, w, x, y) ((array)[3 * ((w) * (y) + (x)) + 2])

#define make_array(width, height) (malloc (sizeof (Uint8 *) * 3 * width * height))

Uint8 *surface_to_array (SDL_Surface * surface);

SDL_Surface *array_to_surface (Uint8 * array, Uint32 flags, int width,
Expand Down
127 changes: 62 additions & 65 deletions energy_functions.c
Original file line number Diff line number Diff line change
@@ -1,124 +1,121 @@
#include <math.h>

#include <SDL.h>

#include "util.h"
#include "pixel_access.h"
#include "array_image.h"

Uint8
gradient_magnitude (SDL_Surface * image, int x, int y)
float
gradient_magnitude (Uint8 * image, int w, int h, int x, int y)
{
Uint8 r, g, b, l1, l2;
Uint8 *pixel;
Uint8 l1, l2;
float ddx, ddy;
/* TODO Better handling of the borders... */
/* d/dx */
if (x == 0)
{
SDL_GetRGB (get_pixel (image, x, y), image->format, &r, &g, &b);
l1 = max (max (r, g), b);
SDL_GetRGB (get_pixel (image, x + 1, y), image->format, &r, &g, &b);
l2 = max (max (r, g), b);
pixel = array_p (image, w, x, y);
l1 = value_from_rgb (pixel[0], pixel[1], pixel[2]);
pixel += 3;
l2 = value_from_rgb (pixel[0], pixel[1], pixel[2]);
ddx = l2 - l1;
}
else if (x == image->w - 1)
else if (x == w - 1)
{
SDL_GetRGB (get_pixel (image, x - 1, y), image->format, &r, &g, &b);
l1 = max (max (r, g), b);
SDL_GetRGB (get_pixel (image, x, y), image->format, &r, &g, &b);
l2 = max (max (r, g), b);
pixel = array_p (image, w, x - 1, y);
l1 = value_from_rgb (pixel[0], pixel[1], pixel[2]);
pixel += 3;
l2 = value_from_rgb (pixel[0], pixel[1], pixel[2]);
ddx = l2 - l1;
}
else
{
SDL_GetRGB (get_pixel (image, x - 1, y), image->format, &r, &g, &b);
l1 = max (max (r, g), b);
SDL_GetRGB (get_pixel (image, x + 1, y), image->format, &r, &g, &b);
l2 = max (max (r, g), b);
pixel = array_p (image, w, x - 1, y);
l1 = value_from_rgb (pixel[0], pixel[1], pixel[2]);
pixel += 6;
l2 = value_from_rgb (pixel[0], pixel[1], pixel[2]);
ddx = (l2 - l1) / 2.0f;
}
/* d/dy */
if (y == 0)
{
SDL_GetRGB (get_pixel (image, x, y), image->format, &r, &g, &b);
l1 = max (max (r, g), b);
SDL_GetRGB (get_pixel (image, x, y + 1), image->format, &r, &g, &b);
l2 = max (max (r, g), b);
pixel = array_p (image, w, x, y);
l1 = value_from_rgb (pixel[0], pixel[1], pixel[2]);
pixel += 3 * w;
l2 = value_from_rgb (pixel[0], pixel[1], pixel[2]);
ddy = l2 - l1;
}
else if (y == image->h - 1)
else if (y == h - 1)
{
SDL_GetRGB (get_pixel (image, x, y - 1), image->format, &r, &g, &b);
l1 = max (max (r, g), b);
SDL_GetRGB (get_pixel (image, x, y), image->format, &r, &g, &b);
l2 = max (max (r, g), b);
pixel = array_p (image, w, x, y - 1);
l1 = value_from_rgb (pixel[0], pixel[1], pixel[2]);
pixel += 3 * w;
l2 = value_from_rgb (pixel[0], pixel[1], pixel[2]);
ddy = l2 - l1;
}
else
{
SDL_GetRGB (get_pixel (image, x, y - 1), image->format, &r, &g, &b);
l1 = max (max (r, g), b);
SDL_GetRGB (get_pixel (image, x, y + 1), image->format, &r, &g, &b);
l2 = max (max (r, g), b);
pixel = array_p (image, w, x, y - 1);
l1 = value_from_rgb (pixel[0], pixel[1], pixel[2]);
pixel += 6 * w;
l2 = value_from_rgb (pixel[0], pixel[1], pixel[2]);
ddy = (l2 - l1) / 2.0f;
}

return sqrt (ddx * ddx + ddy * ddy) * M_SQRT2;
return sqrt (ddx * ddx + ddy * ddy);
}

Uint8
steepest_neighbor (SDL_Surface * image, int x, int y)
steepest_neighbor (Uint8 * image, int w, int h, int x, int y)
{
Uint8 r, g, b, l, l1, l2, l3, l4, l5, l6, l7, l8;
Uint8 l, l1, l2, l3, l4, l5, l6, l7, l8;
l1 = l2 = l3 = l4 = l5 = l6 = l7 = l8 = 0;

SDL_GetRGB (get_pixel (image, x, y), image->format, &r, &g, &b);
l = max (max (r, g), b);
Uint8 *pixel = array_p (image, w, x, y);
l = value_from_rgb (pixel[0], pixel[1], pixel[2]);

if (x > 0)
{
if (y > 0)
{
SDL_GetRGB (get_pixel (image, x - 1, y - 1), image->format, &r, &g,
&b);
l1 = abs (l - max (max (r, g), b));
pixel = array_p (image, w, x - 1, y - 1);
l1 = abs (l - value_from_rgb (pixel[0], pixel[1], pixel[2]));
}
SDL_GetRGB (get_pixel (image, x - 1, y), image->format, &r, &g, &b);
l2 = abs (l - max (max (r, g), b));
if (y < image->h - 1)
pixel = array_p (image, w, x - 1, y);
l2 = abs (l - value_from_rgb (pixel[0], pixel[1], pixel[2]));
if (y < h - 1)
{
SDL_GetRGB (get_pixel (image, x - 1, y + 1), image->format, &r, &g,
&b);
l3 = abs (l - max (max (r, g), b));
pixel = array_p (image, w, x - 1, y + 1);
l3 = abs (l - value_from_rgb (pixel[0], pixel[1], pixel[2]));
}
}

if (y > 0)
{
SDL_GetRGB (get_pixel (image, x, y - 1), image->format, &r, &g, &b);
l4 = abs (l - max (max (r, g), b));
pixel = array_p (image, w, x, y - 1);
l1 = abs (l - value_from_rgb (pixel[0], pixel[1], pixel[2]));
}
if (y < image->h - 1)
pixel = array_p (image, w, x, y);
l2 = abs (l - value_from_rgb (pixel[0], pixel[1], pixel[2]));
if (y < h - 1)
{
SDL_GetRGB (get_pixel (image, x, y + 1), image->format, &r, &g, &b);
l5 = abs (l - max (max (r, g), b));
pixel = array_p (image, w, x, y + 1);
l3 = abs (l - value_from_rgb (pixel[0], pixel[1], pixel[2]));
}

if (x < image->w - 1)
if (x < w - 1)
{
if (y > 0)
{
SDL_GetRGB (get_pixel (image, x + 1, y - 1), image->format, &r, &g,
&b);
l6 = abs (l - max (max (r, g), b));
}
SDL_GetRGB (get_pixel (image, x + 1, y), image->format, &r, &g, &b);
l7 = abs (l - max (max (r, g), b));
if (y < image->h - 1)
{
SDL_GetRGB (get_pixel (image, x + 1, y + 1), image->format, &r, &g,
&b);
l8 = abs (l - max (max (r, g), b));
}
{
pixel = array_p (image, w, x + 1, y - 1);
l1 = abs (l - value_from_rgb (pixel[0], pixel[1], pixel[2]));
}
pixel = array_p (image, w, x + 1, y);
l2 = abs (l - value_from_rgb (pixel[0], pixel[1], pixel[2]));
if (y < h - 1)
{
pixel = array_p (image, w, x + 1, y + 1);
l3 = abs (l - value_from_rgb (pixel[0], pixel[1], pixel[2]));
}
}

return max (max (max (max (max (max (max (l1, l2), l3), l4), l5), l6), l7),
Expand Down
85 changes: 43 additions & 42 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@
#include "pixel_access.h"
#include "array_image.h"

extern Uint8 gradient_magnitude (SDL_Surface * image, int x, int y);
extern Uint8 steepest_neighbor (SDL_Surface * image, int x, int y);

typedef float (*energy_function) (Uint8 * image, int width, int height, int x, int y);

extern float gradient_magnitude (Uint8 * image, int width, int height, int x, int y);
extern float steepest_neighbor (Uint8 * image, int width, int height, int x, int y);


/* TODO There should be more cleanup here... */
void
Expand All @@ -19,36 +23,43 @@ quit (void)
SDL_Quit ();
}

void
energize (SDL_Surface * image, SDL_Surface * energy,
Uint8 (*energy_function) (SDL_Surface *, int, int))
SDL_Surface *
energize (SDL_Surface * image, energy_function f)
{
/* Process image */
if (SDL_MUSTLOCK (image))
{
SDL_LockSurface (image);
}
if (SDL_MUSTLOCK (energy))
Uint8 *array = surface_to_array (image);

if (!array)
{
SDL_LockSurface (energy);
return NULL;
}
Uint8 e;
for (int x = 0; x < image->w; ++x)
float *result = malloc (sizeof (float) * image->w * image->h);
if (!result)
{
for (int y = 0; y < image->h; ++y)
{
e = energy_function (image, x, y);
put_pixel (energy, x, y, SDL_MapRGB (energy->format, e, e, e));
}
free (array);
return NULL;
}
if (SDL_MUSTLOCK (energy))
{
SDL_UnlockSurface (energy);
}
if (SDL_MUSTLOCK (image))
Uint8 *vis = make_array (image->w, image->h);

float *res = result;
Uint8 *pixel = vis;
for (int y = 0; y < image->h; ++y)
{
SDL_UnlockSurface (image);
for (int x = 0; x < image->w; ++x)
{
*res = f (array, image->w, image->h, x, y);
pixel[0] = min (max (*res, 0), 255);
pixel[1] = min (max (*res, 0), 255);
pixel[2] = min (max (*res, 0), 255);

++res;
pixel += 3;
}
}

return array_to_surface (vis, image->flags, image->w, image->h,
image->format->BitsPerPixel, image->format->Rmask,
image->format->Gmask, image->format->Bmask,
image->format->Amask);
}

int
Expand Down Expand Up @@ -92,25 +103,14 @@ main (int argc, char *argv[])
fprintf (stderr, "Could not set video mode: %s\n", SDL_GetError ());
return (EXIT_FAILURE);
}
SDL_Surface *energy =
SDL_CreateRGBSurface (image->flags | SDL_SWSURFACE, image->w, image->h,
image->format->BitsPerPixel, image->format->Rmask,
image->format->Gmask, image->format->Bmask,
image->format->Amask);
if (!energy)
{
fprintf (stderr, "Could not create an energy buffer: %s\n",
SDL_GetError ());
return (EXIT_FAILURE);
}


/* Main loop */
int running = 1;
Uint32 black = SDL_MapRGB (screen->format, 0, 0, 0);
SDL_Event event;
Uint8 (*energy_function) (SDL_Surface *, int, int);
energy_function = steepest_neighbor;
energy_function f = gradient_magnitude;
SDL_Surface *energy = energize (image, f);
while (running)
{
while (SDL_PollEvent (&event))
Expand All @@ -124,16 +124,17 @@ main (int argc, char *argv[])
switch (event.key.keysym.sym)
{
case SDLK_RETURN:
if (energy_function == steepest_neighbor)
if (f == steepest_neighbor)
{
energy_function = gradient_magnitude;
f = gradient_magnitude;
}
else
{
energy_function = steepest_neighbor;
f = steepest_neighbor;
}

energize (image, energy, energy_function);
SDL_FreeSurface (energy);
energy = energize (image, f);
break;
default:
break;
Expand Down
2 changes: 1 addition & 1 deletion util.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) < (b) ? (b) : (a))

#define abs(a) ((a) > 0 ? (a) : -(a))
#define value_from_rgb(r, g, b) (max (max ((r), (g)), (b)))

#endif

0 comments on commit 5143748

Please sign in to comment.