-
Notifications
You must be signed in to change notification settings - Fork 0
dandominicstaicu/Image_Editor_in_C
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Copyright 2023 311CA Dan-Dominic Staicu <dando.ds11@gmail.com> ~Hinds' Law Of Computer Programming~ ~3. If a program is useless, it will have to be documented.~ IMAGE EDITOR ~Murphy's First Law: Anything that can go wrong will go wrong.~ *This program was written in C and can edit photos in format NetPBM *Works with a set of commands inputed from STDIN *Can read/write text (P2, P3) or binary (P5, P6) file formats *Has text inteface for transforming these photo files (only .pgm, .ppm) It has the following functions implemented byh commands: %LOAD a photo as a matrix in memory; if LOAD was inputed, the program tries to open the file with the given name/at the given path; *if the file doesn't exist, an error is printed at STDOUT; *if the file coud be opened, than the program reads photo's magic-word dimensions, and max value (already known to be 255 in our case, so it just steps over it) while ignoring the comments; *if the magic word describes a binary file (P5, P6), it uses fread in order to interpret the values as ints; it pases 1 as size_t size and size_t nmemb in order to interpret values written on only one byte as an int value; *if the magic word describes a text file (P2, P3), it uses fscanf in order to read and save the pixels' values inside a matrix; *if the photo is Black and White (P2, P5) it uses only one matrix in order to memorise it *if the photo is Color (P3, P6) it uses 3 matrixes in order to memorise each color channel in a different matrix, keeping the same column (and line) count for all of them; it's also easier to work with a pixel's neighbors *if the process was executed succesfuly, a succes message is printed The complexity of LOAD command is O(col * lines) The loaded photo is saved in memory as a (struct) photo_t variable which contains variables *the type of photo (2, 3, 5, 6) as an int *for the number of lines and columns of the photo's matrix, *the coordinates of selection (top right and bottom left pixels' coords) *a double pointer to int in case the readen matrix will be Black and white, so it will need only one matrix *a rgb_t varbaile rgb_t is a struct defined as 3 double pointers to int (in order to use them for 3 matrixes, one for each color channel, in case the photo to be loaded is color) %SELECT an area inside a photo; if SELECT was inputed it expects 4 coords in order to memorise 2 points which define the selected area inside the mat If 4 ints were inputed the still need validation; *if they are in the wrong order (eg. y1 > y2) they need to be swaped *if no photo was loaded, an error message is displayed and no selection is done *if the selected area isn't valid (because the interval is [x1, x2) ), an error is printed (eg. if x1x == x2, selection isn't valid) *if the coords are "outside the photo", an error is displayed *if they are correct, we save them using the real selection size (y2 - 1, x2 - 1), and a succes message is displayed SELECT can also expect the ALL parameter which means the selected area is the whole photo (same as bottom y = column cnt - 1) The complexity of SELECT is O(1) Unfortunately, parameters can be inputed wrong resulting into an Invalid command. ~Murphy's Fourteenth Law: If anything can't go wrong on its own, someone will make it go wrong.~ So, in case there are less than 4 ints readen or any other text than ALL, the Invalid command error is printed ~Software bugs are impossible to detect by anybody except the end user.~ %Create the HISTOGRAM of a Black and White photo; this comand expects two int parameters, which are the number of stars and the count of bins; *if no image was loaded, print no load error *if there are less/more than 2 parameters, print invalid command error ~Failure is not an option. It comes bundled with the software.~ *if given photo is color, print black and white photo needed error The Histogram is created by counting the occurances of pixels in a frquency array; these frequences are later cumulated in "bins" number of bins (one bin including 256/bins pixel frequences); these bins are graphically represented according to the formula star_number = (pixel_freq * stars) / value_max The complexity of HISTOGRAM is O(col * lin) %EQUALIZE a Black and White photo (applies on the whole photo, not only on the selection) *check if the equalization can be done (only if a photo was loaded, if that photo is black and white) *create a frequency array for the occurances of every pixel inside the photo matrix *take every pixel from the photo and apply the formula sum / area * MAX_VAL, where sum is the sum of the frequences of every pixel from 0 to the current pixel, area is the area of the whole photo, in pixels, and MAX value is the 255 MAX value of our photo type; the result of this formula is clamped between 0 and 255 in order to have only valid values inside the new photo; *the old photo is overwritten by the new equalized one *if equalization was done succesfully, a succes message is printed The complexity of EQUALIZE is O(2 * lin * col) [frq_array] + [taking every pixel and calculating that formula] => O(lin * col) %ROTATE a whole photo or a square selection inside the photo *check if any photo was loaded *check if the rotate angle is valid (-360 < angle < 360, angle % 90 == 0); because of these facts, we can rotate any photo 90/-90 degrees multiple times, until it matches our given angle; the number of rotation is angle / 90 if angle is positive or angle / 90 * (-1) if angle is negative; *rotate a photo to right if positive, to left if negative *if its color, every color channel has to be rotated separately *there is only one rotating function used for both color and bw photos as it only crops a matrix, regardless photo's type *if it's a selection, the selection has to be square (sel_lin == sel_col) *if the whole photo was selected, it can be rotated anyway, even if it's not square *when rotating to right, it writes the values from the original selection, but it starts with the top right corner of the new matrix, and than goes down the column and left on the line *when rotating to left, it writes the values from the original selection, but it starts with the bottom left corner of the new matrix, and than goes up on the column and than right on the line *if the rotation was done sucessfully, print a succes message The complexity of ROTATE is O(sel_lin * sel_col) %CROP the photo acording to the selection *checks if there is any loaded photo *creates new matrix(es) containing only the values inside the selection from the old photo *frees the memory where the old photo was storaged *points to the new memory *there is only one croping function used for both color and bw photos as it only crops a matrix, regardless photo's type it's applied only once if the photo is bw and 3 times if the photo is color (for each color channel) The complexity of CROP is O(sel_lin * sel_col) %Can APPLY an effect over a selection in a color photo *4 types of effect *there is only one function (**apply_kern()) that can apply any given kernel matrix and any divide coefficient over a selection inside the photo matrix; function kern() just overwrites the old selected matrix with the newly created matrix (by apply_kern()) *checks if apply can be done (if any image was loaded, if the readen parameter is valid) *if you try to APPLY over an BW photo, a computer will call you Charlie Chaplin ~Some people manage by the book, even they don't know who wrote the book, or even what book.~ The complexity of APPLY is O(sel_lin * sel_col) as it's effect is only over a selection %Can SAVE a photo *as ascii or binary no matter if it was ascii (P2/P3) or binary (P5/P6) when it was loaded *default save is binary, it will save only if ascii parameter was read, which is an optional parameter, so it checks how many parameters are read using fgets and strtok *creates a new file where to save or opens the existing one having the same name and overwrites it *for saving as text it uses fprintf and for saving as binary it uses fwrite *fwrite has 1 and 1 as size_t size and size_t nmemb parameters, in order to write the int value from the matrix on one byte; *if photo was color, it prints the 3 color channel matrixes simultaneous The complexity of SAVE is O(lin * col) %(finally)EXIT the program *prints error message if no photo was loaded, but anyway exits it *gratefully frees all the used memory at the time it was called The complexity of EXIT is O(lines) as it only has to free the photo matrix(es) PROGRAMS' STRUCTURE ~Weinberg's Second Law: If builders built buildings the way programmers write programs, then the first woodpecker that came along would destroy civilization.~ - image_editor.c is the main function - every command has it's own .c with it's functions and it's own .h - errors.c/.h has every error message inside the program - succes.c/.h has every succes message inside the program - matrix_op.c/.h has the most used functions for matrix memory (alloc and free) and some checks for devensive programming - utils.c/.h contain some useful functions - photo_type.h contains the definition of the structs VERSION CONTROL ~Murphy's Second Law: Nothing is as easy as it looks.~ ~Murphy's Third Law: Everything takes longer than you think it will.~ commit 1: initial commit *added empty README commit 2: added makefile and main file *added empty main image_editor.c *added makefile commit 3: maybe LOAD works *added command input from stdin *created hashing for commands in order to use switch *created struct for memorising the loaded photo *implemented basic LOAD *can open a file *checks if file exists *error handling if doesn't exit *check and remember photo type *hashing for photo type *can load a photo regardless it's type commit 4: work in progress on SAVE *solved memory leak of not closing the file when loading *added succes message for loading *added no image loaded error *implemented new PROBLEM with getchar(), which cannot be called at the end of any case *refactor - eliminated query file *work in progress on SAVE commit 5: loading and saving works with 3 known bugs *loading and saving working *implemented (Bug) feature with loading as P6 with wrong colours *after reading SAVE with only one parameter an extra \n is displayed *names of saved documents just aren't ok commit 6: solved bugs from LOAD and SAVE *solved file names bugs *solved colour bug commit 7: implemented SELECT (ALL) *implemented SELECT *select splits in SELECT ALL and SELECT <coords> *order of coords can be descending commit 8: implemented histogram *I THINK I implemented it, not sure yet, no checker was published commit 9: EQUALIZE *implemented EQUALIZE *created function for EXIT *some cleaning commit 10: working on CROP *redone selection logic *reminder to implement loading ignoring #comments *CROP seg fault for colour photos *CROP selecting +1 more pixels thant requested commit 11: CROP and SELECT in development *maybe messed up crop and select commit 12: fixed SELECT logic and CROP *maybe fixed CROP and SELECT commit 13: working on APPLY *CHECKER WAS PUBLISHED *repaired select logic *apparantly SELECT and CROP are working *work in progress on apply commit 14: refactor RGB *refactored logic for RGB photos *in order to have 3 columns in a greater matrix for each value, now it saves 3 matrixes with the exact number of lins and cols, one for each color channel commit 15: APPLY in development *created functions for every kind of APPLY *implemented new BUGS *created mutual funcrtions to aplly any kind of kernel in the same way commit 16: fixed APPLY *fixed EDGE and SHARPEN *fixed APPLY without parameter bug *TODO run with valgrind commit 17: working on ROTATE *added new error messages as functions *rotate work in progress *created messages for rotate *cleaned up some dead code commit 18: ROTATE for SELECT ALL working *rotate not working for selections on P2 P5 *rotate not working for selections on P3 P6 *rotate working on SELECT ALL P2 P5 *rotate working on SELECT ALL P3 P6 commit 19: Fixed ROTATE *fixed bug with rotate not working on selections inside the photo commit 20: unconditional jump at save *started debugging tests from checker *start grade = 16.6666/90 + 10 README = 26.6666 *added freeing matrix before loading a new one *detected bug with uncoditional jump at save commit 21: fixed SAVE unconditional jump *problem was tracked from LOAD alloc_matrix *changed from malloc to calloc in alloc_matrix() commit 22: 45/110 *fixed APPLY error message when command was ok *fixed 2 invalid command error messages for only one command *fixed BLUR and GAUSSIAN_BLUR result accucaramelldansenracy *fixed reading GAUSSIAN_BL only commit 23: 85.5/110 *fixed no load error on SAVE *fixed EXIT error and close the program *fixed SLECT error to display when x1 == x2 *fixed invalid read size at APPLY *fixed no_load error at SELECT *fixed wrong display order at SELECT commit 24: 93/110 *fixed SELECT wrong parameters commit 25: 95/110 *fixed HISTOGRAM wrong parameters *cleaned some comments commit 26: 100/110 *fixed ROTATE read error commit 27: 110/110 Coding Style *Coding Style compliant *added Copyright on every file commit 28: beauty refactor and comments *TODO write README lol *refactored function structures *created function for some duplicated code *cleaner declaration of matrix *heavily commented code commit 29: step over comments *can step over comments at load *minor Coding Style fixes commit 30: README *written README lol *added quotes inside the README ~Carlson's Consolation: Nothing is ever a complete failure; it can always serve as a bad example.~ commit 31: struct point *added a struct to define a 2D point ~Murphy's Thirteenth Law: Every solution breeds new problems.~ commit 32: Defensive alloc *added more defensive programming at memory allocation ~Murphy's Eleventh Law: It is impossible to make anything foolproof because fools are so ingenious.~ commit 33: ROTATE refactor *created function with parameter as function at ROTATE command
About
Homework 3 of PCLP1
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published