Presenting you an implementation of the "shear and transpose" method of rotating a bitmap image. It works.. but it works slow, which is fully understandable. It is understandable due to the evident lack of optimization. Notwithstanding it doesn't interact with the VGA or any library for that matter.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* bmp offsets */
#define OFFSET_OF_ID (0x0)
#define OFFSET_OF_SIZE (0x2)
#define OFFSET_OF_PIXELS (0xA)
#define OFFSET_OF_NDIB (0xE)
#define OFFSET_OF_WIDTH (0x12)
#define OFFSET_OF_HEIGHT (0x16)
#define OFFSET_OF_BPP (0x1C)
#define OFFSET_OF_NRAW (0x22)
/* bmp is especially dedicated for windows. defining windows-specific types: */
typedef unsigned char byte, *buffer;
typedef unsigned short word;
typedef unsigned long dword;
typedef unsigned long long ddword;
typedef unsigned char pixel[3];
/* bitmapS[nBitmap][offset] */
buffer *bitmapS;
/* Helper function */
ddword bmp_find_xy (dword width, dword xp, dword yp);
buffer
bmp_rotate
(dword nBitmap, float angle)
{
const dword src_width = *( (dword*)&bitmapS[nBitmap][OFFSET_OF_WIDTH]);
const dword src_height = *( (dword*)&bitmapS[nBitmap][OFFSET_OF_HEIGHT]);
const dword src_nraw = *( (dword*)&bitmapS[nBitmap][OFFSET_OF_NRAW]);
const dword src_pixels = *( (dword*)&bitmapS[nBitmap][OFFSET_OF_PIXELS]);
buffer dest = malloc( src_pixels + src_nraw );
float midX, midY;
float deltaX, deltaY;
dword rotX, rotY;
dword i, j;
midX = src_width / 2.0f;
midY = src_height / 2.0f;
memcpy(dest, bitmapS[nBitmap], src_pixels);
for(i = 0; i < src_width; i++)
for(j = 0; j < src_height; j++)
{
deltaX = i - midX;
deltaY = j - midY;
rotX = (dword)(midX + deltaX * sin(angle) + deltaY * cos(angle));
rotY = (dword)(midY + deltaX * cos(angle) - deltaY * sin(angle));
if(rotX >= 0 && rotX < src_width && rotY >= 0 && rotY < src_height)
{
ddword dest_offset = bmp_find_xy(src_width, i, j);
ddword src_offset = bmp_find_xy(src_width, rotX, rotY);
deltaX = i + midX;
deltaY = j + midY;
memcpy(&dest[dest_offset], &bitmapS[nBitmap][src_offset], sizeof(pixel);
}
}
return dest;
}
/* Definition of helper function */
ddword
bmp_find_xy
(dword width, dword xp, dword yp)
{
dword w = width;
const dword channels = sizeof(pixel);
const dword bpp = 8;
const dword single = (channels * bpp) / 7;
const dword offset = sizeof(BMP) + sizeof(DIB);
dword rowsize = w * single;
dword pixAddress;
if (rowsize % 4 != 0) rowsize += 4 - (rowsize % 4);
pixAddress = offset + yp * rowsize + xp * single;
return pixAddress;
}