Last active
September 2, 2024 06:53
-
-
Save NickBeeuwsaert/5753386 to your computer and use it in GitHub Desktop.
example of a bilinear interpolating thingy.
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
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include "image.h" | |
uint32_t getpixel(image_t *image, unsigned int x, unsigned int y){ | |
return image->pixels[(y*image->w)+x]; | |
} | |
float lerp(float s, float e, float t){return s+(e-s)*t;} | |
float blerp(float c00, float c10, float c01, float c11, float tx, float ty){ | |
return lerp(lerp(c00, c10, tx), lerp(c01, c11, tx), ty); | |
} | |
void putpixel(image_t *image, unsigned int x, unsigned int y, uint32_t color){ | |
image->pixels[(y*image->w) + x] = color; | |
} | |
void scale(image_t *src, image_t *dst){ | |
int x, y; | |
for(x = 0; x < dst->w; x++){ | |
for(y = 0; y < dst->h; y++){ | |
//if(x > newWidth){ | |
// x = 0; y++; | |
//} | |
float gx = (float)(x) / (float)(dst->w) * (float)(src->w-1); | |
float gy = (float)(y) / (float)(dst->h) * (float)(src->h-1); | |
int gxi = (int)gx; | |
int gyi = (int)gy; | |
uint32_t result=0; | |
uint32_t c00 = getpixel(src, gxi, gyi); | |
uint32_t c10 = getpixel(src, gxi+1, gyi); | |
uint32_t c01 = getpixel(src, gxi, gyi+1); | |
uint32_t c11 = getpixel(src, gxi+1, gyi+1); | |
size_t i; | |
for(i = 0; i < sizeof(result); i++){ | |
result |= (uint8_t)blerp(getByte(c00, i), getByte(c10, i), getByte(c01, i), getByte(c11, i), (gx - gxi), (gy - gyi)) << (8*i); | |
} | |
putpixel(dst,x, y, result); | |
} | |
} | |
} | |
image_t *createImage(unsigned int w, unsigned int h){ | |
image_t *image = (image_t*)malloc(sizeof(image_t)); | |
image->pixels = malloc(w*h*sizeof(uint32_t)); | |
memset(image->pixels, 0, w*h*sizeof(uint32_t)); | |
image->w = w; | |
image->h = h; | |
return image; | |
} | |
void freeImage(image_t* t){ | |
free(t->pixels); | |
free(t); | |
} | |
void saveToPPM(char* out, image_t *img){ | |
FILE *file = fopen(out, "w+"); | |
fprintf(file, "P3\n%d %d\n255\n", img->w, img->h); | |
uint32_t x, y; | |
for(y = 0; y < img->h; y++){ | |
for(x = 0; x < img->w; x++){ | |
uint32_t pixel = getpixel(img, x, y); | |
fprintf(file, "%d %d %d ", getByte(pixel, 0), getByte(pixel, 1), getByte(pixel, 2)); // we are only writing rgb, no alpha | |
} | |
fputs("\n", file); | |
} | |
fclose(file); | |
} |
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
#ifndef __IMAGE_H__ | |
#define __IMAGE_H__ | |
#include <stdint.h> | |
typedef struct { | |
uint32_t *pixels; | |
int w; | |
int h; | |
}image_t; | |
uint32_t getpixel(image_t*, unsigned int, unsigned int); | |
float lerp(float, float, float); | |
float blerp(float, float, float, float, float, float); | |
void putpixel(image_t*, unsigned int, unsigned int, uint32_t); | |
#define getByte(value, n) (value >> (n*8) & 0xFF) | |
void scale(image_t*, image_t*); | |
image_t *createImage(unsigned int, unsigned int); | |
void freeImage(image_t*); | |
void saveToPPM(char*, image_t*); | |
#endif // __IMAGE_H__ |
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
/* | |
compile with: | |
$(CC) main.c image.c -o main | |
Usage: | |
./main [width height scaled_width scaled_height] | |
*/ | |
#include <stdio.h> | |
#include <stdint.h> | |
#include "image.h" | |
int main(int argc, char *argv[]){ | |
int nw = 500, nh = 500; | |
int w = 2, h= 2; | |
if(argc == 5){ | |
w = atoi(argv[1]); | |
h = atoi(argv[2]); | |
nw = atoi(argv[3]); | |
nh = atoi(argv[4]); | |
} | |
image_t *testImg = createImage(w,h); | |
uint32_t x, y; | |
printf("w: %d, h: %d\n", testImg->w, testImg->h); | |
for(x = 0; x<testImg->w; x++){ | |
for(y = 0; y < testImg->h; y++){ | |
uint32_t pixel = 0; | |
pixel |= (int)((x/(float)testImg->w)*255) << 0; | |
pixel |= (int)((y/(float)testImg->h)*255) << 8; | |
pixel |= (127) << 16; | |
pixel |= (255 << 24); | |
putpixel(testImg, x, y,pixel); | |
} | |
} | |
image_t *out = createImage(nw,nh); | |
scale(testImg, out); | |
saveToPPM("a.ppm", testImg); | |
saveToPPM("b.ppm", out); | |
freeImage(testImg); | |
freeImage(out); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment