diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..4cba627
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,23 @@
+BasedOnStyle: LLVM
+Language: Cpp
+
+IndentWidth: 2
+ContinuationIndentWidth: 2
+TabWidth: 2
+UseTab: Never
+
+ColumnLimit: 80
+IndentPPDirectives: None
+AlignEscapedNewlines: Left
+AlignConsecutiveMacros: None
+
+BinPackArguments: false
+BinPackParameters: false
+AllowShortFunctionsOnASingleLine: Empty
+AllowShortIfStatementsOnASingleLine: Never
+AllowShortLoopsOnASingleLine: false
+
+BreakBeforeBraces: Attach
+PointerAlignment: Right
+SortIncludes: Never
+ReflowComments: false
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a321ee9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+/.cache
+/build
+/benchmarks/processed_outputs
+/benchmarks/pipeline_outputs
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..b970b1f
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,160 @@
+cmake_minimum_required(VERSION 3.20)
+
+project(ImageConversation LANGUAGES C)
+
+set(CMAKE_C_STANDARD 17)
+set(CMAKE_C_STANDARD_REQUIRED ON)
+set(CMAKE_C_EXTENSIONS OFF)
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
+include(CTest)
+include(FetchContent)
+find_package(Threads REQUIRED)
+find_package(OpenMP REQUIRED)
+
+option(IMAGE_CONVERSATION_ENABLE_OPENCV
+ "Fetch the legacy OpenCV C API target"
+ OFF)
+
+file(GLOB_RECURSE FILTER_SOURCES CONFIGURE_DEPENDS
+ "${CMAKE_CURRENT_SOURCE_DIR}/src/filters/*.c"
+)
+
+file(GLOB_RECURSE CONVOLUTION_RUNTIME_SOURCES CONFIGURE_DEPENDS
+ "${CMAKE_CURRENT_SOURCE_DIR}/src/convolution/*.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/src/gpu_convolution/*.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/src/parallel_convolution/*.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/src/pipeline/*.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/src/sequentially_convolution/*.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/*.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/src/image_helpers/*.c"
+)
+
+set(BUILD_TESTS OFF CACHE BOOL "")
+set(BUILD_PERF_TESTS OFF CACHE BOOL "")
+set(BUILD_EXAMPLES OFF CACHE BOOL "")
+set(BUILD_DOCS OFF CACHE BOOL "")
+set(BUILD_opencv_apps OFF CACHE BOOL "")
+
+set(BUILD_opencv_core ON CACHE BOOL "")
+set(BUILD_opencv_imgproc ON CACHE BOOL "")
+set(BUILD_opencv_highgui ON CACHE BOOL "")
+
+set(BUILD_opencv_ts OFF CACHE BOOL "")
+set(BUILD_opencv_calib3d OFF CACHE BOOL "")
+set(BUILD_opencv_contrib OFF CACHE BOOL "")
+set(BUILD_opencv_features2d OFF CACHE BOOL "")
+set(BUILD_opencv_flann OFF CACHE BOOL "")
+set(BUILD_opencv_gpu OFF CACHE BOOL "")
+set(BUILD_opencv_legacy OFF CACHE BOOL "")
+set(BUILD_opencv_ml OFF CACHE BOOL "")
+set(BUILD_opencv_nonfree OFF CACHE BOOL "")
+set(BUILD_opencv_objdetect OFF CACHE BOOL "")
+set(BUILD_opencv_ocl OFF CACHE BOOL "")
+set(BUILD_opencv_photo OFF CACHE BOOL "")
+set(BUILD_opencv_stitching OFF CACHE BOOL "")
+set(BUILD_opencv_superres OFF CACHE BOOL "")
+set(BUILD_opencv_video OFF CACHE BOOL "")
+set(BUILD_opencv_videostab OFF CACHE BOOL "")
+set(BUILD_opencv_world OFF CACHE BOOL "")
+
+set(WITH_QT OFF CACHE BOOL "")
+set(WITH_GTK OFF CACHE BOOL "")
+set(WITH_OPENGL OFF CACHE BOOL "")
+set(WITH_FFMPEG OFF CACHE BOOL "")
+set(WITH_GSTREAMER OFF CACHE BOOL "")
+set(WITH_V4L OFF CACHE BOOL "")
+set(WITH_1394 OFF CACHE BOOL "")
+set(WITH_CUDA OFF CACHE BOOL "")
+set(WITH_OPENCL OFF CACHE BOOL "")
+set(WITH_TBB OFF CACHE BOOL "")
+set(WITH_IPP OFF CACHE BOOL "")
+set(WITH_TIFF OFF CACHE BOOL "")
+set(WITH_JASPER OFF CACHE BOOL "")
+set(WITH_OPENEXR OFF CACHE BOOL "")
+
+FetchContent_Declare(
+ opencv
+ GIT_REPOSITORY https://github.com/opencv/opencv
+ GIT_TAG 2.4.13.6
+ GIT_SHALLOW TRUE
+)
+
+FetchContent_Declare(
+ opencl_headers
+ GIT_REPOSITORY https://github.com/KhronosGroup/OpenCL-Headers.git
+ GIT_TAG v2023.04.17
+)
+
+FetchContent_Declare(
+ opencl_icd_loader
+ GIT_REPOSITORY https://github.com/KhronosGroup/OpenCL-ICD-Loader.git
+ GIT_TAG v2023.04.17
+)
+
+FetchContent_MakeAvailable(opencv opencl_headers opencl_icd_loader)
+
+add_library(opencv_legacy_c_api INTERFACE)
+target_include_directories(opencv_legacy_c_api
+ INTERFACE
+ ${opencv_SOURCE_DIR}/modules/core/include
+ ${opencv_SOURCE_DIR}/modules/imgproc/include
+ ${opencv_SOURCE_DIR}/modules/highgui/include
+)
+target_link_libraries(opencv_legacy_c_api
+ INTERFACE
+ opencv_core
+ opencv_imgproc
+ opencv_highgui
+)
+
+add_library(filters_core STATIC
+ ${FILTER_SOURCES}
+)
+add_library(filters ALIAS filters_core)
+
+target_include_directories(filters_core
+ PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
+)
+
+add_library(convolution_runtime STATIC
+ ${CONVOLUTION_RUNTIME_SOURCES}
+)
+target_include_directories(convolution_runtime
+ PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
+ PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}/internal
+ ${opencl_headers_SOURCE_DIR}
+)
+target_compile_definitions(convolution_runtime
+ PRIVATE
+ CL_TARGET_OPENCL_VERSION=300
+ GPU_CONVOLUTION_KERNEL_PATH="${CMAKE_CURRENT_SOURCE_DIR}/src/gpu_convolution/gpu_convolution.cl"
+)
+target_link_libraries(convolution_runtime
+ PUBLIC
+ filters_core
+ opencv_legacy_c_api
+ OpenCL
+ Threads::Threads
+ OpenMP::OpenMP_C
+)
+
+add_executable(app
+ src/app.c
+ src/cli_args.c
+)
+target_link_libraries(app
+ PRIVATE
+ convolution_runtime
+)
+
+if(BUILD_TESTING)
+ find_package(PkgConfig REQUIRED)
+ pkg_check_modules(CMOCKA REQUIRED IMPORTED_TARGET cmocka)
+
+ add_subdirectory(test/sequential_tests)
+ add_subdirectory(test/thread_pool_tests)
+endif()
diff --git a/README.md b/README.md
index 587628d..22a2c92 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,429 @@
# Image Conversation
-Основная ветка намеренно оставлена минимальной.
+Image Conversation — консольное приложение для применения фильтров к одному изображению или к набору изображений.
-Реализации задач разнесены по отдельным веткам:
+## Запуск программы
+
+### Сборка
+
+Для обычного запуска программы достаточно собрать таргет `app` в release-конфигурации:
+
+```bash
+cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF
+cmake --build build --target app -j
+```
+
+После сборки исполняемый файл находится в `build/bin/app`.
+
+### Пример для одного изображения
+
+```bash
+./build/bin/app \
+ -i input/satoru.jpg -o output/satoru.jpg \
+ -f gauss -h 5 -w 5 \
+ -f sharpen -h 3 -w 3 \
+ -p rows
+```
+
+### Пример для нескольких изображений
+
+Для пакетной обработки нужно несколько раз передать пару `-i -o