📄 bit2xes.c
字号:
//
// Bitmap to XESS XES File format converter
//
// compiled with Dev-C++
//
#include <stdio.h>
#include <assert.h>
#define BI_RGB 0 // No compression
#define BI_RLE8 1 // RLE8 compression (256 colors)
#define BI_RLE4 2 // RLE4 compression (16 colors)
#pragma pack(1)
typedef struct _BITMAPFILEHEADER { // Offset Size
short bfType; // 0 2
long bfSize; // 2 4
short bfReserved1; // 6 2
short bfReserved2; // 8 2
long bfOffBits; // 10 4
} BITMAPFILEHEADER; // Total size: 14
#pragma pack()
#pragma pack(1)
typedef struct _BITMAPINFOHEADER { // Offset Size
long biSize; // 0 4
long biWidth; // 4 4
long biHeight; // 8 4
short biPlanes; // 12 2
short biBitCount; // 14 2
long biCompression; // 16 4
long biSizeImage; // 20 4
long biXPelsPerMeter; // 24 4
long biYPelsPerMeter; // 28 4
long biClrUsed; // 32 4
long biClrImportant; // 36 4
} BITMAPINFOHEADER; // Total size: 40
#pragma pack()
#pragma pack(1)
typedef struct _RGBQUAD {
char rgbBlue;
char rgbGreen;
char rgbRed;
char rgbReserved;
} RGBQUAD;
#pragma pack()
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
RGBQUAD *bmcoltab;
long bmnumcolors;
char pal[768];
void SetColor(char num, char r, char g, char b)
{
pal[num*3+0] = r >> 2;
pal[num*3+1] = g >> 2;
pal[num*3+2] = b >> 2;
}
void BMPBufferFlip(long biWidth, long biHeight, char *buffer)
{
char byte;
long x, y;
for (y = 0; y < biHeight/2; y++)
for (x = 0; x < biWidth; x++) {
byte = buffer[y*biWidth+x];
buffer[y*biWidth+x] = buffer[(biHeight-y-1)*biWidth+x];
buffer[(biHeight-y-1)*biWidth+x] = byte;
}
}
char *LoadBMP(char *filename, long *biWidth, long *biHeight)
{
FILE *f;
char *buffer, byte;
char byte1, byte2;
char hinib, lonib;
char deltax, deltay;
long x, y;
long size, k, i;
f = fopen(filename,"rb");
assert(f != NULL);
fread(&bmfh, sizeof(BITMAPFILEHEADER), 1, f);
fread(&bmih, sizeof(BITMAPINFOHEADER), 1, f);
printf("\nType : %c%c",bmfh.bfType,bmfh.bfType>>8);
printf("\nSize : %d",bmfh.bfSize);
printf("\nRes1 : %d",bmfh.bfReserved1);
printf("\nRes2 : %d",bmfh.bfReserved2);
printf("\nOffBits: %d\n",bmfh.bfOffBits);
printf("\nSize : %d",bmih.biSize);
printf("\nWidth : %d",bmih.biWidth);
printf("\nHeight : %d",bmih.biHeight);
printf("\nPlanes : %d",bmih.biPlanes);
printf("\nBitCount : %d",bmih.biBitCount);
printf("\nCompression: %d",bmih.biCompression);
printf("\nSizeImage : %d",bmih.biSizeImage);
printf("\nXPels : %d",bmih.biXPelsPerMeter);
printf("\nYPels : %d",bmih.biYPelsPerMeter);
printf("\nClrUsed : %d",bmih.biClrUsed);
printf("\nClrImpor : %d",bmih.biClrImportant);
printf("\n");
bmnumcolors = (1 << bmih.biBitCount);
printf("\nNumber of colors: %d\n", bmnumcolors);
// Bitmap size
size = bmih.biWidth * bmih.biHeight;
// Load color table if biBitCount < 24
if (bmih.biBitCount != 24) {
bmcoltab = (RGBQUAD *)calloc(bmnumcolors, sizeof(RGBQUAD));
assert(bmcoltab != NULL);
fread(bmcoltab, bmnumcolors*sizeof(RGBQUAD), 1, f);
}
else
size *= 3;
for (k = 0; k < bmnumcolors; k++)
SetColor(k, bmcoltab[k].rgbRed, bmcoltab[k].rgbGreen, bmcoltab[k].rgbBlue);
// Allocate memory for picture
buffer = (char *)calloc(size, sizeof(char));
assert(buffer != NULL);
fseek(f, bmfh.bfOffBits, SEEK_SET);
switch (bmih.biCompression) {
// RGB
case BI_RGB:
switch (bmih.biBitCount) {
// 2 colors
case 1:
k = 0;
for (y = 0; y < bmih.biHeight; y++) {
for (x = 0; x < (bmih.biWidth >> 3); x++) {
fread(&byte, sizeof(char), 1, f);
for (i = 7; i >= 0; i--)
buffer[k++] = ((byte & (1 << i)) >> i);
}
// biWidth % 8 pixels still to draw
if ((bmih.biWidth % 8) > 0) {
fread(&byte, sizeof(char), 1, f);
size = 8 - (bmih.biWidth % 8);
for (i = 7; i >= size; i--)
buffer[k++] = ((byte & (1 << i)) >> i);
// We read one more byte
size = 1;
}
else
size = 0;
// Scan line must be zero-padded to end on a 32-bit boundary
size += (bmih.biWidth >> 3);
while (size % 4 != 0) {
fread(&byte, sizeof(char), 1, f);
size++;
}
}
break;
// 16 colors
case 4:
k = 0;
for (y = 0; y < bmih.biHeight; y++) {
for (x = 0; x < (bmih.biWidth >> 1); x++) {
fread(&byte, sizeof(char), 1, f);
buffer[k++] = ((byte >> 4) & 0x0F);
buffer[k++] = (byte & 0x0F);
}
// Last pixel of row if number of pixels in row is odd
if ((bmih.biWidth % 2) == 1) {
fread(&byte, sizeof(char), 1, f);
buffer[k++] = ((byte >> 4) & 0x0F);
// We read one more byte
size = 1;
}
else
size = 0;
// Scan line must be zero-padded to end on a 32-bit boundary
size += (bmih.biWidth >> 1);
while (size % 4 != 0) {
fread(&byte, sizeof(char), 1, f);
size++;
}
}
break;
// 256 colors
case 8:
k = 0;
for (y = 0; y < bmih.biHeight; y++) {
for (x = 0; x < bmih.biWidth; x++)
fread(&buffer[k++], sizeof(char), 1, f);
// Scan line must be zero-padded to end on a 32-bit boundary
size += bmih.biWidth;
while (size % 4 != 0) {
fread(&byte, sizeof(char), 1, f);
size++;
}
}
break;
// 16.7M colors
case 24:
assert(0);
break;
default:
assert(0);
}
break;
// RLE8
case BI_RLE8:
x = 0;
y = 0;
while (y*bmih.biWidth+x < size) {
fread(&byte1, sizeof(char), 1, f);
fread(&byte2, sizeof(char), 1, f);
// Absolute Mode
if (byte1 == 0 && byte2 >= 0x03 && byte2 <= 0xFF){
for (k = 0; k < byte2; k++) {
fread(&byte, sizeof(char), 1, f);
buffer[y*bmih.biWidth+x++] = byte;
}
// Each run must be aligned on a word boundary
if ((byte2 % 2) != 0)
fread(&byte, sizeof(char), 1, f);
}
// Encoded Mode
else {
// Indicate an escape
if (byte1 == 0) {
switch (byte2) {
// End of line
case 0:
x = 0;
y++;
break;
// End of bitmap
case 1:
break;
// Delta
case 2:
fread(&deltax, sizeof(char), 1, f);
fread(&deltay, sizeof(char), 1, f);
x += deltax;
y += deltay;
break;
default:
assert(0);
}
}
else {
for (k = 0; k < byte1; k++)
buffer[y*bmih.biWidth+x++] = byte2;
}
}
}
break;
// RLE4
case BI_RLE4:
x = 0;
y = 0;
while (y*bmih.biWidth+x < size) {
fread(&byte1, sizeof(char), 1, f);
fread(&byte2, sizeof(char), 1, f);
// Absolute Mode
if (byte1 == 0 && byte2 >= 0x03 && byte2 <= 0xFF) {
byte2 >>= 1;
for (k = 0; k < byte2; k++) {
fread(&byte, sizeof(char), 1, f);
hinib = ((byte >> 4) & 0x0F);
lonib = (byte & 0x0F);
buffer[y*bmih.biWidth+x++] = hinib;
buffer[y*bmih.biWidth+x++] = lonib;
}
// Each run must be aligned on a word boundary
if ((byte2 % 2) != 0)
fread(&byte, sizeof(char), 1, f);
}
// Encoded Mode
else {
// Indicate an escape
if (byte1 == 0) {
switch (byte2) {
// End of line
case 0:
x = 0;
y++;
break;
// End of bitmap
case 1:
break;
// Delta
case 2:
fread(&deltax, sizeof(char), 1, f);
fread(&deltay, sizeof(char), 1, f);
x += deltax;
y += deltay;
break;
default:
assert(0);
}
}
else {
hinib = ((byte2 >> 4) & 0x0F);
lonib = (byte2 & 0x0F);
byte2 = byte1 % 2;
byte1 >>= 1;
for (k = 0; k < byte1; k++) {
buffer[y*bmih.biWidth+x++] = hinib;
buffer[y*bmih.biWidth+x++] = lonib;
}
if (byte2 != 0)
buffer[y*bmih.biWidth+x++] = hinib;
}
}
}
break;
default: // Should not happen
assert(0);
}
fclose(f);
BMPBufferFlip(bmih.biWidth, bmih.biHeight, buffer);
*biWidth = bmih.biWidth;
*biHeight = bmih.biHeight;
return buffer;
}
main(int argc, char **argv)
{
FILE *fileOut;
long x, y, width, height;
char *p;
int numBits, numBytes;
int col, row, addr;
unsigned short aByte;
int i;
unsigned invertColors = 0;
char *filename;
printf("\n");
printf("Bitmap to XESS XES File Format Converter\n");
printf("by Doug Hodson at www.RetroMicro.com\n\n");
if (argc < 2) {
printf("Converts monochrome formatted bitmap .bmp formatted\n");
printf("files to XESS .xsa format memory hex files\n\n");
printf("bit2xes [-i] <image.bmp>\n\n");
printf(" -i Invert colors.\n\n");
printf("Output file is named image.xes\n\n");
exit(1);
}
// very clunky, but it works
if (!strcmp(argv[1],"-i"))
{
invertColors = 0;
filename = argv[2];
}
else
{
invertColors = 1;
filename = argv[1];
}
p = LoadBMP(filename, &width, &height);
numBits = width * height;
printf("Number of Bits: %d\n", numBits);
numBytes = numBits / 8;
printf("Number of Bytes: %d\n", numBytes);
// create dest file with addresses
if ( (fileOut = fopen("image.xes","w")) == NULL )
{
printf("Cannot create destination file.\n");
return 0;
}
printf("Writing file image.bmp\n");
addr = 0;
i = 0;
for( row=0; row<455; row++ )
{
fprintf(fileOut, "- 48 %4x ", addr);
addr += 72;
for( col=0; col<72; col++ )
{
// convert picture bits to bytes
aByte = 128 * p[i+0] +
64 * p[i+1] +
32 * p[i+2] +
16 * p[i+3] +
8 * p[i+4] +
4 * p[i+5] +
2 * p[i+6] +
1 * p[i+7];
if(invertColors==0)
aByte = (~aByte) & 0x00FF;
i += 8;
fprintf(fileOut, "%02X ", aByte);
}
fprintf(fileOut, "\n");
}
printf("Done\n");
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -