diff --git a/Makefile b/Makefile index 554dcde..12a9cca 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,17 @@ +BASE_DIR=../ +include Makefile.wasm.inc + # SOD does not generally require a Makefile to build. Just drop sod.c and its accompanying # header files on your source tree and you are done. -CC = clang -CFLAGS = -lm -Ofast -march=native -Wall -std=c99 +NCC = clang +NCFLAGS = -I. -DCPU_FREQ=3600 -O3 -lm -DSOD_DISABLE_CNN -DLIBCOX_DISABLE_DISK_IO +WCFLAGS = -DWASM -I. -DSOD_DISABLE_CNN -lm -DLIBCOX_DISABLE_DISK_IO #sod: sod.c # $(CC) sod.c samples/cnn_face_detection.c -o sod_face_detect -I. $(CFLAGS) EXT = out +WEXT = wout SAMPLES = resize_image \ license_plate_detection @@ -36,8 +41,14 @@ SAMPLES = resize_image \ # sobel_operator_img SAMPLESOUT = $(SAMPLES:%=%.$(EXT)) +SAMPLESWOUT = $(SAMPLES:%=%.$(WEXT)) + +all: clean dir copy -all: clean dir copy samples +native: samples +wasm: samples.wasm +# samples.wasm +# samples dir: mkdir -p bin/ @@ -48,8 +59,15 @@ copy: samples: $(SAMPLESOUT) +samples.wasm: $(SAMPLESWOUT) + %.$(EXT): - $(CC) $(CFLAGS) -I. -lm sod.c samples/$(@:%.$(EXT)=%.c) -o bin/$@ + $(NCC) $(NCFLAGS) sod.c samples/$(@:%.$(EXT)=%.c) -o bin/$@ + +%.$(WEXT): + $(WASMCC) $(WCFLAGS) $(WASMCFLAGS) $(OPTFLAGS) sod.c samples/$(@:%.$(WEXT)=%.c) $(DUMMY) -o bin/$(@:%.$(WEXT)=%.wasm) + $(SFCC) bin/$(@:%.$(WEXT)=%.wasm) -o bin/$(@:%.$(WEXT)=%.bc) + $(CC) ${CFLAGS} ${EXTRA_CFLAGS} $(OPTFLAGS) -D$(USE_MEM) bin/$(@:%.$(WEXT)=%.bc) $(RT_LIBC) $(RT_RT) ${MEMC} -o bin/$@ clean: rm -f bin/* diff --git a/Makefile.wasm.inc b/Makefile.wasm.inc new file mode 100644 index 0000000..fb3894e --- /dev/null +++ b/Makefile.wasm.inc @@ -0,0 +1,38 @@ +BASE=awsm +SFCC=silverfish +CC=clang +WASMCC=wasm32-unknown-unknown-wasm-clang + +OPTFLAGS=-O3 -flto +# same stack-size for all +WASMLINKFLAGS=-Wl,-z,stack-size=524288,--allow-undefined,--no-threads,--stack-first,--no-entry,--export-all,--export=main,--export=dummy +WASMCFLAGS=${WASMLINKFLAGS} -nostartfiles + +MEMC_64=64bit_nix.c +MEMC_NO=no_protection.c +MEMC_GEN=generic.c +MEMC_MPX=mpx.c +MEMC_SEG=segmented.c + +# for silverfish +RT_DIR=${BASE_DIR}/runtime/ +RT_MEM=${RT_DIR}/memory/ +RT_LIBC=${RT_DIR}/libc/libc_backing.c +RT_RT=${RT_DIR}/runtime.c + +MEMC=${RT_MEM}/${MEMC_64} +DUMMY=${BASE_DIR}/code_benches/dummy.c + +# for awsm +ABASE_DIR=${BASE_DIR}/../ +ART_DIR=${ABASE_DIR}/runtime/ +ART_INC=${ART_DIR}/include/ + +USE_MEM=USE_MEM_VM +ifeq ($(USE_MEM),USE_MEM_VM) +AMEMC=${ART_DIR}/compiletime/memory/${MEMC_64} +endif +WASMISA=${ART_DIR}/compiletime/instr.c + +ABIN_DIR=${ART_DIR}/bin/ +TMP_DIR=tmp/ diff --git a/get_time.h b/get_time.h new file mode 100644 index 0000000..89e5d71 --- /dev/null +++ b/get_time.h @@ -0,0 +1,44 @@ +#ifndef GET_TIME_H +#define GET_TIME_H + +#include +#include + +#ifndef WASM +#ifndef CPU_FREQ +#define CPU_FREQ 1000 +#endif +#endif + +static unsigned long long +get_time() +{ +#if 0 + unsigned long long int ret = 0; + unsigned int cycles_lo; + unsigned int cycles_hi; + __asm__ volatile ("RDTSC" : "=a" (cycles_lo), "=d" (cycles_hi)); + ret = (unsigned long long int)cycles_hi << 32 | cycles_lo; + + return ret; +#else + struct timeval Tp; + int stat; + stat = gettimeofday (&Tp, NULL); + if (stat != 0) + printf ("Error return from gettimeofday: %d", stat); + return (Tp.tv_sec * 1000000 + Tp.tv_usec); +#endif +} + +static inline void +print_time(unsigned long long s, unsigned long long e) +{ +#if 0 + printf("%llu cycs, %llu us\n", e - s, (e - s) / CPU_FREQ); +#else + printf("%llu us\n", e - s); +#endif +} + +#endif /* GET_TIME_H */ diff --git a/samples/license_plate_detection.c b/samples/license_plate_detection.c index 3952bcf..d052036 100644 --- a/samples/license_plate_detection.c +++ b/samples/license_plate_detection.c @@ -24,7 +24,13 @@ * https://sod.pixlab.io/api.html */ #include +#include +#include +#include +#include +#include #include "sod.h" +#include "get_time.h" /* * Frontal License Plate detection without deep-learning. Only image processing code. */ @@ -45,12 +51,35 @@ static int filter_cb(int width, int height) } int main(int argc, char *argv[]) { + struct stat stbf; + unsigned char *zInpbuf = NULL; + unsigned long long s = get_time(), e; /* Input image (pass a path or use the test image shipped with the samples ZIP archive) */ const char *zInput = argc > 1 ? argv[1] : "./plate.jpg"; /* Processed output image path */ - const char *zOut = argc > 2 ? argv[2] : "./out_plate.png"; + const char *zOut = argc > 2 ? argv[2] : "./out_plate.jpg"; + int r = stat(zInput, &stbf); + if (r < 0) { + perror("stat"); + return -1; + } + zInpbuf = malloc(stbf.st_size); + //memset(zInpbuf, 0, stbf.st_size); + int zIfd = open(zInput, O_RDONLY); + if (zIfd < 0) { + perror("open"); + return -1; + } + r = read(zIfd, zInpbuf, stbf.st_size); + if (r < stbf.st_size) { + perror("read"); + return -1; + } + close(zIfd); + /* Load the input image in the grayscale colorspace */ - sod_img imgIn = sod_img_load_grayscale(zInput); + //sod_img imgIn = sod_img_load_grayscale(zInput); + sod_img imgIn = sod_img_load_from_mem(zInpbuf, stbf.st_size, SOD_IMG_GRAYSCALE); if (imgIn.data == 0) { /* Invalid path, unsupported format, memory failure, etc. */ puts("Cannot load input image..exiting"); @@ -59,7 +88,8 @@ int main(int argc, char *argv[]) /* A full color copy of the input image so we can draw rose boxes * marking the plate in question if any. */ - sod_img imgCopy = sod_img_load_color(zInput); + //sod_img imgCopy = sod_img_load_color(zInput); + sod_img imgCopy = sod_img_load_from_mem(zInpbuf, stbf.st_size, SOD_IMG_COLOR); /* Obtain a binary image first */ sod_img binImg = sod_threshold_image(imgIn, 0.5); /* @@ -85,12 +115,14 @@ int main(int argc, char *argv[]) } sod_image_blob_boxes_release(box); /* Finally save the output image to the specified path */ - sod_img_save_as_png(imgCopy, zOut); + sod_img_save_as_jpeg(imgCopy, zOut, 0); /* Cleanup */ sod_free_image(imgIn); sod_free_image(cannyImg); sod_free_image(binImg); sod_free_image(dilImg); sod_free_image(imgCopy); + e = get_time(); + print_time(s, e); return 0; -} \ No newline at end of file +} diff --git a/samples/resize_image.c b/samples/resize_image.c index 52afa42..c910aa6 100644 --- a/samples/resize_image.c +++ b/samples/resize_image.c @@ -24,18 +24,47 @@ * https://sod.pixlab.io/api.html */ #include +#include +#include +#include +#include +#include #include "sod.h" +#include "get_time.h" /* * Resize an image (Minify) to half its original size. */ int main(int argc, char *argv[]) { + struct stat stbf; + unsigned char *zInpbuf = NULL; + unsigned long long s = get_time(), e; /* Input image (pass a path or use the test image shipped with the samples ZIP archive) */ const char *zInput = argc > 1 ? argv[1] : "./flower.jpg"; /* Processed output image path */ const char *zOut = argc > 2 ? argv[2] : "./out_rz.png"; /* Load the input image in full color */ - sod_img imgIn = sod_img_load_from_file(zInput, SOD_IMG_COLOR /* full color channels */); + int r = stat(zInput, &stbf); + if (r < 0) { + perror("stat"); + return -1; + } + zInpbuf = malloc(stbf.st_size); + //memset(zInpbuf, 0, stbf.st_size); + int zIfd = open(zInput, O_RDONLY); + if (zIfd < 0) { + perror("open"); + return -1; + } + r = read(zIfd, zInpbuf, stbf.st_size); + if (r < stbf.st_size) { + perror("read"); + return -1; + } + close(zIfd); + +// sod_img imgIn = sod_img_load_from_file(zInput, SOD_IMG_COLOR /* full color channels */); + sod_img imgIn = sod_img_load_from_mem(zInpbuf, stbf.st_size, SOD_IMG_COLOR /* full color channels */); if (imgIn.data == 0) { /* Invalid path, unsupported format, memory failure, etc. */ puts("Cannot load input image..exiting"); @@ -48,8 +77,11 @@ int main(int argc, char *argv[]) sod_img rz = sod_resize_image(imgIn, newWidth, newHeight); /* Save the resized image to the specified path */ sod_img_save_as_png(rz, zOut); + //sod_img_save_as_jpeg(rz, zOut, 0); /* Cleanup */ sod_free_image(imgIn); sod_free_image(rz); + e = get_time(); + print_time(s, e); return 0; -} \ No newline at end of file +}