⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bit2xes.c

📁 vga视频输出(vhdl)
💻 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 + -