Skip to content

Commit

Permalink
Implement interactive demo program
Browse files Browse the repository at this point in the history
  • Loading branch information
61315 committed Feb 18, 2022
1 parent 03b7275 commit 6035fa3
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 21 deletions.
11 changes: 8 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ INC_FLAGS := $(addprefix -I,$(INC_DIRS))
STATIC_LIB := $(LIB_DIR)/libresynthesizer.a

EXAMPLE_DIR := examples
EXAMPLES := $(EXAMPLE_DIR)/dummy $(EXAMPLE_DIR)/ppm
EXAMPLES := $(EXAMPLE_DIR)/hello $(EXAMPLE_DIR)/ppm $(EXAMPLE_DIR)/painter

# -g -Wall -Wextra -Werror -std=c99 -pedantic-errors
# TODO: Try both -Werror and -pedantic-errors after all the chores are done.
Expand All @@ -41,16 +41,21 @@ $(BUILD_DIR)/%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@

# Build the example executables.
$(EXAMPLE_DIR)/dummy: examples/dummy.c $(STATIC_LIB)
$(EXAMPLE_DIR)/hello: examples/hello.c $(STATIC_LIB)
@echo "\033[1;92mBuilding $@\033[0m"
mkdir -p $(dir $@)
$(CC) $(CFLAGS) -o $@ examples/dummy.c $(LDFLAGS) $(INC_FLAGS) $(STATIC_LIB)
$(CC) $(CFLAGS) -o $@ examples/hello.c $(LDFLAGS) $(INC_FLAGS) $(STATIC_LIB)

$(EXAMPLE_DIR)/ppm: examples/ppm.c $(STATIC_LIB)
@echo "\033[1;92mBuilding $@\033[0m"
mkdir -p $(dir $@)
$(CC) $(CFLAGS) -o $@ examples/ppm.c $(LDFLAGS) $(INC_FLAGS) $(STATIC_LIB)

$(EXAMPLE_DIR)/painter: examples/painter.c $(STATIC_LIB)
@echo "\033[1;92mBuilding $@\033[0m"
mkdir -p $(dir $@)
$(CC) $(CFLAGS) -o $@ examples/painter.c $(LDFLAGS) $(INC_FLAGS) $(STATIC_LIB) $(shell pkg-config --cflags --libs sdl2)

# Run the executable(ppm) against the sample images with varying parameters.
test: $(EXAMPLES)
echo "\033[1;92mTesting...\033[0m"
Expand Down
13 changes: 5 additions & 8 deletions examples/dummy.c → examples/hello.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// examples/dummy.c
// examples/hello.c
#include <stdlib.h>
#include <stdio.h>

Expand All @@ -15,13 +15,10 @@ int main()

error = imageSynth(source_image_buffer, mask_image_buffer, T_RGB, params, NULL, NULL, &cancel_token);

if (error != 0)
{
printf("Task failed with the error code: %d\n", error);
exit(EXIT_FAILURE);
}

printf("Task finished\n");
// We're sending empty source/mask buffers.
// imageSynth() should return `IMAGE_SYNTH_ERROR_EMPTY_TARGET`
if (error == IMAGE_SYNTH_ERROR_EMPTY_TARGET)
puts("hello");

return EXIT_SUCCESS;
}
181 changes: 181 additions & 0 deletions examples/painter.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
/* examples/painter.c
* $ ./painter source!
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#include "SDL2/SDL.h"

#include "imageSynth.h"

/* PPM(P6) Read/Write snippets
*
* Adopted from:
* https://github.com/skeeto/scratch/blob/master/animation/pixelsort.c
*/
struct ppm
{
long width;
long height;
unsigned char data[];
};

static struct ppm *ppm_create(long width, long height)
{
struct ppm *m = malloc(sizeof(*m) + width * height * 3);
m->width = width;
m->height = height;
return m;
}

static struct ppm *ppm_read(const char *filename)
{
FILE *f = fopen(filename, "rb");
if (f == NULL)
{
perror(filename);
return NULL;
}
struct ppm *m;
long width, height;
if (fscanf(f, "P6 %ld%ld%*d%*c", &width, &height) < 2)
{
fprintf(stderr, "Not a valid PPM image.\n");
return NULL;
}
m = ppm_create(width, height);
fread(m->data, width * height, 3, f);
fclose(f);
return m;
}

SDL_Window *window = NULL;
SDL_Surface *screen_surface = NULL;
SDL_Surface *source_surface = NULL;
SDL_Surface *mask_surface = NULL;
SDL_Rect brush = {.x = 0, .y = 0, .w = 16, .h = 16};

int main(int argc, char **argv)
{
const char *source_in = argc > 1 ? argv[1] : NULL;
struct ppm *source_ppm = ppm_read(source_in);

if (source_ppm == NULL)
{
fprintf(stderr, "Source image not provided.\n");
exit(EXIT_FAILURE);
}

const int w = source_ppm->width;
const int h = source_ppm->width;
unsigned char *mask_surface_data = malloc(w * h * 4 * sizeof(*mask_surface_data));
unsigned char *mask_buffer_data = malloc(w * h * sizeof(*mask_buffer_data));

if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
fprintf(stderr, "error %s \n", SDL_GetError());
exit(EXIT_FAILURE);
}

window = SDL_CreateWindow("resynthesizer", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, w, h, SDL_WINDOW_SHOWN);
screen_surface = SDL_GetWindowSurface(window);
source_surface = SDL_CreateRGBSurfaceFrom(
source_ppm->data, w, h, 24, w * 3, 0xFF, 0xFF00, 0xFF0000, 0);
mask_surface = SDL_CreateRGBSurfaceFrom(
mask_surface_data, w, h, 32, w * 4, 0xFF, 0xFF00, 0xFF0000, 0xFF000000);

ImageBuffer source_buffer = {
.data = source_ppm->data,
.width = w,
.height = h,
.rowBytes = w * 3,
};

ImageBuffer mask_buffer = {
.data = mask_buffer_data,
.width = w,
.height = h,
.rowBytes = w,
};

TImageSynthParameters params = {
.matchContextType = 1,
.mapWeight = 0.5f,
.sensitivityToOutliers = 0.117f,
.patchSize = 30,
.maxProbeCount = 200,
};

int cancel = 0;
bool is_running = true;
bool pressed = false;
SDL_Event event;

while (is_running)
{
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_MOUSEMOTION:
brush.x = event.motion.x - brush.w / 2;
brush.y = event.motion.y - brush.h / 2;
if (!pressed)
memset(mask_surface_data, 0, w * h * 4 * sizeof(char));
SDL_FillRect(mask_surface, &brush, SDL_MapRGB(mask_surface->format, 0xFF, 0xFF, 0xFF));
break;
case SDL_MOUSEBUTTONDOWN:
pressed = true;
SDL_FillRect(mask_surface, &brush, SDL_MapRGB(mask_surface->format, 0xFF, 0xFF, 0xFF));
break;
case SDL_MOUSEBUTTONUP:
pressed = false;
// Do the synthesis opration
for (int i = 0; i < w * h; ++i)
mask_buffer_data[i] = mask_surface_data[i * 4];
imageSynth(&source_buffer, &mask_buffer, T_RGB, &params, NULL, NULL, &cancel);
memset(mask_surface_data, 0, w * h * 4 * sizeof(char));
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
// Quit
is_running = false;
break;
case SDLK_r:
// Reset source image
break;
case SDLK_LEFTBRACKET:
// Increase brush size
brush.w--;
brush.h--;
break;
case SDLK_RIGHTBRACKET:
// Decrease brush size
brush.w++;
brush.h++;
break;
}
break;
}
}
SDL_BlitSurface(source_surface, NULL, screen_surface, NULL);
SDL_BlitSurface(mask_surface, NULL, screen_surface, NULL);
SDL_UpdateWindowSurface(window);
SDL_Delay(1);
}

SDL_FreeSurface(mask_surface);
SDL_FreeSurface(source_surface);
SDL_DestroyWindow(window);
SDL_Quit();

free(mask_buffer_data);
free(mask_surface_data);
free(source_ppm);

return EXIT_SUCCESS;
}
20 changes: 10 additions & 10 deletions examples/ppm.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/* examples/ppm.c
* $ ./ppm source! mask! result? context? neighbors? probes?
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>

#include <imageSynth.h>
#include "imageSynth.h"

/* PPM(P6) Read/Write snippets
*
* Borrowed and modified from:
* Adopted from:
* https://github.com/skeeto/scratch/blob/master/animation/pixelsort.c
*/
struct ppm
Expand All @@ -18,25 +18,22 @@ struct ppm
unsigned char data[];
};

static struct ppm *
ppm_create(long width, long height)
static struct ppm *ppm_create(long width, long height)
{
struct ppm *m = malloc(sizeof(*m) + width * height * 3);
m->width = width;
m->height = height;
return m;
}

static void
ppm_write(struct ppm *m, FILE *f)
static void ppm_write(struct ppm *m, FILE *f)
{
fprintf(f, "P6\n%ld %ld\n255\n", m->width, m->height);
if (!fwrite(m->data, m->width * m->height, 3, f))
exit(EXIT_FAILURE);
}

static struct ppm *
ppm_read(const char *filename)
static struct ppm *ppm_read(const char *filename)
{
FILE *f = fopen(filename, "rb");
if (f == NULL)
Expand All @@ -47,7 +44,10 @@ ppm_read(const char *filename)
struct ppm *m;
long width, height;
if (fscanf(f, "P6 %ld%ld%*d%*c", &width, &height) < 2)
{
fprintf(stderr, "Not a valid PPM image.\n");
return NULL;
}
m = ppm_create(width, height);
fread(m->data, width * height, 3, f);
fclose(f);
Expand Down Expand Up @@ -115,7 +115,7 @@ int main(int argc, char **argv)

error = imageSynth(&source_buffer, &mask_buffer, T_RGB, &params, NULL, NULL, &cancel_token);

if (error != 0)
if (error != IMAGE_SYNTH_SUCCESS)
fprintf(stderr, "Operation failed. Error code: %d\n", error);

FILE *result_file = fopen(result_out, "wb");
Expand Down

0 comments on commit 6035fa3

Please sign in to comment.