I found this code which seems to do what you want :
http://fvirtman.free.fr/recueil/02_03_10_resize.c.html
With the nearest algorithm, we fill each pixel of the scaled image using the nearest pixel from the source image. This leads to many possible artifacts.
With the linear algorithm, the goal is to look for each pixel of the scaled image where we are in the source image (this can be between 4 source pixels for example), and do a linear interpolation of the colors of the pixels around the position (which is a real number) in the original image. It's all about smoothing.
You also can look here for more explanation and another scaling algorithm : http://www.brockmann-consult.de/beam/doc/help/general/ResamplingMethods.html
Here is an bilinear interpolation code commented :
float sourceWidth=192.0f;
float sourceHeight=128.0f;
float scaledWidth=sourceWidth*1.5f;
float scaledHeight=sourceheight*1.5f;
// First we need to find a ratio between the source image and the scaled image
// We already know it's 1.5
float ratioX=scaledWidth/sourceWidth;
float ratioY=scaledHeight/sourceHeight;
// Then we need to loop through each scaled image pixel
for(int i=0;i<scaledWidth;i++)
{
for(int j=0;j<scaledHeight;j++)
{
// Time to get the real number position on the source image
float sourceX=(float)i/ratioX;
float sourceY=(float)j/ratioY;
// Then we find the four pixels around our position
int minX=floor(sourceX);
int minY=floor(sourceY);
int maxX=minX+1;
int maxY=minY+1;
// We need to check if the bottom-right pixel is out of the source image
if(maxX>=sourceWidth)
maxX--;
if(maxY>=sourceHeight)
maxY--;
// Now we get the distance between the top-left source pixel and
// The real number position
float dX=sourceX-(float)minX;
float dY=sourceY-(float)minY;
// And for each color component (R,G,B) we apply the formula
// You can find it in the second link I posted
// I assume I have both GetPixelComp and SetPixelComp functions
// And both images represented as source and scaled
for(char k=0;k<3;k++)
{
unsigned char component=(unsigned char)
(GetPixelComp(source,minX,minY,k)*(1-dX)*(1-dY)+ // Top-Left
GetPixelComp(source,maxX,minY,k)*dX*(1-dY)+ // Top-Right
GetPixelComp(source,minX,maxY,k)*(1-dX)*dY+ // Bottom-Left
GetPixelComp(source,maxX,maxY,k)*dX*dY); // Bottom-Right
SetPixelComp(scaled,i,j,k,component);
}
}
}
I hope it helps you understand the principle :)