diff --git a/C_image_processing/.gitignore b/C_image_processing/.gitignore index eb3c204..ee2f73b 100644 --- a/C_image_processing/.gitignore +++ b/C_image_processing/.gitignore @@ -76,12 +76,13 @@ dkms.conf # Executables ### VisualStudioCode ### -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json -!.vscode/*.code-snippets +*.vscode +#!.vscode/c_cpp_properties.json +#!.vscode/settings.json # user Specific +#!.vscode/tasks.json +#!.vscode/launch.json # user Specific +#!.vscode/extensions.json +#!.vscode/*.code-snippets # Local History for Visual Studio Code .history/ @@ -120,7 +121,5 @@ $RECYCLE.BIN/ # Windows shortcuts *.lnk -# End of https://www.toptal.com/developers/gitignore/api/windows,visualstudiocode,c,c++ - # Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) output.bmp diff --git a/C_image_processing/.vscode/c_cpp_properties.json b/C_image_processing/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..610e4bc --- /dev/null +++ b/C_image_processing/.vscode/c_cpp_properties.json @@ -0,0 +1,25 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**", + "C:/msys64/mingw64/include/gtk-4.0", + "C:/msys64/mingw64/include/glib-2.0", + "C:/msys64/mingw64/include/**", + "C:/msys64/mingw64/lib/**" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE" + ], + "windowsSdkVersion": "10.0.22000.0", + "compilerPath": "C:/msys64/mingw64/bin/gcc.exe", + "cStandard": "c17", + "cppStandard": "c++17", + "intelliSenseMode": "windows-gcc-x64" + } + ], + "version": 4 + } \ No newline at end of file diff --git a/C_image_processing/.vscode/tasks.json b/C_image_processing/.vscode/tasks.json new file mode 100644 index 0000000..c22991c --- /dev/null +++ b/C_image_processing/.vscode/tasks.json @@ -0,0 +1,61 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: gcc.exe build active file", + "command": "C:/msys64/mingw64/bin/gcc.exe", + "args": [ + "-fdiagnostics-color=always", + "-g", + "-IC:/msys64/mingw64/include/gtk-4.0", + "-IC:/msys64/mingw64/include/pango-1.0", + "-IC:/msys64/mingw64/include", + "-IC:/msys64/mingw64/include/glib-2.0", + "-IC:/msys64/mingw64/lib/glib-2.0/include", + "-IC:/msys64/mingw64/include/harfbuzz", + "-IC:/msys64/mingw64/include/freetype2", + "-IC:/msys64/mingw64/include/libpng16", + "-IC:/msys64/mingw64/include/fribidi", + "-IC:/msys64/mingw64/include/cairo", + "-IC:/msys64/mingw64/include/pixman-1", + "-IC:/msys64/mingw64/include/gdk-pixbuf-2.0", + "-IC:/msys64/mingw64/include/webp", + "-DLIBDEFLATE_DLL", + "-IC:/msys64/mingw64/include/graphene-1.0", + "-IC:/msys64/mingw64/lib/graphene-1.0/include", + "-mfpmath=sse", + "-msse", + "-msse2", + + "${file}", + + "-LC:/msys64/mingw64/lib", + "-lgtk-4", + "-lpangowin32-1.0", + "-lpangocairo-1.0", + "-lpango-1.0", + "-lharfbuzz", + "-lgdk_pixbuf-2.0", + "-lcairo-gobject", + "-lcairo", + "-lgraphene-1.0", + "-lgio-2.0", + "-lgobject-2.0", + "-lglib-2.0", + "-lintl", + + "-o", + "${fileDirname}\\${fileBasenameNoExtension}.exe" + ], + "options": { + "cwd": "C:/msys64/mingw64/bin" + }, + "problemMatcher": [ + "$gcc" + ], + "group": "build", + "detail": "compiler: C:/msys64/mingw64/bin/gcc.exe" + } + ] +} \ No newline at end of file diff --git a/C_image_processing/filters/black_and_white_filter.c b/C_image_processing/filters/black_and_white_filter.c index 12403f0..e8efb6e 100644 --- a/C_image_processing/filters/black_and_white_filter.c +++ b/C_image_processing/filters/black_and_white_filter.c @@ -1,4 +1,5 @@ #include + #define THRESHOLD 128 // define value of threshold for black and white #define WHITE 255 #define BLACK 0 @@ -16,48 +17,45 @@ int black_and_white_filter(const char *inputFile, const char *outputFile) { return 1; } - int i; - unsigned char byte[54]; + unsigned char headerInfo[54]; unsigned char colorTable[1024]; - // read header info of image - for(i = 0; i < 54; i++) { - byte[i] = getc(fileIn); + // Read header info of image + for(int i = 0; i < 54; i++) { + headerInfo[i] = getc(fileIn); } - // write header info to output file - fwrite(byte, sizeof(unsigned char), 54, fileOut); + // Write header info to output file + fwrite(headerInfo, sizeof(unsigned char), 54, fileOut); - // extract height, width and bitDepth of image from the header information - int height = *(int*)&byte[18]; - int width = *(int*)&byte[22]; - int bitDepth = *(int*)&byte[28]; + // Extract.. of image from the header information + int height = *(int*)&headerInfo[18]; + int width = *(int*)&headerInfo[22]; + int bitDepth = *(int*)&headerInfo[28]; int size = height * width; - // check if the image has a color table + // Check if the image has a color table if(bitDepth <= 8) { - // read, and then write the color table from the input file fread(colorTable, sizeof(unsigned char), 1024, fileIn); fwrite(colorTable, sizeof(unsigned char), 1024, fileOut); } + + unsigned char chunkBuffer[CHUNK_SIZE]; - // array to store the image data in chunks - unsigned char buffer[CHUNK_SIZE]; - - // read and write the image data in chunks until the end of the file is reached + // Read & write the image data in chunks until the end of file is reached while(!feof(fileIn)) { - // read a chunk of image data from the input file - size_t bytesRead = fread(buffer, sizeof(unsigned char), CHUNK_SIZE, fileIn); + // Read a chunk of image data from input file + size_t bytesRead = fread(chunkBuffer, sizeof(unsigned char), CHUNK_SIZE, fileIn); - // apply the threshold to each pixel in the chunk - for(i = 0; i < bytesRead; i++) { - buffer[i] = (buffer[i] > THRESHOLD) + // Apply threshold to each pixel in the chunk + for(int i = 0; i < bytesRead; i++) { + chunkBuffer[i] = (chunkBuffer[i] > THRESHOLD) ? WHITE : BLACK; } - // write the thresholded image data to the output file - fwrite(buffer, sizeof(unsigned char), bytesRead, fileOut); + // Write the thresholded image data to the output file + fwrite(chunkBuffer, sizeof(unsigned char), bytesRead, fileOut); } fclose(fileIn); diff --git a/C_image_processing/filters/bright_filter.c b/C_image_processing/filters/bright_filter.c index e09be8a..1afdb46 100644 --- a/C_image_processing/filters/bright_filter.c +++ b/C_image_processing/filters/bright_filter.c @@ -1,5 +1,6 @@ #include #include + #define MAX_COLOR 255 #define BRIGHTNESS 25 #define CHUNK_SIZE 1024 // define size of the chunks to read and write @@ -17,54 +18,47 @@ int bright_filter(inputFile, outputFile) { return 1; } - int i; - unsigned char byte[54]; // store header info of image - unsigned char colorTable[1024]; // store color table of image - - // read the header info of image - for(i = 0; i < 54; i++) { - byte[i] = getc(fileIn); + unsigned char headerInfo[54]; + unsigned char colorTable[1024]; + + for(int i = 0; i < 54; i++) { + headerInfo[i] = getc(fileIn); } - // write header info to output file - fwrite(byte, sizeof(unsigned char), 54, fileOut); + fwrite(headerInfo, sizeof(unsigned char), 54, fileOut); - // extract height, width and bitDepth of image from header info - int height = *(int*)&byte[18]; - int width = *(int*)&byte[22]; - int bitDepth = *(int*)&byte[28]; + // Extract.. of image from header info + int height = *(int*)&headerInfo[18]; + int width = *(int*)&headerInfo[22]; + int bitDepth = *(int*)&headerInfo[28]; + int pixelsInImage = height * width; - // calculate size of image in pixels - int size = height * width; - - // check if image has a color table + // Check if image has a color table if(bitDepth <= 8) { - // read, then write color table from the input file fread(colorTable, sizeof(unsigned char), 1024, fileIn); fwrite(colorTable, sizeof(unsigned char), 1024, fileOut); } - // array to store image data in chunks - unsigned char buffer[CHUNK_SIZE]; + unsigned char chunkBuffer[CHUNK_SIZE]; - // read & write image data in chunks until the end of file is reached + // Read & write image data in chunks until the end of file is reached while(!feof(fileIn)) { - - // read a chunk of image data from input file - size_t bytesRead = fread(buffer, sizeof(unsigned char), CHUNK_SIZE, fileIn); - // apply brightness factor to each pixel in the chunk - for (i = 0; i < bytesRead; i++) { - buffer[i] = buffer[i] + BRIGHTNESS; - buffer[i] = (buffer[i] > THRESHOLD) ? MAX_COLOR : buffer[i]; + // Read a chunk of image data from the input file + size_t bytesRead = fread(chunkBuffer, sizeof(unsigned char), CHUNK_SIZE, fileIn); + + // Apply brightness factor to each pixel in the chunk + for (int i = 0; i < bytesRead; i++) { + chunkBuffer[i] = chunkBuffer[i] + BRIGHTNESS; + chunkBuffer[i] = (chunkBuffer[i] > THRESHOLD) ? MAX_COLOR : chunkBuffer[i]; } - // write thresholded image data to the output file - fwrite(buffer, sizeof(unsigned char), bytesRead, fileOut); + // Write thresholded image data to output file + fwrite(chunkBuffer, sizeof(unsigned char), bytesRead, fileOut); } - // write thresholded image data to the output file - fwrite(buffer, sizeof(unsigned char), size, fileOut); + // Write thresholded image data to output file + fwrite(chunkBuffer, sizeof(unsigned char), pixelsInImage, fileOut); fClose(fileIn); fclose(fileOut); diff --git a/C_image_processing/filters/dark_filter.c b/C_image_processing/filters/dark_filter.c index ff6444d..857fd31 100644 --- a/C_image_processing/filters/dark_filter.c +++ b/C_image_processing/filters/dark_filter.c @@ -1,4 +1,5 @@ #include + #define MAX_COLOR 255 #define THRESHOLD 40 // define threshold value for darkness #define CHUNK_SIZE 1024 // define size of chunks to read and write @@ -15,53 +16,48 @@ int dark_filter(inputFile, outputFile) { return 1; } - int i; - unsigned char byte[54]; // store header info of image - unsigned char colorTable[1024]; // store color table of image + unsigned char headerInfo[54]; + unsigned char colorTable[1024]; - // read header information of image - for(i = 0; i < 54; i++) { - byte[i] = getc(fileIn); + // Read header info of image + for(int i = 0; i < 54; i++) { + headerInfo[i] = getc(fileIn); } - // write header info to output file - fwrite(byte, sizeof(unsigned char), 54, fileOut); - - // extract height, width and bitDepth of the image from header information - int height = *(int*)&byte[18]; - int width = *(int*)&byte[22]; - int bitDepth = *(int*)&byte[28]; + // Write header info to output file + fwrite(headerInfo, sizeof(unsigned char), 54, fileOut); - // calculate size of image in pixels - int size = height * width; + // Extract.. of the image from header info + int height = *(int*)&headerInfo[18]; + int width = *(int*)&headerInfo[22]; + int bitDepth = *(int*)&headerInfo[28]; + int pixelsInImage = height * width; - // check if image has a color table + // Check if image has a color table if(bitDepth <= 8) { - // read, then write the color table from input file fread(colorTable, sizeof(unsigned char), 1024, fileIn); fwrite(colorTable, sizeof(unsigned char), 1024, fileOut); } - // array to store image data in chunks - unsigned char buffer[CHUNK_SIZE]; + unsigned char chunkBuffer[CHUNK_SIZE]; - // read & write image data in chunks until end of the file reached + // Read & write image data in chunks until end of file reached while(!feof(fileIn)) { // read a chunk of image data from input file - size_t bytesRead = fread(buffer, sizeof(unsigned char), CHUNK_SIZE, fileIn); + size_t bytesRead = fread(chunkBuffer, sizeof(unsigned char), CHUNK_SIZE, fileIn); // apply darkness threshold to each pixel in chunk - for (i = 0; i < bytesRead; i++) { - buffer[i] = buffer[i] + THRESHOLD; - buffer[i] = (buffer[i] > THRESHOLD) ? MAX_COLOR : buffer[i]; + for (int i = 0; i < bytesRead; i++) { + chunkBuffer[i] = chunkBuffer[i] + THRESHOLD; + chunkBuffer[i] = (chunkBuffer[i] > THRESHOLD) ? MAX_COLOR : chunkBuffer[i]; } // write thresholded image data to the output file - fwrite(buffer, sizeof(unsigned char), bytesRead, fileOut); + fwrite(chunkBuffer, sizeof(unsigned char), bytesRead, fileOut); } - // write thresholded image data to the output file - fwrite(buffer, sizeof(unsigned char), size, fileOut); + // Write thresholded image data to output file + fwrite(chunkBuffer, sizeof(unsigned char), pixelsInImage, fileOut); fClose(fileIn); fclose(fileOut); diff --git a/C_image_processing/filters/negative_filter.c b/C_image_processing/filters/negative_filter.c index 8954ec8..0c879ee 100644 --- a/C_image_processing/filters/negative_filter.c +++ b/C_image_processing/filters/negative_filter.c @@ -14,45 +14,46 @@ int negative_filter(const char *inputFile, const char *outputFile) { return 1; } - unsigned char *imageData; - unsigned char *newImageData; - unsigned char imageHeader[54]; + unsigned char *imageData = NULL; + unsigned char *newImageData = NULL; + unsigned char headerInfo[54]; unsigned char colorTable[1024]; - - int i, j; - // check if input file exists - fread(imageHeader, sizeof(unsigned char), 54, fileIn); - int width = *(int*)&imageHeader[18]; - int height = *(int*)&imageHeader[22]; - int bitDepth = *(int*)&imageHeader[28]; + // Read image header + fread(headerInfo, sizeof(unsigned char), 54, fileIn); + int width = *(int*)&headerInfo[18]; + int height = *(int*)&headerInfo[22]; + int bitDepth = *(int*)&headerInfo[28]; int imageDataSize = width * height; + // Allocate memory for image data imageData = (unsigned char*)malloc(imageDataSize * sizeof(unsigned char)); newImageData = (unsigned char*)malloc(imageDataSize * sizeof(unsigned char)); - // check if image has a color table + // Read color table if present if (bitDepth <= 8) { fread(colorTable, sizeof(unsigned char), 1024, fileIn); } + // Read original image data fread(imageData, sizeof(unsigned char), imageDataSize, fileIn); - // apply negative filter to each pixel + // Apply negative filter to each pixel unsigned char *p = imageData; unsigned char *q = newImageData; - for (i = 0; i < height * width; i++) { + for (int i = 0; i < height * width; i++) { *q++ = 255 - *p++; } - // write image data to output file - fwrite(imageHeader, sizeof(unsigned char), 54, fileOut); + // Write image data to output file + fwrite(headerInfo, sizeof(unsigned char), 54, fileOut); if (bitDepth <= 8) { fwrite(colorTable, sizeof(unsigned char), 1024, fileOut); } - + fwrite(newImageData, sizeof(unsigned char), imageDataSize, fileOut); + // Clean up and close files fclose(fileIn); fclose(fileOut); diff --git a/C_image_processing/filters/rgb_to_gray_filter.c b/C_image_processing/filters/rgb_to_gray_filter.c index 8a16d2c..51f81c0 100644 --- a/C_image_processing/filters/rgb_to_gray_filter.c +++ b/C_image_processing/filters/rgb_to_gray_filter.c @@ -4,9 +4,6 @@ int rgb_to_gray_filter(inputFile, outputFile) { FILE *fileIn = fopen(inputFile, "rb"); FILE *fileOut = fopen(outputFile, "wb+"); - - int i; - unsigned char byte[54]; // store header info if (fileIn == NULL || fileOut == NULL) { printf("File does not exist.\n"); @@ -15,42 +12,43 @@ int rgb_to_gray_filter(inputFile, outputFile) { return 1; } - // read header info of image - for(i = 0; i < 54; i++) { - byte[i] = getc(fileIn); - } - - // write header info to output file - fwrite(byte, sizeof(unsigned char), 54, fileOut); + // Read and write header info + unsigned char headerInfo[54]; + fread(headerInfo, sizeof(unsigned char), 54, fileIn); + fwrite(headerInfo, sizeof(unsigned char), 54, fileOut); - // extract height, width & bitDepth of image from header info - int height = *(int*)&byte[18]; - int width = *(int*)&byte[22]; - int bitDepth = *(int*)&byte[28]; - int size = height * width; + // Extract image dimensions from header info + int height = *(int*)&headerInfo[18]; + int width = *(int*)&headerInfo[22]; + int bitDepth = *(int*)&headerInfo[28]; + int pixelsInImage = height * width; - unsigned char (*buffer)[3] = malloc(size * sizeof(*buffer)); // store image data + // Allocate Memory to Image Data + unsigned char (*buffer)[3] = malloc(pixelsInImage * sizeof(*buffer)); if (buffer == NULL) { printf("Memory allocation failed.\n"); + fclose(fileIn); + fclose(fileOut); return 1; } - unsigned char y; - for(i = 0; i < size; i ++) { - y = 0; - buffer[i][0] = getc(fileIn); // red - buffer[i][1] = getc(fileIn); // green - buffer[i][2] = getc(fileIn); // blue - - // RGB to gray - y = (buffer[i][0] * 0.3) + (buffer[i][2] * 0.11); - - // Triplicate grayscale value for three color channels - putc(y, fileOut); - putc(y, fileOut); - putc(y, fileOut); + for (int i = 0; i < pixelsInImage; i++) { + + // read RGB color components of current pixel from input file + buffer[i][0] = getc(fileIn); // Red + buffer[i][1] = getc(fileIn); // Green + buffer[i][2] = getc(fileIn); // Blue + + // calculate grayscale value using weighted average of red and blue components + unsigned char grayscaleValue = (buffer[i][0] * 0.3) + (buffer[i][2] * 0.11); + + // write the calculated grayscale value to the output file for each RGB channel + putc(grayscaleValue, fileOut); // Red + putc(grayscaleValue, fileOut); // Green + putc(grayscaleValue, fileOut); // Blue } + // Clean up / Close fClose(fileIn); fclose(fileOut); return 0; diff --git a/C_image_processing/filters/sepia_filter.c b/C_image_processing/filters/sepia_filter.c index 23d192b..44a9313 100644 --- a/C_image_processing/filters/sepia_filter.c +++ b/C_image_processing/filters/sepia_filter.c @@ -1,4 +1,5 @@ #include + #define MAX_VALUE 255 int sepia_filter(inputFile, outputFile) { @@ -6,9 +7,6 @@ int sepia_filter(inputFile, outputFile) { FILE *fileIn = fopen(inputFile, "rb"); FILE *fileOut = fopen(outputFile, "wb+"); - int i, r, g, b; - unsigned char byte[54]; - if (fileIn == NULL || fileOut == NULL) { printf("File does not exist.\n"); if (fileIn != NULL) fclose(fileIn); @@ -16,36 +14,35 @@ int sepia_filter(inputFile, outputFile) { return 1; } - // read header info of image - for(i = 0; i < 54; i++) { - byte[i] = getc(fileIn); + // Read header info of image + unsigned char headerInfo[54]; + for(int i = 0; i < 54; i++) { + headerInfo[i] = getc(fileIn); } + + // Write header info to output file + fwrite(headerInfo, sizeof(unsigned char), 54, fileOut); - // write header info to output file - fwrite(byte, sizeof(unsigned char), 54, fileOut); - - // extract height, width and bitDepth of image from header info - int height = *(int*)&byte[18]; - int width = *(int*)&byte[22]; - int bitDepth = *(int*)&byte[28]; - - // calculate size of image in pixels - int size = height * width; + // Extract.. of image from header info + int height = *(int*)&headerInfo[18]; + int width = *(int*)&headerInfo[22]; + int bitDepth = *(int*)&headerInfo[28]; + int pixelsInImage = height * width; - unsigned char (*buffer)[3] = malloc(size * sizeof(*buffer)); // store the image data + // Store image data in buffer + unsigned char (*buffer)[3] = malloc(pixelsInImage * sizeof(*buffer)); if (buffer == NULL) { printf("Memory allocation failed.\n"); return 1; } - for(i = 0; i < size; i++) { - r = 0; g = 0; b = 0; + for(int i = 0; i < pixelsInImage; i++) { + int r = 0, g = 0, b = 0; buffer[i][0] = getc(fileIn); // red buffer[i][1] = getc(fileIn); // green buffer[i][2] = getc(fileIn); // blue - - // each pixel value is above 255? + if(r > MAX_VALUE) { r = MAX_VALUE; } else if (g > MAX_VALUE) { @@ -53,7 +50,7 @@ int sepia_filter(inputFile, outputFile) { } else if (b > MAX_VALUE) { b = MAX_VALUE; } - // Triplicate grayscale value for three color channels + // add Grayscale filter to each pixel putc(b, fileOut); putc(b, fileOut); putc(b, fileOut); diff --git a/C_image_processing/main.c b/C_image_processing/main.c index 5bc5629..dfdabfd 100644 --- a/C_image_processing/main.c +++ b/C_image_processing/main.c @@ -1,10 +1,11 @@ #include "filters/black_and_white_filter.c" #include "filters/negative_filter.c" +#include int main() { + const char* inputFileName = "assets/images/test_image.bmp"; const char* outputFileName = "assets/images/output.bmp"; - int result = black_and_white_filter(inputFileName, outputFileName); switch (result) {