- /**
- * Names: Luke Whipple and Colton Johnson and David Dubchakov
- *
- * Some image manioulation functions for an array of pixels
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- #define STB_IMAGE_IMPLEMENTATION
- #include "stb_image.h"
- #define STB_IMAGE_WRITE_IMPLEMENTATION
- #include "stb_image_write.h"
- #include "imageUtils.h"
- Pixel **loadImage(const char *filePath, int *height, int *width) {
- int x,y,n;
- unsigned char *data = stbi_load(filePath, &x, &y, &n, 4); //4 = force RGBA channels
- *height = y;
- *width = x;
- //contiguous allocation:
- Pixel **image = (Pixel **)malloc(sizeof(Pixel *) * y);
- image[0] = (Pixel *)malloc(sizeof(Pixel) * (y * x));
- for(int i=1; i<y; i++) {
- image[i] = (*image + (x * i));
- }
- int rowIndex = 0;
- int colIndex = 0;
- for(int i=0; i<(x * y * 4); i+=4) { //for each row
- image[rowIndex][colIndex].red = data[i+0];
- image[rowIndex][colIndex].green = data[i+1];
- image[rowIndex][colIndex].blue = data[i+2];
- colIndex++;
- if(colIndex == x) {
- //go to next row, reset column
- rowIndex++;
- colIndex=0;
- }
- }
- stbi_image_free(data);
- return image;
- }
- void saveImage(const char *fileName, Pixel **image, int height, int width) {
- // Convert height x width Pixel array to single array with
- // 3 (RGB) channels, ignoring the alpha channel and assume 100% opaque
- unsigned char *data = (unsigned char *) malloc(height * width * 3);
- int x = 0;
- for(int i=0; i<height; i++) {
- for(int j=0; j<width; j++) {
- data[x+0] = image[i][j].red;
- data[x+1] = image[i][j].green;
- data[x+2] = image[i][j].blue;
- x+=3;
- }
- }
- //write
- stbi_write_jpg(fileName, width, height, 3, data, 100);
- free(data);
- return;
- }
- Pixel ** copyImage(Pixel ** image, int height, int width) {
- if ((height <= 0) || (width <= 0) || (image == NULL)) {
- return (NULL);
- }
- Pixel ** copy = NULL;
- copy = (Pixel ** ) malloc(sizeof(Pixel) * height);
- for (int k = 0; k < height; k++) {
- copy[k] = (Pixel * ) malloc(sizeof(Pixel) * width);
- }
- int i = 0;
- int j = 0;
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++) {
- copy[i][j] = image[i][j];
- }
- }
- return (copy);
- }
- void flipHorizontal(Pixel ** image, int height, int width) {
- for (int i = 0; i < height; i++) {
- for (int n = 0; n < (width / 2); n++) {
- Pixel placeHolder = image[i][n];
- image[i][n] = image[i][width - 1 - n];
- image[i][width - 1 - n] = placeHolder;
- }
- }
- }
- /**
- * for (i = 0; i < (NUM_ELEMENTS / 2); ++i) {
- tempVal = userVals[i]; // Temp for swap
- userVals[i] = userVals[NUM_ELEMENTS - 1 - i]; // First part of swap
- userVals[NUM_ELEMENTS - 1 - i] = tempVal; // Second complete
- }
- */
- //TODO: implement
- void flipVertical(Pixel ** image, int height, int width) {
- for (int i = 0; i < width; i++) {
- for (int n = 0; n < (height / 2); n++) {
- Pixel placeHolder = image[n][i];
- image[n][i] = image[height - 1 - n][i];
- image[height - 1 - n][i] = placeHolder;
- }
- }
- }
- Pixel ** rotateClockwise(Pixel ** image, int height, int width) {
- int placeHolder = height;
- height = width;
- width = placeHolder;
- Pixel ** rotate = NULL;
- rotate = (Pixel ** ) malloc(sizeof(Pixel) * height);
- for (int k = 0; k < height; k++) {
- rotate[k] = (Pixel * ) malloc(sizeof(Pixel) * width);
- }
- for (int i = 0; i < height; i++) {
- for (int j = 0; j < width; j++) {
- rotate[i][j] = image[j][i];
- }
- //TODO: implement
- }
- flipHorizontal(rotate, height, width);
- placeHolder = height;
- height = width;
- width = placeHolder;
- return (rotate);
- }