Skip to content

Instantly share code, notes, and snippets.

@NickBeeuwsaert
Last active December 18, 2015 08:19
Show Gist options
  • Save NickBeeuwsaert/5753386 to your computer and use it in GitHub Desktop.
Save NickBeeuwsaert/5753386 to your computer and use it in GitHub Desktop.
example of a bilinear interpolating thingy.
#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);
}
#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__
/*
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