241 lines
4.8 KiB
C++
241 lines
4.8 KiB
C++
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
typedef struct
|
|
{
|
|
int size;
|
|
int width;
|
|
int height;
|
|
short planes;
|
|
short bitcount;
|
|
int compression;
|
|
int sizeimage;
|
|
int xpelspermeter;
|
|
int ypelspermeter;
|
|
int clrused;
|
|
int clrimportant;
|
|
} DIB;
|
|
|
|
int DIBSize (void* dib) {return ((DIB*)dib)->size ;}
|
|
int DIBWidth (void* dib) {return ((DIB*)dib)->width ;}
|
|
int DIBHeight (void* dib) {return ((DIB*)dib)->height;}
|
|
|
|
int DIBPlanes (void* dib) {return DIBSize(dib) < 14 ? 1 : ((DIB*)dib)->planes ;}
|
|
int DIBBitCount (void* dib) {return DIBSize(dib) < 16 ? 24 : ((DIB*)dib)->bitcount ;}
|
|
int DIBCompression (void* dib) {return DIBSize(dib) < 20 ? 0 : ((DIB*)dib)->compression ;}
|
|
int DIBSizeImage (void* dib) {return DIBSize(dib) < 24 ? 0 : ((DIB*)dib)->sizeimage ;}
|
|
int DIBXPelsPerMeter(void* dib) {return DIBSize(dib) < 28 ? 0 : ((DIB*)dib)->xpelspermeter;}
|
|
int DIBYPelsPerMeter(void* dib) {return DIBSize(dib) < 32 ? 0 : ((DIB*)dib)->ypelspermeter;}
|
|
int DIBClrUsed (void* dib) {return DIBSize(dib) < 36 ? 0 : ((DIB*)dib)->clrused; }
|
|
int DIBClrImportant (void* dib) {return DIBSize(dib) < 40 ? 0 : ((DIB*)dib)->clrimportant; }
|
|
|
|
int
|
|
DIBNumberOfColors(void* dib)
|
|
{
|
|
return 1 << DIBBitCount(dib);
|
|
}
|
|
|
|
int
|
|
DIBPaletteSize(void* dib)
|
|
{
|
|
return DIBClrUsed(dib) ? DIBClrUsed(dib) : DIBNumberOfColors(dib) > 256 ? 0 : DIBNumberOfColors(dib);
|
|
}
|
|
|
|
void*
|
|
DIBColorTable(void* dib)
|
|
{
|
|
return &((char*)dib)[DIBSize(dib)];
|
|
}
|
|
|
|
void*
|
|
DIBPixels(void* dib)
|
|
{
|
|
return &((int*)DIBColorTable(dib))[DIBPaletteSize(dib)];
|
|
}
|
|
|
|
int
|
|
DIBWidthInBytes(void* dib)
|
|
{
|
|
return (DIBWidth(dib) * DIBBitCount(dib) + 7) >> 3;
|
|
}
|
|
|
|
int
|
|
DIBBytesPerRow(void* dib)
|
|
{
|
|
return (DIBWidthInBytes(dib) + 3) >> 2 << 2;
|
|
}
|
|
|
|
int
|
|
DIBPitch(void* dib)
|
|
{
|
|
return DIBBytesPerRow(dib) * DIBPlanes(dib);
|
|
}
|
|
|
|
void*
|
|
DIBPixelRow(void* dib, int i)
|
|
{
|
|
return &((char*)DIBPixels(dib))[DIBPitch(dib) * i];
|
|
}
|
|
|
|
char
|
|
DIBRed(void* dib, int i)
|
|
{
|
|
return ((char*)DIBColorTable(dib))[(i << 2) + 2];
|
|
}
|
|
|
|
char
|
|
DIBGreen(void* dib, int i)
|
|
{
|
|
return ((char*)DIBColorTable(dib))[(i << 2) + 1];
|
|
}
|
|
|
|
char
|
|
DIBBlue(void* dib, int i)
|
|
{
|
|
return ((char*)DIBColorTable(dib))[(i << 2) + 0];
|
|
}
|
|
|
|
int
|
|
DIBMemoryUsage(void* dib)
|
|
{
|
|
return DIBSize(dib) + DIBPaletteSize(dib) * 4 + DIBPitch(dib) * DIBHeight(dib);
|
|
}
|
|
|
|
void*
|
|
DIBCreate(int width, int height, int planes, int bitcount)
|
|
{
|
|
DIB* dib;
|
|
|
|
dib = (DIB*) calloc(1, sizeof(DIB));
|
|
|
|
dib->size = sizeof(DIB);
|
|
dib->width = width;
|
|
dib->height = height;
|
|
dib->planes = planes;
|
|
dib->bitcount = bitcount;
|
|
dib->clrused = DIBPaletteSize(dib);
|
|
|
|
dib = (DIB*) realloc(dib, DIBMemoryUsage(dib));
|
|
|
|
return dib;
|
|
}
|
|
|
|
void
|
|
DIBDelete(void* dib)
|
|
{
|
|
free(dib);
|
|
}
|
|
|
|
void*
|
|
DIBLoad(char* name)
|
|
{
|
|
FILE* fp;
|
|
void* dib = NULL;
|
|
|
|
if ((fp = fopen(name, "rb")) != NULL)
|
|
{
|
|
fseek(fp, 0, SEEK_END);
|
|
|
|
int size = ftell(fp) - 14;
|
|
|
|
if ((dib = malloc(size)) != NULL)
|
|
{
|
|
fseek(fp, 14, SEEK_SET);
|
|
|
|
fread(dib, size, 1, fp);
|
|
}
|
|
fclose(fp);
|
|
}
|
|
return dib;
|
|
}
|
|
|
|
void*
|
|
DIBSave(void* dib, char* name)
|
|
{
|
|
FILE* fp;
|
|
|
|
if ((fp = fopen(name, "wb")) != NULL)
|
|
{
|
|
/* TODO: Write out bitmap file header */
|
|
fwrite(dib, DIBMemoryUsage(dib), 1, fp);
|
|
|
|
fclose(fp);
|
|
}
|
|
return dib;
|
|
}
|
|
|
|
void*
|
|
DIBFlip(void* dib)
|
|
{
|
|
int height = DIBHeight(dib);
|
|
int pitch = DIBPitch(dib);
|
|
char* top = (char*) DIBPixelRow(dib, 0);
|
|
char* bot = (char*) DIBPixelRow(dib, height - 1);
|
|
char* buf = (char*) malloc(pitch);
|
|
|
|
if (buf)
|
|
{
|
|
|
|
for (height >>= 1; height--; top += pitch, bot -= pitch)
|
|
{
|
|
memcpy(buf, top, pitch);
|
|
memcpy(top, bot, pitch);
|
|
memcpy(bot, buf, pitch);
|
|
}
|
|
free(buf);
|
|
}
|
|
return dib;
|
|
}
|
|
|
|
typedef struct
|
|
{
|
|
short width;
|
|
short height;
|
|
short bitcount;
|
|
} Image;
|
|
|
|
int
|
|
ImageWidth(void* image)
|
|
{
|
|
return ((Image*)image)->width;
|
|
}
|
|
|
|
int
|
|
ImageHeight(void* image)
|
|
{
|
|
return ((Image*)image)->height;
|
|
}
|
|
|
|
int
|
|
ImageBitCount(void* image)
|
|
{
|
|
return ((Image*)image)->bitcount;
|
|
}
|
|
|
|
void*
|
|
ImageFromDIB(void* dib)
|
|
{
|
|
Image* image = &((Image*)DIBPixels(dib))[-1];
|
|
|
|
image->width = DIBPitch(dib);
|
|
image->height = DIBHeight(dib);
|
|
image->bitcount = DIBBitCount(dib);
|
|
|
|
return image;
|
|
}
|
|
|
|
long*
|
|
PaletteFromDIB(long* palette, void* dib)
|
|
{
|
|
for (int i = 0; i < DIBPaletteSize(dib); i++)
|
|
{
|
|
palette[i] =
|
|
(DIBRed (dib, i) >> 2 >> 0) |
|
|
(DIBGreen(dib, i) >> 2 << 8) |
|
|
(DIBBlue (dib, i) >> 2 << 16);
|
|
}
|
|
return palette;
|
|
}
|
|
|