-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The content of filter.c is courtesy of Tekky, based in part on a file of the same name from Harvard's CS50x. The definitions of the BMP headers and RGBTRIPLE added to filter.h are directly from CS50x's bmp.h. N.B. This challenge and it's code have been structured in such a way that it must not breach the academic honesty policy of CS50x.
- Loading branch information
bolt
committed
Jan 12, 2025
0 parents
commit 11a1531
Showing
7 changed files
with
8,216 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
filter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
CC := clang | ||
|
||
CFLAGS := -march=native -std=c18 -Wall -Wextra -pthread | ||
CFLAGS_debug := -O0 -ggdb3 -gdwarf-4 | ||
CFLAGS_release := -O3 | ||
|
||
LDFLAGS := -lm | ||
|
||
all: release | ||
|
||
debug: CFLAGS += $(CFLAGS_debug) | ||
debug: filter | ||
release: CFLAGS += $(CFLAGS_release) | ||
release: filter | ||
|
||
filter: filter.c filter.h | ||
$(CC) $(CFLAGS) -o $@ filter.c $(LDFLAGS) | ||
|
||
.PHONY: release debug |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Fast Blur Challenge | ||
|
||
Implement the `blur()` function in `blur.c`. Make it as fast as possible. | ||
|
||
## Rules | ||
|
||
1. | ||
|
||
## DEADLINE | ||
|
||
18 Jan 17:00pm UTC. | ||
(Temporarily subject to alteration.) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/* | ||
* TODO: Implement | ||
*/ | ||
void | ||
blur(uint32_t height, uint32_t width, RGBTRIPLE input[height][width], | ||
RGBTRIPLE output[height][width], uint32_t size) | ||
{ | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
#define _DEFAULT_SOURCE | ||
|
||
#include <stdint.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <sys/resource.h> | ||
#include <sys/time.h> | ||
|
||
#define STB_IMAGE_IMPLEMENTATION | ||
#include "stb_image.h" | ||
|
||
#include "filter.h" | ||
#include "blur.c" | ||
|
||
#define BLUR_SIZE 3 | ||
|
||
int main( int argc, char *argv[] ) | ||
{ | ||
BITMAPFILEHEADER bf = { 0x4D42, 0, 0, 0, sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) }; | ||
BITMAPINFOHEADER bi = { sizeof(BITMAPINFOHEADER), 0, 0, 1, 24, 0, 0, 11811, 11811, 0, 0 }; | ||
int width, height, num_channels; | ||
struct rusage before, after; | ||
struct timeval total_before, total_after, difference; | ||
|
||
// check for correct number of arguments | ||
if ( argc != 3 ) | ||
{ | ||
fprintf( stderr, "Usage: %s [inputfile] [outputfile]\n", argv[0] != NULL ? argv[0] : "filter" ); | ||
exit( EXIT_FAILURE ); | ||
} | ||
|
||
// open and decode input file | ||
unsigned char *input = stbi_load( argv[1], &width, &height, &num_channels, 3 ); | ||
if ( input == NULL ) | ||
{ | ||
fprintf( stderr, "Error opening/decoding input file!\n" ); | ||
exit( EXIT_FAILURE ); | ||
} | ||
|
||
// change RGB channel order to BGR | ||
for ( int i = 0; i < width * height * 3; i += 3 ) | ||
{ | ||
unsigned char temp = input[i]; | ||
input[i] = input[i+2]; | ||
input[i+2] = temp; | ||
} | ||
|
||
// allocate memory output bitmap data | ||
RGBTRIPLE(*output)[width] = calloc( height * width, sizeof(RGBTRIPLE) ); | ||
if ( output == NULL ) | ||
{ | ||
fprintf( stderr, "Error allocating memory for output image data!\n" ); | ||
exit( EXIT_FAILURE ); | ||
} | ||
|
||
// perform the actual function call to blur | ||
fprintf( stderr, "Calling function blur..." ); | ||
getrusage( RUSAGE_SELF, &before ); | ||
blur( height, width, (RGBTRIPLE(*)[width])input, output, BLUR_SIZE ); | ||
getrusage( RUSAGE_SELF, &after ); | ||
fprintf( stderr, "finished.\n" ); | ||
|
||
// free input image | ||
stbi_image_free( input ); | ||
|
||
// calculate difference between starting time and ending time | ||
timeradd( &before.ru_utime, &before.ru_stime, &total_before ); | ||
timeradd( & after.ru_utime, & after.ru_stime, &total_after ); | ||
timersub( &total_after, &total_before, &difference ); | ||
|
||
// print rusage data | ||
fprintf | ||
( | ||
stderr, | ||
"Elapsed time: %.5f seconds\n", | ||
( difference.tv_sec * 1000 * 1000 + difference.tv_usec ) / ( 1000.0 * 1000.0) | ||
); | ||
|
||
// open output file | ||
FILE *fp = fopen( argv[2], "wb" ); | ||
if ( fp == NULL ) | ||
{ | ||
fprintf( stderr, "Error opening output file!\n" ); | ||
exit( EXIT_FAILURE ); | ||
} | ||
|
||
// calculating amount of padding | ||
int padding = ( 4 - ( width * sizeof(RGBTRIPLE) ) % 4 ) % 4; | ||
|
||
// write headers to output file | ||
bf.bfSize = bf.bfOffBits + ( ( sizeof(RGBTRIPLE) * width ) + padding ) * height; | ||
bi.biWidth = width; | ||
bi.biHeight = -height; | ||
fwrite( &bf, sizeof bf, 1, fp ); | ||
fwrite( &bi, sizeof bi, 1, fp ); | ||
|
||
// write bitmap data to output file | ||
for ( int i = 0; i < height; i++ ) | ||
{ | ||
fwrite( output[i], sizeof(RGBTRIPLE), width, fp ); | ||
|
||
// add padding | ||
for ( int j = 0; j < padding; j++ ) | ||
{ | ||
putc( 0x00, fp ); | ||
} | ||
} | ||
|
||
// close output file | ||
fclose(fp); | ||
|
||
// free output bitmap data | ||
free( output ); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#include <stdint.h> | ||
|
||
/* -------------------------------------------------------------------------- */ | ||
|
||
// BMP-related data types based on Microsoft's own | ||
|
||
// These data types are essentially aliases for C/C++ primitive data types. | ||
// Adapted from http://msdn.microsoft.com/en-us/library/cc230309.aspx. | ||
// See https://en.wikipedia.org/wiki/C_data_types#stdint.h for more on stdint.h. | ||
|
||
typedef uint8_t BYTE; | ||
typedef uint32_t DWORD; | ||
typedef int32_t LONG; | ||
typedef uint16_t WORD; | ||
|
||
// The BITMAPFILEHEADER structure contains information about the type, size, | ||
// and layout of a file that contains a DIB [device-independent bitmap]. | ||
// Adapted from http://msdn.microsoft.com/en-us/library/dd183374(VS.85).aspx. | ||
|
||
typedef struct | ||
{ | ||
WORD bfType; | ||
DWORD bfSize; | ||
WORD bfReserved1; | ||
WORD bfReserved2; | ||
DWORD bfOffBits; | ||
} __attribute__((__packed__)) | ||
BITMAPFILEHEADER; | ||
|
||
// The BITMAPINFOHEADER structure contains information about the | ||
// dimensions and color format of a DIB [device-independent bitmap]. | ||
// Adapted from http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx. | ||
|
||
typedef struct | ||
{ | ||
DWORD biSize; | ||
LONG biWidth; | ||
LONG biHeight; | ||
WORD biPlanes; | ||
WORD biBitCount; | ||
DWORD biCompression; | ||
DWORD biSizeImage; | ||
LONG biXPelsPerMeter; | ||
LONG biYPelsPerMeter; | ||
DWORD biClrUsed; | ||
DWORD biClrImportant; | ||
} __attribute__((__packed__)) | ||
BITMAPINFOHEADER; | ||
|
||
// The RGBTRIPLE structure describes a color consisting of relative intensities of | ||
// red, green, and blue. Adapted from http://msdn.microsoft.com/en-us/library/aa922590.aspx. | ||
|
||
typedef struct | ||
{ | ||
BYTE rgbtBlue; | ||
BYTE rgbtGreen; | ||
BYTE rgbtRed; | ||
} __attribute__((__packed__)) | ||
RGBTRIPLE; | ||
|
||
/* -------------------------------------------------------------------------- */ | ||
|
||
/* | ||
* Box-blur image and store the result in output. | ||
* | ||
* image is expected to point to a region of memory with pixel data for | ||
* (height * width) RGBTRIPLE's. | ||
* output is expected to point to a writable region of memory with a size of | ||
* height * width * sizeof(RGBTRIPLE). | ||
* size denotes the box blur radius. | ||
*/ | ||
void blur(uint32_t height, uint32_t width, RGBTRIPLE input[height][width], RGBTRIPLE output[height][width], uint32_t size); |
Oops, something went wrong.