From fc61e7fcb3a30659580d88ba85cb71c8f72a1e0b Mon Sep 17 00:00:00 2001 From: Yeonji Date: Wed, 12 Sep 2018 22:23:24 +0800 Subject: [PATCH] first commit --- Makefile | 47 ++++ arch.md | 14 ++ src/bmp.c | 554 ++++++++++++++++++++++++++++++++++++++++++ src/bmp.h | 29 +++ src/config.h | 27 ++ src/image.c | 73 ++++++ src/image.h | 70 ++++++ src/image_average.c | 43 ++++ src/image_average.h | 28 +++ src/image_binary.c | 50 ++++ src/image_binary.h | 28 +++ src/image_edge_dect.c | 71 ++++++ src/image_edge_dect.h | 28 +++ src/image_gray.c | 54 ++++ src/image_gray.h | 28 +++ src/main.c | 153 ++++++++++++ src/path.c | 43 ++++ src/path.h | 29 +++ src/ppm.c | 207 ++++++++++++++++ src/ppm.h | 29 +++ src/utils.c | 99 ++++++++ src/utils.h | 30 +++ src/wave.c | 184 ++++++++++++++ src/wave.h | 36 +++ 24 files changed, 1954 insertions(+) create mode 100644 Makefile create mode 100644 arch.md create mode 100644 src/bmp.c create mode 100644 src/bmp.h create mode 100644 src/config.h create mode 100644 src/image.c create mode 100644 src/image.h create mode 100644 src/image_average.c create mode 100644 src/image_average.h create mode 100644 src/image_binary.c create mode 100644 src/image_binary.h create mode 100644 src/image_edge_dect.c create mode 100644 src/image_edge_dect.h create mode 100644 src/image_gray.c create mode 100644 src/image_gray.h create mode 100644 src/main.c create mode 100644 src/path.c create mode 100644 src/path.h create mode 100644 src/ppm.c create mode 100644 src/ppm.h create mode 100644 src/utils.c create mode 100644 src/utils.h create mode 100644 src/wave.c create mode 100644 src/wave.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..58c1d4c --- /dev/null +++ b/Makefile @@ -0,0 +1,47 @@ +DIR_SRC = ./src +DIR_OBJ = ./obj +DIR_BIN = ./bin + +SRC = $(wildcard ${DIR_SRC}/*.c) +OBJ = $(patsubst %.c,${DIR_OBJ}/%.o,$(notdir ${SRC})) + +CC = clang +CFLAGS = -g -pipe -O2 -Wall -Wextra -std=c99 -Wcomment -I${DIR_SRC} + +TARGET = v2w + +BIN_TARGET = ${DIR_BIN}/${TARGET} + +${BIN_TARGET}:${OBJ} + $(CC) $(CFLAGS) $(OBJ) -o $@ -lprofiler + +${DIR_OBJ}/%.o:${DIR_SRC}/%.c ${DIR_OBJ} + $(CC) $(CFLAGS) -c $< -o $@ + +${DIR_OBJ}: + @mkdir -p $@ + +${DIR_BIN}: + @mkdir -p $@ + +prof.txt: + @pprof --text ./bin/v2w ./test.prof > ./prof.txt + +out.mp4: + @echo "Compose Video." + @ffmpeg -loglevel 0 -stats -r 24 -i ./tmp/frames_proc/v-%05d.bmp -c:v libx264 -vf fps=24 -pix_fmt yuv420p ./out_tmp.mp4 + @echo "Integrate Audio." + @ffmpeg -loglevel 0 -stats -i ./out_tmp.mp4 -i ./tmp/Sample.aac -acodec copy -vcodec copy out.mp4 + rm out_tmp.mp4 + +.PHONY:clean run + +clean: + rm -f ${DIR_OBJ}/*.o + rm -rf ./tmp + rm -f out.mp4 + rm -f ./tmp/Sample.aac + rm -f ${DIR_BIN}/${TARGET} + +run: + @time ${BIN_TARGET} \ No newline at end of file diff --git a/arch.md b/arch.md new file mode 100644 index 0000000..dc598a4 --- /dev/null +++ b/arch.md @@ -0,0 +1,14 @@ +# Arch + +0. Getting fps and length by calling the ffmpeg program +1. Transform video to BMP frame files by calling the ffmpeg program +2. Read one BMP file to image struct +3. Thresholding +4. Edge Detection by convolution and transform to absolute value +5. Thresholding +6. Select starting point (random for the first, and nearest for privies frame) +7. Get Route Array by doing graph traversal using depth first search +8. Adjust Route Array to fixed length using cubic Hermite interpolator +9. Loop from 2 to 8 to generate all Route Arrays for every frame +10. Merge Route Arrays to one Array +11. transform Route Array to wav file \ No newline at end of file diff --git a/src/bmp.c b/src/bmp.c new file mode 100644 index 0000000..727c194 --- /dev/null +++ b/src/bmp.c @@ -0,0 +1,554 @@ +/****************************************************************************** +The MIT License +Copyright (c) 2017-2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include +#include +#include +#include +#include +#include + + + +/************************************************** + + BMP Basic Structs + +**************************************************/ + +/* BMP Header Struct */ +typedef struct { + uint16_t bfType; + uint32_t bfSize; + uint16_t bfReserved1; + uint16_t bfReserved2; + uint32_t bfOffBits; +}__attribute__((packed)) bmp_header_t; + +/* Magic Number in BMP Header (bfType) */ +#define WINDOWS_BMP 0X4D42 /*BM*/ +#define OS2_BITMAP_ARRAY 0X4142 /*BA*/ +#define OS2_COLOR_ICON 0X4943 /*CI*/ +#define OS2_COLOR_POINTER 0X5043 /*CP*/ +#define OS2_ICON 0X4349 /*IC*/ +#define OS2_POINTER 0X5450 /*PT*/ + +/* DIB Header Struct */ +typedef struct { + uint32_t biSize; + uint32_t biWidth; + uint32_t biHeight; + uint16_t biPlanes; + uint16_t biBitCount; + uint32_t biCompression; + uint32_t biSizeImage; + uint32_t biXPelsPerMeter; + uint32_t biYPelsPerMeter; + uint32_t biClrUsed; + uint32_t biClrImportant; +}bmp_info_t; + +#define DIB_BITMAPCOREHEADER_SIZE 12 +#define DIB_OS22XBITMAPHEADER_SIZE 16 +#define DIB_BITMAPINFOHEADER_SIZE 40 +#define DIB_BITMAPV2INFOHEADER_SIZE 52 +#define DIB_BITMAPV3INFOHEADER_SIZE 56 +#define DIB_OS22XBITMAPHEADER2_SIZE 64 +#define DIB_BITMAPV4HEADER_SIZE 108 +#define DIB_BITMAPV5HEADER_SIZE 124 + +#define COMPRESS_BI_RGB 0 +#define COMPRESS_BI_RLE8 1 +#define COMPRESS_BI_RLE4 2 +#define COMPRESS_BI_BITFIELDS 3 +#define COMPRESS_BI_JPEG 4 +#define COMPRESS_BI_PNG 5 +#define COMPRESS_BI_ALPHABITFIELDS 6 +#define COMPRESS_BI_CMYK 11 +#define COMPRESS_BI_CMYKRLE8 12 +#define COMPRESS_BI_CMYKRLE4 13 + +#define CHANNEL_R 0 +#define CHANNEL_G 1 +#define CHANNEL_B 2 +#define CHANNEL_A 3 + +#define CHANNEL_CNT 4 +#define CHANNEL_ALL 4 + + + +/************************************************** + + BMP Strings + +**************************************************/ + +static const char * string_unknown = "Unknown"; +static const char * string_windows_bmp = \ + "Windows 3.1x bitmap (424D)"; +static const char * string_os2_bitmap_array = \ + "OS/2 struct bitmap array (4241)"; +static const char * string_os2_color_icon = \ + "OS/2 struct color icon (4349)"; +static const char * string_os2_color_pointer = \ + "OS/2 const color pointer (4350)"; +static const char * string_os2_icon = \ + "OS/2 struct icon (4943)"; +static const char * string_os2_pointer = \ + "OS/2 pointer (5054)"; + + +static const char * string_bitmapcoreheader = \ + "BMP core header"; +static const char * string_os22xbitmapheader = \ + "OS/2 BMP header"; +static const char * string_bitmapinfoheader = \ + "Standard BMP header"; +static const char * string_bitmapv2infoheader = \ + "Adobe Photoshop Externed BMP header ver.2"; +static const char * string_bitmapv3infoheader = \ + "Adobe Photoshop Externed BMP header ver.3"; +static const char * string_os22xbitmapheader2 = \ + "OS/2 BMP header ver.2"; +static const char * string_bitmapv4header = \ + "Standard BMP header ver.4"; +static const char * string_bitmapv5header = \ + "Standard BMP header ver.5"; + + +static const char * string_compress_bi_rgb = \ + "None"; +static const char * string_compress_bi_rle8 = \ + "RLE 8-bit/pixel"; +static const char * string_compress_bi_rle4 = \ + "RLE 4-bit/pixel"; +static const char * string_compress_bi_bitfields = \ + "RGBA (Perhaps Huffman 1D)"; +static const char * string_compress_bi_jpeg = \ + "JPEG image for printing"; +static const char * string_compress_bi_png = \ + "PNG image for printing"; +static const char * string_compress_bi_alphabitfields = \ + "RGBA bit field masks on Windows CE 5.0 with .NET 4.0 or later"; +static const char * string_compress_bi_cmyk = \ + "Windows Metafile CMYK"; +static const char * string_compress_bi_cmykrle8 = \ + "Windows Metafile CMYK with RLE 8-bit/pixel"; +static const char * string_compress_bi_cmykrle4 = \ + "Windows Metafile CMYK with RLE 4-bit/pixel"; + + +const char * get_bmp_type_string(const int16_t type_word) +{ + switch(type_word) + { + case WINDOWS_BMP : return string_windows_bmp ; break; + case OS2_BITMAP_ARRAY : return string_os2_bitmap_array ; break; + case OS2_COLOR_ICON : return string_os2_color_icon ; break; + case OS2_COLOR_POINTER : return string_os2_color_pointer ; break; + case OS2_ICON : return string_os2_icon ; break; + case OS2_POINTER : return string_os2_pointer ; break; + default : return string_unknown; + }; + return string_unknown; +} + +const char * get_bmp_dib_string(uint32_t size) +{ + switch(size) + { + case DIB_BITMAPCOREHEADER_SIZE : + return string_bitmapcoreheader ; break; + + case DIB_OS22XBITMAPHEADER_SIZE : + return string_os22xbitmapheader ; break; + + case DIB_BITMAPINFOHEADER_SIZE : + return string_bitmapinfoheader ; break; + + case DIB_BITMAPV2INFOHEADER_SIZE : + return string_bitmapv2infoheader ; break; + + case DIB_BITMAPV3INFOHEADER_SIZE : + return string_bitmapv3infoheader ; break; + + case DIB_OS22XBITMAPHEADER2_SIZE : + return string_os22xbitmapheader2 ; break; + + case DIB_BITMAPV4HEADER_SIZE : + return string_bitmapv4header ; break; + + case DIB_BITMAPV5HEADER_SIZE : + return string_bitmapv5header ; break; + + default: + return string_unknown; + } + + return string_unknown; +} + +const char * get_bmp_comp_string(uint32_t method){ + switch(method) + { + case COMPRESS_BI_RGB : + return string_compress_bi_rgb ; break; + + case COMPRESS_BI_RLE8 : + return string_compress_bi_rle8 ; break; + + case COMPRESS_BI_RLE4 : + return string_compress_bi_rle4 ; break; + + case COMPRESS_BI_BITFIELDS : + return string_compress_bi_bitfields ; break; + + case COMPRESS_BI_JPEG : + return string_compress_bi_jpeg ; break; + + case COMPRESS_BI_PNG : + return string_compress_bi_png ; break; + + case COMPRESS_BI_ALPHABITFIELDS : + return string_compress_bi_alphabitfields ; break; + + case COMPRESS_BI_CMYK : + return string_compress_bi_cmyk ; break; + + case COMPRESS_BI_CMYKRLE8 : + return string_compress_bi_cmykrle8 ; break; + + case COMPRESS_BI_CMYKRLE4 : + return string_compress_bi_cmykrle4 ; break; + + default: + return string_unknown; + } + return string_unknown; +} + + + +/************************************************** + + BMP File Basic Struct + +**************************************************/ + +typedef struct{ + FILE *fp; + image_t *img; + + bmp_header_t header; + bmp_info_t info; + uint8_t *data; + + int32_t data_offset; + int32_t data_size; + int32_t img_width; + int32_t img_height; + int32_t color_depth; + int32_t width_fixed; +} bmp_file_t; + + + +/************************************************** + + BMP Data Encode && Decode + +**************************************************/ + +int bmp_decode_data_24(bmp_file_t *bmp) +{ + int32_t line = bmp->info.biHeight; + int32_t column = 0; + + uint8_t *src; + + for (line--; line >= 0; line--) { + src = bmp->data + line * bmp->width_fixed; + for(column = 0; column < bmp->img->width; column++) { + image_pixel(bmp->img, column, (bmp->img->height - line - 1))[IMG_CHANNEL_B] = *src; + src ++; + image_pixel(bmp->img, column, (bmp->img->height - line - 1))[IMG_CHANNEL_G] = *src; + src ++; + image_pixel(bmp->img, column, (bmp->img->height - line - 1))[IMG_CHANNEL_R] = *src; + src ++; + } + } + + return 0; +} + +int bmp_encode_data_24(bmp_file_t *bmp) +{ + int32_t line = bmp->img->height; + int32_t column = 0; + + int32_t s; + uint8_t *dst; + + int32_t width; + + bmp->width_fixed = width = bmp->img->width * 3; + + if (bmp->width_fixed % 4 != 0) { + bmp->width_fixed = (bmp->width_fixed - bmp->width_fixed % 4 + 4); + } + + bmp->data_size = bmp->width_fixed * line * sizeof(uint8_t); + + bmp->data = malloc(bmp->data_size); + + dst = bmp->data; + + for (line = 0; line < bmp->img->height; line++) { + for(column = 0; column < bmp->img->width; column++) { + s = round(image_pixel(bmp->img, column, (bmp->img->height - line - 1))[IMG_CHANNEL_B]); + if (s > 255) s = 255; + if (s < 0) s = 0; + *dst = s; + dst ++; + + s = round(image_pixel(bmp->img, column, (bmp->img->height - line - 1))[IMG_CHANNEL_G]); + if (s > 255) s = 255; + if (s < 0) s = 0; + *dst = s; + dst ++; + + s = round(image_pixel(bmp->img, column, (bmp->img->height - line - 1))[IMG_CHANNEL_R]); + if (s > 255) s = 255; + if (s < 0) s = 0; + *dst = s; + dst ++; + } + + column = column * 3; + + while (column < bmp->width_fixed) { + *dst = 0; + column ++; + dst ++; + } + } + + return 0; +} + +int bmp_encode_data(bmp_file_t *bmp) +{ + return bmp_encode_data_24(bmp); +} + +int bmp_decode_data(bmp_file_t *bmp) +{ + return bmp_decode_data_24(bmp); +} + + +/************************************************** + + BMP Srtuct Read + +**************************************************/ + +int bmp_read_header(bmp_file_t *bmp) +{ + /* Read Header */ + fseek(bmp->fp, 0, SEEK_SET); + if(fread(&bmp->header, sizeof(bmp->header), 1, bmp->fp) != 1){ + fprintf(stderr, "Broken File: Can not read header.\n"); + return -1; + } + + /* Check if Valid BMP file */ + if(bmp->header.bfType != WINDOWS_BMP){ + fprintf(stderr, "Unsupported Format: %s.\n", \ + get_bmp_type_string(bmp->header.bfType)); + return -1; + } + + bmp->data_offset = bmp->header.bfOffBits; + + return 0; +} + +int bmp_read_dib(bmp_file_t *bmp) +{ + /* Read DIB Info Chunk */ + fseek(bmp->fp, 14, SEEK_SET); + + /* get bmp information header */ + if( fread(&bmp->info, sizeof(bmp->info), 1, bmp->fp) != 1 ) { + fprintf(stderr, "Cannot Read DIB info.\n"); + return -1; + } + + /* unsupported bmp format */ + if(bmp->info.biSize < DIB_BITMAPINFOHEADER_SIZE){ + fprintf(stderr, "Unsupported DIB Format: %s.\n", \ + get_bmp_dib_string(bmp->info.biSize)); + return -1; + } + + bmp->img_width = bmp->info.biWidth; + bmp->img_height = bmp->info.biHeight; + + bmp->color_depth = bmp->info.biBitCount; + + bmp->width_fixed = (bmp->info.biWidth * bmp->color_depth) / 8; + + if (bmp->width_fixed % 4 != 0) { + bmp->width_fixed = (bmp->width_fixed - bmp->width_fixed % 4 + 4); + } + + bmp->data_size = bmp->width_fixed * bmp->info.biHeight; + + return 0; +} + +int bmp_read_data(bmp_file_t *bmp) +{ + /* locate file stream */ + if(fseek(bmp->fp, bmp->data_offset, SEEK_SET) != 0){ + return -1; + } + + bmp->data = malloc((bmp->data_size) * sizeof(uint8_t)); + + if(bmp->data == NULL){ + return -1; + } + + /* read bmp data */ + if(fread(bmp->data, bmp->data_size, 1, bmp->fp) != 1){ + free(bmp->data); + return -1; + } + + return 0; +} + + + +/************************************************** + + BMP Read/Write + +**************************************************/ + + +image_t * bmp_read(const char * path) +{ + FILE * fp; + bmp_file_t bmp; + + fp = fopen(path, "rb"); + if ( fp == NULL ) { + perror("Cannot open file"); + return NULL; + } + + bmp.fp = fp; + + if( bmp_read_header(&bmp) != 0) { + fprintf(stderr, "Cannot read BMP header\n"); + return NULL; + } + + if( bmp_read_dib(&bmp) != 0) { + fprintf(stderr, "Cannot read BMP DIB\n"); + return NULL; + } + + if( bmp_read_data(&bmp) != 0) { + fprintf(stderr, "Cannot read BMP data\n"); + return NULL; + } + + bmp.img = image_new(bmp.img_width, bmp.img_height, IMG_MODEL_BGR); + + if( bmp_decode_data(&bmp) != 0) { + fprintf(stderr, "Cannot decode BMP data\n"); + return NULL; + } + + fclose(fp); + free(bmp.data); + + return bmp.img; +} + +int bmp_save(image_t * img, const char * path) +{ + bmp_file_t bmp; + + uint32_t data_offset; + uint32_t file_size; + + if ( img == NULL ) return -1; + + memset(&bmp, 0, sizeof(bmp_file_t)); + + /* open file */ + bmp.fp = fopen(path, "wb"); + if(bmp.fp == NULL){ + perror("Cannot open file for write."); + return -1; + } + + bmp.img = img; + + if(bmp_encode_data(&bmp) != 0) { + fclose(bmp.fp); + return -1; + } + + data_offset = sizeof(bmp_header_t) + sizeof(bmp_info_t); + file_size = data_offset + bmp.data_size; + + bmp.header.bfType = WINDOWS_BMP; + bmp.header.bfSize = file_size; + bmp.header.bfOffBits = data_offset; + + bmp.info.biSize = DIB_BITMAPINFOHEADER_SIZE; + bmp.info.biWidth = bmp.img->width; + bmp.info.biHeight = bmp.img->height; + bmp.info.biPlanes = 1; /* This shoule always be 1 */ + bmp.info.biBitCount = 24; + bmp.info.biCompression = COMPRESS_BI_RGB; + bmp.info.biSizeImage = bmp.data_size; + bmp.info.biXPelsPerMeter = 72; + bmp.info.biYPelsPerMeter = 72; + bmp.info.biClrUsed = 0; + bmp.info.biClrImportant = 0; + + fwrite(&bmp.header, sizeof(bmp_header_t), 1, bmp.fp); + fwrite(&bmp.info, sizeof(bmp_info_t), 1, bmp.fp); + fwrite(bmp.data, bmp.data_size, 1, bmp.fp); + + fclose(bmp.fp); + + free(bmp.data); + + return 0; +} diff --git a/src/bmp.h b/src/bmp.h new file mode 100644 index 0000000..dd7071e --- /dev/null +++ b/src/bmp.h @@ -0,0 +1,29 @@ +/******************************************************************************** +The MIT License +Copyright (c) 2017-2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +********************************************************************************/ + +#ifndef _BMP_H_ +#define _BMP_H_ 1 + +#include + +image_t * bmp_read(const char * path); +int bmp_save(image_t * img, const char * path); + +#endif /* _BMP_H_ */ diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..a51126e --- /dev/null +++ b/src/config.h @@ -0,0 +1,27 @@ +/******************************************************************************** +The MIT License +Copyright (c) 2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +********************************************************************************/ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +#define TMP_DIR "./tmp" +#define IMG_DIR TMP_DIR "/frames" + +#endif \ No newline at end of file diff --git a/src/image.c b/src/image.c new file mode 100644 index 0000000..1ac15e2 --- /dev/null +++ b/src/image.c @@ -0,0 +1,73 @@ +/****************************************************************************** +The MIT License +Copyright (c) 2017-2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include +#include +#include +#include + +image_t * image_new(int32_t width, int32_t height, int32_t model) +{ + image_t * img = NULL; + + img = malloc( sizeof( image_t ) ); + if( img == NULL ) { + perror("Cannot alloc memory for new image object"); + return NULL; + } + + img->magic = IMG_MAGIC; + img->width = width; + img->height = height; + img->model = model; + img->data = NULL; + + switch (img->model) { + case IMG_MODEL_CYMK: + case IMG_MODEL_BGRA: + img->nChannels = 4; + break; + default: + img->nChannels = 3; + } + + img->pStep = img->nChannels; + img->lStep = img->pStep * img->width; + img->data = malloc(img->width * img->height * img->pStep * sizeof(float)); + if ( img->data == NULL ) { + perror("Cannot alloc memory for new image object"); + free(img); + return NULL; + } + + memset(img->data, 0, img->width * img->height * img->pStep * sizeof(float)); + + return img; +} + +void image_free(image_t * img) +{ + do { + if (img == NULL) break; + if (img->data != NULL) free(img->data); + free(img); + img = NULL; + } while (0); +} diff --git a/src/image.h b/src/image.h new file mode 100644 index 0000000..6593720 --- /dev/null +++ b/src/image.h @@ -0,0 +1,70 @@ +/****************************************************************************** +The MIT License +Copyright (c) 2017-2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef _IMAGE_H_ +#define _IMAGE_H_ 1 + +#include + +typedef struct { + int32_t magic; /* Should Always Be 0x474D4959 */ + int32_t width; + int32_t height; + int32_t model; + int32_t nChannels; + int32_t lStep; + int32_t pStep; + float *data; +} image_t; + +/* image magic number */ +#define IMG_MAGIC 0x474D4959 + +/* image model */ +#define IMG_MODEL_CIEXYZ 0 +#define IMG_MODEL_BGR 1 +#define IMG_MODEL_BGRA 2 +#define IMG_MODEL_YUV 3 +#define IMG_MODEL_YCBCR 4 +#define IMG_MODEL_HSV 5 +#define IMG_MODEL_HSL 6 +#define IMG_MODEL_CYMK 7 +#define IMG_MODEL_GRAY 8 +#define IMG_MODEL_Y 9 + +#define IMG_MODEL_RGB IMG_MODEL_BGR + +/* image channel rgba */ +#define IMG_CHANNEL_B 0 +#define IMG_CHANNEL_G 1 +#define IMG_CHANNEL_R 2 +#define IMG_CHANNEL_A 3 + +image_t * image_new(int32_t width, int32_t height, int32_t model); + +inline float * image_pixel(image_t * img, int32_t x, int32_t y) +{ + return (img->data) + x * (img->pStep) + y * (img->lStep); +} + +int image_save(image_t * img, const char * path); +void image_free(image_t * img); + +#endif /* _IMAGE_H_ */ diff --git a/src/image_average.c b/src/image_average.c new file mode 100644 index 0000000..8c4209a --- /dev/null +++ b/src/image_average.c @@ -0,0 +1,43 @@ +/****************************************************************************** +The MIT License +Copyright (c) 2017-2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include +#include +#include + +float image_average(image_t * img) +{ + float sum = 0; + int cnt = 0; + + float *ip; + float *endp; + + ip = img->data; + endp = &ip[3 * img->width * img->height]; + + while (ip < endp) { + sum += *ip; + cnt ++; + ip ++; + } + + return (float)(sum / (float)cnt); +} diff --git a/src/image_average.h b/src/image_average.h new file mode 100644 index 0000000..7b5e99b --- /dev/null +++ b/src/image_average.h @@ -0,0 +1,28 @@ +/****************************************************************************** +The MIT License +Copyright (c) 2017-2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef _IMAGE_AVERAGE_H_ +#define _IMAGE_AVERAGE_H_ 1 + +#include + +float image_average(image_t * img); + +#endif \ No newline at end of file diff --git a/src/image_binary.c b/src/image_binary.c new file mode 100644 index 0000000..b40c9f6 --- /dev/null +++ b/src/image_binary.c @@ -0,0 +1,50 @@ +/****************************************************************************** +The MIT License +Copyright (c) 2017-2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include +#include +#include +#include + +int image_binary(image_t * img) +{ + float average; + + float *ip; + float *endp; + + image_gray(img); + + average = image_average(img) / 2.0; + + ip = img->data; + endp = &ip[3 * img->width * img->height]; + + while (ip < endp) { + if (*ip > average && *ip > 1) { + *ip = 255; + } else { + *ip = 0; + } + ip ++; + } + + return 0; +} diff --git a/src/image_binary.h b/src/image_binary.h new file mode 100644 index 0000000..22fba5d --- /dev/null +++ b/src/image_binary.h @@ -0,0 +1,28 @@ +/****************************************************************************** +The MIT License +Copyright (c) 2017-2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef _IMAGE_BINARY_H_ +#define _IMAGE_BINARY_H_ 1 + +#include + +int image_binary(image_t * img); + +#endif \ No newline at end of file diff --git a/src/image_edge_dect.c b/src/image_edge_dect.c new file mode 100644 index 0000000..e25c74f --- /dev/null +++ b/src/image_edge_dect.c @@ -0,0 +1,71 @@ +/****************************************************************************** +The MIT License +Copyright (c) 2017-2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + + +#include +#include +#include +#include +#include + + +int image_edge_dect(image_t * img) +{ + int x0,y0; + + float conv_tmp; + float * img_tmp; + + static image_t * img_out = NULL; + + if (img_out == NULL) { + img_out = image_new(img->width, img->height, IMG_MODEL_BGR); + } + + for(x0 = 1; x0 < img->width - 1; x0++){ + for(y0 = 1; y0 < img->height - 1; y0++){ + /* ergodic pixel in image */ + conv_tmp = 0; + + conv_tmp += image_pixel(img, x0 + 1, y0)[0]; + conv_tmp += image_pixel(img, x0 + 1, y0 + 1)[0]; + conv_tmp += image_pixel(img, x0 + 1, y0 + 1)[0]; + conv_tmp += image_pixel(img, x0, y0 + 1)[0]; + + conv_tmp -= image_pixel(img, x0 - 1, y0)[0]; + conv_tmp -= image_pixel(img, x0 - 1, y0 - 1)[0]; + conv_tmp -= image_pixel(img, x0 - 1, y0 - 1)[0]; + conv_tmp -= image_pixel(img, x0, y0 - 1)[0]; + + conv_tmp = (float)fabs(conv_tmp / 8.0); + + img_tmp = image_pixel(img_out, x0, y0); + + img_tmp[0] = conv_tmp; + img_tmp[1] = conv_tmp; + img_tmp[2] = conv_tmp; + + } + } + + memcpy(img->data, img_out->data, 3 * img->width * img->height * sizeof(float)); + + return 0; +} diff --git a/src/image_edge_dect.h b/src/image_edge_dect.h new file mode 100644 index 0000000..6167376 --- /dev/null +++ b/src/image_edge_dect.h @@ -0,0 +1,28 @@ +/****************************************************************************** +The MIT License +Copyright (c) 2017-2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef _IMAGE_EDGE_DECT_H_ +#define _IMAGE_EDGE_DECT_H_ + +#include + +int image_edge_dect(image_t * img); + +#endif \ No newline at end of file diff --git a/src/image_gray.c b/src/image_gray.c new file mode 100644 index 0000000..df817ea --- /dev/null +++ b/src/image_gray.c @@ -0,0 +1,54 @@ +/****************************************************************************** +The MIT License +Copyright (c) 2017-2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + + +#include +#include + +int image_gray(image_t * img) +{ + float R; + float G; + float B; + float Y; + + float *ip; + float *endp; + + ip = img->data; + endp = &ip[3 * img->width * img->height]; + + while (ip < endp) { + B = ip[0]; + G = ip[1]; + R = ip[2]; + + Y = + (0.299 * R) + (0.587 * G) + (0.114 * B); + + ip[0] = Y; + ip[1] = Y; + ip[2] = Y; + + ip = &ip[3]; + } + + return 0; +} + diff --git a/src/image_gray.h b/src/image_gray.h new file mode 100644 index 0000000..e8be3a1 --- /dev/null +++ b/src/image_gray.h @@ -0,0 +1,28 @@ +/****************************************************************************** +The MIT License +Copyright (c) 2017-2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef _IMAGE_GRAY_H_ +#define _IMAGE_GRAY_H_ 1 + +#include + +int image_gray(image_t * img); + +#endif \ No newline at end of file diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..6d36b43 --- /dev/null +++ b/src/main.c @@ -0,0 +1,153 @@ +/******************************************************************************** +The MIT License +Copyright (c) 2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +********************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +int frame_cnt = 0; +int frame_index = 0; +int frame_w = 0; +int frame_h = 0; +int frame_s = 0; + +void show_proc(int signal); + +int main(void) +{ + extern int frame_cnt; + extern int frame_index; + extern int frame_w; + extern int frame_h; + extern int frame_s; + char path[64]; + image_t * img; + wave_t * wav; + struct sigaction sa; + + + create_tmp_dir(); + + transform_video("./test-y.mp4"); + + frame_cnt = get_frame_cnt(); + + fprintf(stderr, "Do Processing Workflow On Each Frame.\n"); + + sa.sa_handler = &show_proc; + sa.sa_flags = SA_RESTART; + sigaction(SIGALRM, &sa, NULL); + alarm(1); + + ProfilerStart("./test.prof"); + ProfilerRegisterThread(); + + wav = wave_new(2, 48000, (48000 / 24) * frame_cnt); + + for (frame_index = 1; frame_index <= frame_cnt; frame_index++) { + + sprintf(path, "./tmp/frames/v-%05d.bmp", frame_index); + + img = bmp_read(path); + + if (frame_w == 0) { + frame_w = img->width; + frame_h = img->height; + frame_s = 3 * frame_w * frame_h * 4; + } + + image_binary(img); + + image_edge_dect(img); + + image_binary(img); + + sprintf(path, "./tmp/frames_proc/v-%05d.bmp", frame_index); + + bmp_save(img, path); + + image_free(img); + + } + + raise(SIGALRM); + + fprintf(stderr, "\nProcess end.\n"); + + ProfilerStop(); + + alarm(0); + + wave_save(wav, "./out.wav"); + + wave_free(wav); + + /* + system("rm -rf ./tmp"); + */ + return 0; +} + +void show_proc(int signal) +{ + extern int frame_cnt; + extern int frame_index; + extern int frame_s; + + static int priv_index = 0; + static int time_s = 0; + static int time_m = 0; + static int time_h = 0; + + int fps; + float kbps; + float speed; + + fps = frame_index - priv_index; + kbps = (fps * frame_s)/1000.0; + priv_index = frame_index; + speed = (float)fps / (float)24; + time_s ++; + + if (time_s == 60) { + time_s = 0; + time_m ++; + } + + if (time_m == 60) { + time_m = 0; + time_h ++; + } + + fprintf(stderr, "\rframe= %d fps= %d time=%02d:%02d:%02ds bitrate=%.1fkbits/s speed=%.2fx SIG=%d",\ + frame_index, fps, time_h, time_m, time_s, kbps, speed, signal); + fflush(stderr); + + alarm(1); +} diff --git a/src/path.c b/src/path.c new file mode 100644 index 0000000..0cac004 --- /dev/null +++ b/src/path.c @@ -0,0 +1,43 @@ +/******************************************************************************** +The MIT License +Copyright (c) 2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +********************************************************************************/ + +#include + +int gen_path(image_t * img, wave_t * wav, int frame_no) +{ + static int * origin_x_pos = NULL; + static int * origin_y_pos = NULL; + static int * origin_dist = NULL; + static int * origin_avail = NULL; + static int * sorted_x = NULL; + static int * sorted_y = NULL; + + int graph_size = 0; + int point_cnt; + + int wav_length = (48000 / 24); + + static int last_x = 0; + static int last_y = 0; +} + +int main(void) { + return 0; +} diff --git a/src/path.h b/src/path.h new file mode 100644 index 0000000..e33148b --- /dev/null +++ b/src/path.h @@ -0,0 +1,29 @@ +/******************************************************************************** +The MIT License +Copyright (c) 2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +********************************************************************************/ + +#ifndef _PATH_H_ +#define _PATH_H_ 1 + +#include +#include + +int gen_path(image_t * img, wave_t * wav, int frame_no); + +#endif \ No newline at end of file diff --git a/src/ppm.c b/src/ppm.c new file mode 100644 index 0000000..ce9820f --- /dev/null +++ b/src/ppm.c @@ -0,0 +1,207 @@ +/****************************************************************************** +The MIT License +Copyright (c) 2017-2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + + +#include +#include +#include +#include + +int ppm_read_header(FILE * fp, int32_t *width, int32_t *height, int32_t *depth) +{ + int32_t data[3] = {0}; + int i = 0; + int ch = 0; + + while( i < 3 ) { + ch = fgetc(fp); + if ( ch == '#' ) { + while ( (ch = fgetc(fp)) != EOF ) { + if ( ch == '\n' ) break; + if ( ch == '\r' ) { + ch = fgetc(fp); + if ( ch == '\n' ) { + break; + } + ungetc(ch, fp); + break; + } + } + } else { + ungetc(ch, fp); + fscanf(fp, "%d", &data[i]); + i++; + } + } + + *width = data[0]; + *height = data[1]; + + if (data[2] < 255) { + return -1; + } else if (data[2] <= 255) { + *depth = 8; + } else if (data[2] <= 65535) { + *depth = 16; + } else { + *depth = 32; + } + + return 0; +} + +image_t * ppm_p3_read(FILE * fp) +{ + int32_t width; + int32_t height; + int32_t depth; + int32_t x; + int32_t y; + int32_t R; + int32_t G; + int32_t B; + + image_t *img; + + fprintf(stderr, "Format: Portable PixMap in ASCII (P3)\n"); + + /* Read Header */ + ppm_read_header(fp, &width, &height, &depth); + + fprintf(stderr, "Image Size: %d x %d.\n", width, height); + fprintf(stderr, "Color Depth: %d bit.\n", 3 * depth); + + img = image_new(width, height, IMG_MODEL_BGR); + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + fscanf(fp, "%d", &R); + fscanf(fp, "%d", &G); + fscanf(fp, "%d", &B); + image_pixel(img, x, y)[IMG_CHANNEL_R] = R; + image_pixel(img, x, y)[IMG_CHANNEL_G] = G; + image_pixel(img, x, y)[IMG_CHANNEL_B] = B; + } + } + + return img; +} + +#if 0 + +image_t * ppm_p1_read(FILE * fp) +{ + fprintf(stderr, "Format: Portable Bitmap in ASCII (P1)\n"); + return NULL; +} + +image_t * ppm_p2_read(FILE * fp) +{ + fprintf(stderr, "Format: Portable GrayMap in ASCII (P2)\n"); + return NULL; +} + +image_t * ppm_p4_read(FILE * fp) +{ + fprintf(stderr, "Format: Portable Bitmap in Binary (P4)\n"); + return NULL; +} + +image_t * ppm_p5_read(FILE * fp) +{ + fprintf(stderr, "Format: Portable GrayMap in Binary (P5)\n"); + return NULL; +} + +image_t * ppm_p6_read(FILE * fp) +{ + fprintf(stderr, "Format: Portable GrayMap in Binary (P6)\n"); + return NULL; +} +#endif + +image_t * ppm_read(FILE * fp) +{ + image_t *img = NULL; + int num = 0; + + fseek(fp, 0, SEEK_SET); + + /* Read Magic */ + if(!fscanf(fp, "P%d\n", &num)) { + fprintf(stderr, "Not PPM Format\n"); + return NULL; + } + +#if 0 + switch ( num ) { + case 1: img = ppm_p1_read(fp); break; + case 2: img = ppm_p2_read(fp); break; + case 3: img = ppm_p3_read(fp); break; + case 4: + case 5: + case 6: + default: + fprintf(stderr, "Not PPM Format\n"); + } +#endif + + img = ppm_p3_read(fp); + + return img; +} + + +int ppm_save(image_t * img, const char * path) +{ + FILE *fp = NULL; + + int32_t x = 0; + int32_t y = 0; + + int32_t R = 0; + int32_t G = 0; + int32_t B = 0; + + fp = fopen(path, "wb"); + + fprintf(fp, "P3\n"); + fprintf(fp, "# Generate by YCIL\n"); + fprintf(fp, "%d %d\n", img->width, img->height); + fprintf(fp, "255\n"); + + for (y = 0; y < img->height; y++) { + for (x = 0; x < img->width; x++) { + R = round(image_pixel(img, x, y)[IMG_CHANNEL_R]); + G = round(image_pixel(img, x, y)[IMG_CHANNEL_G]); + B = round(image_pixel(img, x, y)[IMG_CHANNEL_B]); + if (R > 255) R = 255; + if (G > 255) G = 255; + if (B > 255) B = 255; + if (R < 0) R = 0; + if (G < 0) G = 0; + if (B < 0) B = 0; + + fprintf(fp, "%d %d %d\n", R, G, B); + } + } + + return 0; +} diff --git a/src/ppm.h b/src/ppm.h new file mode 100644 index 0000000..9460737 --- /dev/null +++ b/src/ppm.h @@ -0,0 +1,29 @@ +/****************************************************************************** +The MIT License +Copyright (c) 2017-2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef _YCIL_PPM_H_ +#define _YCIL_PPM_H_ 1 + +#include + +image_t * ppm_read(FILE * fp); +int ppm_save(image_t * img, const char * path); + +#endif \ No newline at end of file diff --git a/src/utils.c b/src/utils.c new file mode 100644 index 0000000..4795801 --- /dev/null +++ b/src/utils.c @@ -0,0 +1,99 @@ +/******************************************************************************** +The MIT License +Copyright (c) 2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +********************************************************************************/ + +#include +#include + +#include + +#include + +int create_tmp_dir(void) +{ + fprintf(stderr, "Creating Temp Dir.\n"); + /* Windows command lines are different from others */ + +#if defined(WIN32) || defined(WIN64) || defined(WINNT) + + /* Add Windows command lines here */ + +#else /* ! WIN32 || WIN64 || WINNT */ + + system("mkdir -p ./tmp"); + system("mkdir -p ./tmp/frames"); + system("mkdir -p ./tmp/frames_proc"); + +#endif /* WIN32 || WIN64 || WINNT */ + + return 0; +} + +int remove_tmp_dir(void) +{ + /* Windows command lines are different from others */ + +#if defined(WIN32) || defined(WIN64) || defined(WINNT) + + /* Add Windows command lines here */ + +#else /* ! WIN32 || WIN64 || WINNT */ + + system("rm -rf ./tmp"); + +#endif /* WIN32 || WIN64 || WINNT */ + + return 0; +} + +int transform_video(const char * input_path) +{ + char commands[255]; + + fprintf(stderr, "Extracting Frames.\n"); + + sprintf(commands, "ffmpeg -loglevel 0 -stats -i %s -vf fps=24 ./tmp/frames/v-%%05d.bmp", input_path); + + system(commands); + + fprintf(stderr, "Extracting Audio Track.\n"); + + sprintf(commands, "ffmpeg -loglevel 0 -stats -i %s -vn -ar 44100 -ac 2 -ab 192k -f adts ./tmp/Sample.aac", input_path); + + system(commands); + + return 0; +} + +int get_frame_cnt(void) +{ + int frame_count = 0; + DIR * dirp; + struct dirent * entry; + + dirp = opendir("./tmp/frames"); + while ((entry = readdir(dirp)) != NULL) { + if (entry->d_type == DT_REG) { + frame_count++; + } + } + closedir(dirp); + + return frame_count; +} diff --git a/src/utils.h b/src/utils.h new file mode 100644 index 0000000..5e7e0e4 --- /dev/null +++ b/src/utils.h @@ -0,0 +1,30 @@ +/******************************************************************************** +The MIT License +Copyright (c) 2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +********************************************************************************/ + +#ifndef _UTILS_H_ +#define _UTILS_H_ 1 + +int create_tmp_dir(void); +int remove_tmp_dir(void); + +int transform_video(const char * input_path); +int get_frame_cnt(void); + +#endif diff --git a/src/wave.c b/src/wave.c new file mode 100644 index 0000000..5c8b3cc --- /dev/null +++ b/src/wave.c @@ -0,0 +1,184 @@ +/******************************************************************************** +The MIT License +Copyright (c) 2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +********************************************************************************/ + +#include +#include +#include +#include + +wave_t * wave_new(int channel, int rate, int length) +{ + int ch_index; + wave_t * wave; + + wave = malloc(sizeof(wave_t)); + + if (wave == NULL) { + return NULL; + } + + wave->data = malloc(channel * sizeof(int16_t *)); + + if (wave->data == NULL) { + free(wave); + return NULL; + } + + for (ch_index = 0; ch_index < channel; ch_index++) { + wave->data[ch_index] = malloc(length * sizeof(int16_t)); + + if (wave->data[ch_index] == NULL) { + while (ch_index >= 0) { + free(wave->data[ch_index]); + ch_index --; + } + free(wave); + return NULL; + } + } + + wave->channel = channel; + wave->rate = rate; + wave->length = length; + + return wave; +} + +int wave_free(wave_t * wave) +{ + int ch_index; + for (ch_index = 0; ch_index < wave->channel; ch_index++) { + free(wave->data[ch_index]); + } + free(wave); + return 0; +} + +#define RIFF_CHUNKID 0x46464952 /* RIFF in ascii */ +#define RIFF_FORMAT 0x45564157 /* WAVE in ascii */ + +typedef struct { + uint32_t ChunkID; /* should always be RIFF_CHUNKID */ + uint32_t ChunkSize; + uint32_t Format; /* should always be RIFF_FORMAT */ +} riff_header_t; + +#define RIFF_SCHUNK_FMT 0x20746d66 /* "fmt " in ascii */ +#define RIFF_SCHUNK_DATA 0x61746164 /* "data" in ascii */ + +typedef struct { + uint32_t Subchunk1ID; /* should always be RIFF_SCHUNK_FMT */ + uint32_t Subchunk1Size; /* 16 */ + uint16_t AudioFormat; /* 1 for PCM */ + uint16_t NumChannels; /* Mono = 1, Stereo = 2, etc. */ + uint32_t SampleRate; /* 8000, 44100, etc. */ + uint32_t ByteRate; /* == SampleRate * NumChannels * BitsPerSample/8 */ + uint16_t BlockAlign; /* == NumChannels * BitsPerSample/8 */ + uint16_t BitsPerSample; /* 8 bits = 8, 16 bits = 16, etc. */ +}__attribute__((packed)) riff_fmt_chunk_t; + +typedef struct { + uint32_t Subchunk2ID; /* shoule always be RIFF_SCHUNK_DATA */ + uint32_t Subchunk2Size; /* == NumSamples * NumChannels * BitsPerSample/8 */ +} riff_data_chunk_t; + +int wave_save(wave_t * wave, const char * path) +{ + riff_header_t header; + riff_fmt_chunk_t fmt; + riff_data_chunk_t data; + + int ch_index; + int frame_index; + + FILE * fp; + + fp = fopen(path, "wb"); + if (fp == NULL) { + perror("Cannot open wav file"); + return -1; + } + + header.ChunkID = RIFF_CHUNKID; + header.ChunkSize = 36 + wave->length * wave->channel * 2; + header.Format = RIFF_FORMAT; + + fwrite(&header, sizeof(riff_header_t), 1, fp); + + fmt.Subchunk1ID = RIFF_SCHUNK_FMT; + fmt.Subchunk1Size = 16; + fmt.AudioFormat = 1; + fmt.NumChannels = wave->channel; + fmt.SampleRate = wave->rate; + fmt.BlockAlign = 4; + fmt.BitsPerSample = 16; + + fmt.ByteRate = fmt.SampleRate * (fmt.BitsPerSample / 8); + + fwrite(&fmt, sizeof(riff_fmt_chunk_t), 1, fp); + + data.Subchunk2ID = RIFF_SCHUNK_DATA; + data.Subchunk2Size = wave->channel * wave->length * (fmt.BitsPerSample / 8); + + fwrite(&data, sizeof(riff_data_chunk_t), 1, fp); + + for (frame_index = 0; frame_index < wave->length; frame_index++) { + for (ch_index = 0; ch_index < wave->channel; ch_index++) { + fwrite(&wave->data[ch_index][frame_index], sizeof(int16_t), 1, fp); + } + } + + fclose(fp); + return 0; +} + +#if 0 + +/* test program */ + +#include + +int __attribute__((weak)) main(int argc, char const *argv[]) +{ + wave_t * test; + int frame; + float fact; + char cnt = 0; + + test = wave_new(2,48000,480000); + + for (frame = 0; frame < 480000; frame++) { + cnt ++; + if (cnt > 0) { + fact = 30000.0; + } else { + fact = 25000.0; + } + test->data[0][frame] = (int16_t)(cos(frame * (3.14 / 24.0)) * fact); + test->data[1][frame] = (int16_t)(sin(frame * (3.14 / 24.0)) * fact); + } + + wave_save(test, "./test.wav"); + + wave_free(test); + return 0; +} + +#endif diff --git a/src/wave.h b/src/wave.h new file mode 100644 index 0000000..d9e9048 --- /dev/null +++ b/src/wave.h @@ -0,0 +1,36 @@ +/******************************************************************************** +The MIT License +Copyright (c) 2018 Yeonji +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +********************************************************************************/ + +#ifndef _WAVE_H_ +#define _WAVE_H_ 1 + +typedef struct { + int channel; + int rate; + int length; + int16_t **data; +} wave_t; + +wave_t * wave_new(int channel, int rate, int lenght); +int wave_free(wave_t * wave); + +int wave_save(wave_t * wave, const char * path); + +#endif \ No newline at end of file