::: °­ÁÂ/¼Ò½º/¹®¼­ :::

°­ÁÂ/¼Ò½º/¹®¼­ ¼º°Ý¿¡ ¸ÂÁö ¾Ê´Â ±¤°í,ºñ¹æ,Áú¹®ÀÇ ±ÛÀº Áï½Ã »èÁ¦Çϸç
³»¿ëÀ» º¹»çÇÏ¿© »ç¿ëÇÒ °æ¿ì ¹Ýµå½Ã ÀÌ°÷(http://www.howto.pe.kr)À» Ãâó·Î ¸í½ÃÇÏ¿© ÁÖ¼¼¿ä


Category

  ±è¿µ´ë(2003-03-18 22:36:40, Hit : 8628, Vote : 1506
 [¼Ò½º] Windows RLE(BMP) Encoder

// Á¦  ¸ñ: Windows RLE(BMP) Encoder
// ÀÛ¼ºÀÚ: ±è¿µ´ë ( http://www.howto.pe.kr )

#include <stdio.h>
#include <fcntl.h>
#include <math.h>

#define BI_RGB       0
#define BI_RLE8      1
#define BI_RLE4      2
#define BI_bitfield  3

typedef struct tag_BITMAP_FILE_HEADER {
  unsigned char bfType[2]; // ASCII "BM"
  unsigned char bfSize[4]; // Àüü ÆÄÀÏÅ©±â
  unsigned char bfReserved[4];
  unsigned char bfOffBits[4]; // ½ÇÁ¦ raster pixel data°¡ ½ÃÀÛÇÏ´Â À§Ä¡
} BITMAP_FILE_HEADER;
  
typedef struct tag_BITMAP_INFO_HEADER {
  unsigned char biSize[4]; // size of BITMAP_INFO_HEADER(40 bytes)
  unsigned char biWidth[4];
  unsigned char biHeight[4];
  unsigned char biPlanes[2];   // Ç×»ó 1
  unsigned char biBitCount[2]; // bits per pixel 1=mono,4=16,8=256,16=65536 High,24=2^24 True color
  unsigned char biCompression[4];   // 0=no, 1=8bitRLE, 2=4bitRLE
  unsigned char biSizeImage[4];     // ½ÇÁ¦ pixel dataÀÇ Å©±â=bfSize-bfOffBits
  unsigned char biXPelsPerMeter[4]; // ¼öÆò resolution
  unsigned char biYPelsPerMeter[4]; // ¼öÁ÷ resolution
  unsigned char biClrUsed[4];       // Color Table(Palette)ÀÇ entry °¹¼ö(0 À̸é all used:2^BitCount °³)
  unsigned char biClrImportant[4];  // biClrUsed¿Í °°´Ù
} BITMAP_INFO_HEADER;

typedef struct tag_COLOR_TABLE {
  unsigned char bBlue; // Color Table(palette) Àº RGB°¡ ¾Æ´Ñ BGR formatÀ¸·Î ÀúÀåµÇ¾î ÀÖÀ½
  unsigned char bGreen;
  unsigned char bRed;
  unsigned char bReserved; // padding
} COLOR_TABLE;

void pack_bytes(unsigned char dst[], long src, int bytes) {
  int i;
  for (i = 0; i < bytes; i++)
    dst[i] = (src >> (8*i)) & 255;
}  

long unpack_bytes(unsigned char src[], int bytes) {
  int i;
  long dst = 0;
  
  for (i=bytes-1; i >= 0; i--)
    dst += src[i] << (8*i);
    
  return dst;  
}  
    
void print_header(BITMAP_FILE_HEADER *bmp_file, BITMAP_INFO_HEADER *bmp_info, COLOR_TABLE *color_table, int cu) {
  int i;
        
  printf("Bitmap File Header(14 bytes)n");
  printf("  bfType(2 bytes): %c%c(%.2X%.2X)n",
        bmp_file->bfType[0], bmp_file->bfType[1],
        bmp_file->bfType[0], bmp_file->bfType[1]);
  printf("  bfSize(4 bytes): %u(%.8X)n",
        unpack_bytes(bmp_file->bfSize, sizeof(bmp_file->bfSize)),
        unpack_bytes(bmp_file->bfSize, sizeof(bmp_file->bfSize)));
  printf("  bfReserved(4 bytes): %u(%.8X)n",
        unpack_bytes(bmp_file->bfReserved, sizeof(bmp_file->bfReserved)),
        unpack_bytes(bmp_file->bfReserved, sizeof(bmp_file->bfReserved)));
  printf("  bfOffBits(4 bytes): %u(%.8X)n",
        unpack_bytes(bmp_file->bfOffBits, sizeof(bmp_file->bfOffBits)),
        unpack_bytes(bmp_file->bfOffBits, sizeof(bmp_file->bfOffBits)));
  
  printf("Bitmap Info Header(40 bytes)n");
  printf("  biSize(4 bytes): %u(%.8X)n",
        unpack_bytes(bmp_info->biSize, sizeof(bmp_info->biSize)),
        unpack_bytes(bmp_info->biSize, sizeof(bmp_info->biSize)));
  printf("  biWidth(4 bytes): %u(%.8X)n",
        unpack_bytes(bmp_info->biWidth, sizeof(bmp_info->biWidth)),
        unpack_bytes(bmp_info->biWidth, sizeof(bmp_info->biWidth)));
  printf("  biHeight(4 bytes): %u(%.8X)n",
        unpack_bytes(bmp_info->biHeight, sizeof(bmp_info->biHeight)),
        unpack_bytes(bmp_info->biHeight, sizeof(bmp_info->biHeight)));
  printf("  biPlanes(2 bytes): %u(%.4X)n",
        unpack_bytes(bmp_info->biPlanes, sizeof(bmp_info->biPlanes)),
        unpack_bytes(bmp_info->biPlanes, sizeof(bmp_info->biPlanes)));
  printf("  biBitCount(2 bytes): %u(%.4X)n",
        unpack_bytes(bmp_info->biBitCount, sizeof(bmp_info->biBitCount)),
        unpack_bytes(bmp_info->biBitCount, sizeof(bmp_info->biBitCount)));
  printf("  biCompression(4 bytes): %u(%.8X)n",
        unpack_bytes(bmp_info->biCompression, sizeof(bmp_info->biCompression)),
        unpack_bytes(bmp_info->biCompression, sizeof(bmp_info->biCompression)));
  printf("  biSizeImage(4 bytes): %u(%.8X)n",
        unpack_bytes(bmp_info->biSizeImage, sizeof(bmp_info->biSizeImage)),
        unpack_bytes(bmp_info->biSizeImage, sizeof(bmp_info->biSizeImage)));
  printf("  biXPelsPerMeter(4 bytes): %u(%.8X)n",
        unpack_bytes(bmp_info->biXPelsPerMeter, sizeof(bmp_info->biXPelsPerMeter)),
        unpack_bytes(bmp_info->biXPelsPerMeter, sizeof(bmp_info->biXPelsPerMeter)));
  printf("  biYPelsPerMeter(4 bytes): %u(%.8X)n",
        unpack_bytes(bmp_info->biYPelsPerMeter, sizeof(bmp_info->biYPelsPerMeter)),
        unpack_bytes(bmp_info->biYPelsPerMeter, sizeof(bmp_info->biYPelsPerMeter)));
  printf("  biClrUsed(4 bytes): %u(%.8X)n",
        unpack_bytes(bmp_info->biClrUsed, sizeof(bmp_info->biClrUsed)),
        unpack_bytes(bmp_info->biClrUsed, sizeof(bmp_info->biClrUsed)));
  printf("  biClrImportant(4 bytes): %u(%.8X)n",
        unpack_bytes(bmp_info->biClrImportant, sizeof(bmp_info->biClrImportant)),
        unpack_bytes(bmp_info->biClrImportant, sizeof(bmp_info->biClrImportant)));

  if (cu > 0) {
    printf("ColorTable(4 * %d = %d bytes)n", cu, cu*4);
    for (i=0; i < cu; i++) {
      printf("%3d: ", i);
      printf("R(%.2X) G(%.2X) B(%.2X) Padding(%.2X)n",
            color_table[i].bRed,
            color_table[i].bGreen,
            color_table[i].bBlue,
            color_table[i].bReserved);
    }    
  }  
}
    
main(int argc, char **argv) {
  int ifd, ofd;
  int bfSize, biHeight, biWidth, biBitCount, biClrUsed, biSizeImage;
  int retbiSizeImage, retbiCompression;
  int i, j, k, bnd, startWidth, endWidth;
  BITMAP_FILE_HEADER bmp_file;
  BITMAP_INFO_HEADER bmp_info;
  COLOR_TABLE *color_table;
  unsigned char *src_data, *tar_data;

  if (argc != 3) {
    fprintf(stderr, "»ç¿ë¹ý: %s sourceÆÄÀϸí targetÆÄÀϸín", argv[0]);
    exit(1);
  }  
  
  if ((ifd = open(argv[1], O_RDONLY)) < 0) {
    fprintf(stderr, "%s ÆÄÀÏÀ» ÀÐÀ» ¼ö ¾ø½À´Ï´Ùn", argv[1]);
    exit(1);
  }  

  // sourceÆÄÀÏ¿¡¼­ BITMAP_FILE_HEADER ¸¦ Àд´Ù
  if (read(ifd, &bmp_file, sizeof(BITMAP_FILE_HEADER)) < sizeof(BITMAP_FILE_HEADER))
    exit(1);
  // sourceÆÄÀÏ¿¡¼­ BITMAP_INFO_HEADER ¸¦ Àд´Ù
  if (read(ifd, &bmp_info, sizeof(BITMAP_INFO_HEADER)) < sizeof(BITMAP_INFO_HEADER))
    exit(1);

  // BMP ÆÄÀÏÀÇ Çì´õ´Â "BM" À¸·Î ½ÃÀÛÇÑ´Ù
  if (bmp_file.bfType[0] != 'B' ||
      bmp_file.bfType[1] != 'M') {
    fprintf(stderr, "%s ÆÄÀÏÀº BMP ÆÄÀÏÀÌ ¾Æ´Õ´Ï´Ùn", argv[1]);
    close(ifd);
    exit(1);
  }
  
  // ÀÌ¹Ì ¾ÐÃàµÇ¾î ÀÖ´Ù¸é ÁøÇàÀ» ÁßÁöÇÑ´Ù
  if ((i=unpack_bytes(bmp_info.biCompression, sizeof(bmp_info.biCompression))) > BI_RGB) {
    switch (i) {
      case BI_RLE8:
        fprintf(stderr, "%s ÆÄÀÏÀº ÀÌ¹Ì RLE-8 ·Î ¾ÐÃàµÇ¾î ÀÖ½À´Ï´Ùn", argv[1]);
        break;
      case BI_RLE4:
        fprintf(stderr, "%s ÆÄÀÏÀº ÀÌ¹Ì RLE-4 ·Î ¾ÐÃàµÇ¾î ÀÖ½À´Ï´Ùn", argv[1]);
        break;
      case BI_bitfield:
        fprintf(stderr, "%s ÆÄÀÏÀº ÀÌ¹Ì bit-field ·Î ¾ÐÃàµÇ¾î ÀÖ½À´Ï´Ùn", argv[1]);
        break;
      default:
        fprintf(stderr, "%s ÆÄÀÏÀº ÀÌ¹Ì ¾Ë ¼ö ¾ø´Â formatÀ¸·Î ¾ÐÃàµÇ¾î ÀÖ½À´Ï´Ùn", argv[1]);
    }
    close(ifd);
    exit(1);
  }

  if ((ofd = creat(argv[2], 0644)) < 0) {
    fprintf(stderr, "%s ÆÄÀÏÀ» ¸¸µé ¼ö ¾ø½À´Ï´Ùn", argv[2]);
    exit(1);
  }

  bfSize     = unpack_bytes(bmp_file.bfSize,     sizeof(bmp_file.bfSize));
  biWidth    = unpack_bytes(bmp_info.biWidth,    sizeof(bmp_info.biWidth));
  biHeight   = unpack_bytes(bmp_info.biHeight,   sizeof(bmp_info.biHeight));
  biBitCount = unpack_bytes(bmp_info.biBitCount, sizeof(bmp_info.biBitCount));
  biClrUsed  = unpack_bytes(bmp_info.biClrUsed,  sizeof(bmp_info.biClrUsed));
      
  // sourceÆÄÀÏ¿¡¼­ Color Table(Palette) À» Àд´Ù
  color_table = NULL;
  if (biBitCount > 0 && biBitCount <= 8) {
    // Color Table ÀÇ entry °¹¼ö´Â 2^BitCount °³ ÀÌÁö¸¸ À̹ÌÁö¿¡¼­ ½ÇÁ¦ »ç¿ëµÈ color ¸¸ ÀúÀåÇϱâ À§ÇØ
    // biClrUsed °³ÀÇ entry¸¸ Color Table¿¡ »ç¿ëÇÑ´Ù
    // ÇÏÁö¸¸ biClrUsed == 0 À̸é 2^BitCountÀ¸·Î ó¸®ÇؾßÇÑ´Ù
    if (biClrUsed == 0)
      biClrUsed = (int)pow(2, biBitCount); // 2 << (biBitCount-1)
    color_table = (COLOR_TABLE *)malloc(biClrUsed * sizeof(COLOR_TABLE));
    for (i=0; i < biClrUsed; i++)
      if (read(ifd, &color_table[i], sizeof(COLOR_TABLE)) < sizeof(COLOR_TABLE))
        exit(0);
  }  

  // biSizeImage°¡ 0ÀÏ ¼ö ÀÖÀ¸¹Ç·Î biSizeImage°¡¸¦ Á÷Á¢ ±¸ÇÑ´Ù
  biSizeImage = bfSize - (14+40+(biClrUsed*4));

  // source/target Raster Data ¸¦ ÀúÀåÇÒ ¹öÆÛ
  src_data = (char *)malloc(biSizeImage);
  tar_data = (char *)malloc(biSizeImage * 2);

  // sourceÆÄÀÏ¿¡¼­ Raster Data ¸¦ Àд´Ù
  if (read(ifd, src_data, biSizeImage) < biSizeImage)
    exit(1);

  // print_header(&bmp_file, &bmp_info, color_table, biClrUsed);

  // target Raster DataÀÇ Å©±â´Â °è»êÇϸ鼭 Áõ°¡µÊ
  retbiSizeImage = 0;

  if (biBitCount == 1) { // 8 bit RLE encoding ÇÑ´Ù
    retbiCompression = BI_RLE8;

    for (i=0; i < biHeight; i++) {
      if (biWidth%8 == 0) {
        startWidth = i*(biWidth/8); // °Ë»çÇÒ rowÀÇ ½ÃÀÛ data À§Ä¡
        // 4 bytes bound °¡ raster data ¿¡ ÀÖÀ¸¹Ç·Î ½ÇÁ¦ rowÀÇ dataÀÇ À§Ä¡¸¦ º¸Á¤ ÇÑ´Ù
        if ((biWidth/8) % 4 != 0)
          startWidth  += (i*(4-(biWidth/8)%4)); // °Ë»çÇÒ rowÀÇ ½ÃÀÛ index À§Ä¡+padding bytes
        endWidth = startWidth + (biWidth/8);
      } else {
        startWidth = i*(biWidth/8+1); // °Ë»çÇÒ rowÀÇ ½ÃÀÛ data À§Ä¡
        // 4 bytes bound °¡ raster data ¿¡ ÀÖÀ¸¹Ç·Î ½ÇÁ¦ rowÀÇ dataÀÇ À§Ä¡¸¦ º¸Á¤ ÇÑ´Ù
        if ((biWidth/8+1) % 4 != 0)
          startWidth  += i*(4-(biWidth/8+1)%4); // °Ë»çÇÒ rowÀÇ ½ÃÀÛ index À§Ä¡+padding bytes
        endWidth = startWidth + (biWidth/8+1); // nibbleÀ» byte·Î ȯ»êÇÑ rowÀÇ ³¡ À§Ä¡(¸¶Áö¸· byteÀÇ nibbleÀº °è»ê¾ÈÇÔ)
      }  
  
      j = startWidth;          
      while (1) {
        // °°Àº ¼ýÀÚ°¡ ¹Ýº¹µÇ´Â length ¸¦ ã´Â´Ù
        // example: 47 53 1E 0A 0A 0A 0A 05 05 3D 4C 01 01 || 01 B2 ...
        k = j;
        while ( (src_data[k] == src_data[k+1]) && ((k+1) < endWidth) && // 8bit°¡ 2°³ ÀÌ»ó ¹Ýº¹
                ((unsigned int)(k-j+1) <= 254) )
          k++;
        if ((k-j) > 0) {
          tar_data[retbiSizeImage] = k-j+1; // Run Length
          retbiSizeImage++;
          tar_data[retbiSizeImage] = src_data[j]; // Raster Pixel index
          retbiSizeImage++;
          j = k+1; // ´ÙÀ½ °Ë»çÇÒ À§Ä¡
          
          if (tar_data[retbiSizeImage-2] >= 255)
            continue;
        }
        if (j >= endWidth) // ÇÑ ÇàÀÇ °è»êÀÌ ³¡³²
          break;
  
        // °°Àº ¼ýÀÚ°¡ ¹Ýº¹µÇÁö ¾Ê´Â length ¸¦ ã´Â´Ù
        k = j;
        while ( (src_data[k] != src_data[k+1]) && (src_data[k+1] != src_data[k+2]) &&
                ((k+2) < endWidth) &&
                ((unsigned int)(k-j+1) <= 253) )
          k += 2;
        if ((k-j) > 0) { // example: 47 53 1E 0A 0A
          tar_data[retbiSizeImage] = 0; // 0 = absolute mode
          retbiSizeImage++;
          tar_data[retbiSizeImage] = k-j+1; // directly drawn >= 3
          retbiSizeImage++;
          for (bnd=0; j <= k; j++, bnd++) {
            tar_data[retbiSizeImage] = src_data[j]; // Raster Pixel index
            retbiSizeImage++;  
          }
          if (bnd%2 == 1) { // Ȧ¼ö°³¿´´Ù¸é 16 bit boundary ½ÃŲ´Ù(2 byte ¾¿ ¦À» ÀÌ·ç¾î¾ß ÇÑ´Ù)
            tar_data[retbiSizeImage] = 0;
            retbiSizeImage++;
          }
        } else { // ¾Æ¹«°Íµµ °è»êµÇÁö ¾ÊÀ½
          if (endWidth - j <= 2) { // °è»êÇÒ°ÍÀÌ 2°³ ÀÌÇÏ·Î ³²À¸¸é ±×³É Ãâ·Â
            for (; j < endWidth; j++) {
              tar_data[retbiSizeImage] = 1; // Run Length
              retbiSizeImage++;
              tar_data[retbiSizeImage] = src_data[j]; // Raster Pixel index
              retbiSizeImage++;
            }  
          } else { // example: 1E 0A 0A ...
            tar_data[retbiSizeImage] = 1; // Run Length
            retbiSizeImage++;
            tar_data[retbiSizeImage] = src_data[j]; // Raster Pixel index
            retbiSizeImage++;
            j++; // ´ÙÀ½ °Ë»çÇÒ À§Ä¡
          }  
        }
        if (j >= endWidth) // ÇÑ ÇàÀÇ °è»êÀÌ ³¡³²
          break;
      }      
      tar_data[retbiSizeImage] = 0; // 0 = absolute mode
      retbiSizeImage++;
      tar_data[retbiSizeImage] = 0; // escape value: EOL(end of line)
      retbiSizeImage++;
    }    
    tar_data[retbiSizeImage] = 0; // 0 = absolute mode
    retbiSizeImage++;
    tar_data[retbiSizeImage] = 1; // escape value: EOB(end of bitmap)
    retbiSizeImage++;
/*
    retbiCompression = BI_RLE4;

    for (i=0; i < biHeight; i++) {
      if (biWidth%8 == 0) {
        startWidth = i*(biWidth/8); // °Ë»çÇÒ rowÀÇ ½ÃÀÛ data À§Ä¡
        // 4 bytes bound °¡ raster data ¿¡ ÀÖÀ¸¹Ç·Î ½ÇÁ¦ rowÀÇ dataÀÇ À§Ä¡¸¦ º¸Á¤ ÇÑ´Ù
        if ((biWidth/8) % 4 != 0)
          startWidth  += (i*(4-(biWidth/8)%4)); // °Ë»çÇÒ rowÀÇ ½ÃÀÛ index À§Ä¡+padding bytes
        endWidth = startWidth + (biWidth/8);
      } else {
        startWidth = i*(biWidth/8+1); // °Ë»çÇÒ rowÀÇ ½ÃÀÛ data À§Ä¡
        // 4 bytes bound °¡ raster data ¿¡ ÀÖÀ¸¹Ç·Î ½ÇÁ¦ rowÀÇ dataÀÇ À§Ä¡¸¦ º¸Á¤ ÇÑ´Ù
        if ((biWidth/8+1) % 4 != 0)
          startWidth  += i*(4-(biWidth/8+1)%4); // °Ë»çÇÒ rowÀÇ ½ÃÀÛ index À§Ä¡+padding bytes
        endWidth = startWidth + (biWidth/8+1); // nibbleÀ» byte·Î ȯ»êÇÑ rowÀÇ ³¡ À§Ä¡(¸¶Áö¸· byteÀÇ nibbleÀº °è»ê¾ÈÇÔ)
      }  
  
      j = startWidth;          
      while (1) {
        // °°Àº ¼ýÀÚ°¡ ¹Ýº¹µÇ´Â length ¸¦ ã´Â´Ù
        // ¿ø·¡´Â nibble´ÜÀ§·Î °è»êµÇ¾î¾ß Çϳª byte ´ÜÀ§·Î °è»êÇÔ
        // example: 47 53 1E 0A 0A 0A 0A 05 05 3D 4C 01 01 || 01 B2 ...
        k = j;
        while ( (src_data[k] == src_data[k+1]) && ((k+1) < endWidth) && // 8bit°¡ 2°³ ÀÌ»ó ¹Ýº¹
                ((unsigned int)(2*(k-j+1)) <= 252) )
          k++;
        if ((k-j) > 0) {
          tar_data[retbiSizeImage] = 2*(k-j+1); // Run Length
          retbiSizeImage++;
          tar_data[retbiSizeImage] = src_data[j]; // Raster Pixel index
          retbiSizeImage++;
          j = k+1; // ´ÙÀ½ °Ë»çÇÒ À§Ä¡
          
          if (tar_data[retbiSizeImage-2] >= 254)
            continue;
        }
        if (j >= endWidth) // ÇÑ ÇàÀÇ °è»êÀÌ ³¡³²
          break;
  
        // °°Àº ¼ýÀÚ°¡ ¹Ýº¹µÇÁö ¾Ê´Â length ¸¦ ã´Â´Ù
        k = j;
        while ( (src_data[k] != src_data[k+1]) && ((k+1) < endWidth) &&
                ((unsigned int)(2*(k-j+1)) <= 252) )
          k++;
        if ((k-j) > 0) { // example: 47 53 1E 0A 0A
          tar_data[retbiSizeImage] = 0; // 0 = absolute mode
          retbiSizeImage++;
          tar_data[retbiSizeImage] = 2*(k-j+1); // directly drawn >= 4
          retbiSizeImage++;
          for (bnd=0; j <= k; j++, bnd++) {
            tar_data[retbiSizeImage] = src_data[j]; // Raster Pixel index
            retbiSizeImage++;  
          }
          if (bnd%2 == 1) { // Ȧ¼ö°³¿´´Ù¸é 16 bit boundary ½ÃŲ´Ù(2 byte ¾¿ ¦À» ÀÌ·ç¾î¾ß ÇÑ´Ù)
            tar_data[retbiSizeImage] = 0;
            retbiSizeImage++;
          }
        } else { // ¾Æ¹«°Íµµ °è»êµÇÁö ¾ÊÀ½
          if (endWidth - j <= 1) { // °è»êÇÒ°ÍÀÌ 1°³ ÀÌÇÏ·Î ³²À¸¸é ±×³É Ãâ·Â
            for (; j < endWidth; j++) {
              tar_data[retbiSizeImage] = (biWidth%8>4)?2:1; // Run Length(Ȧ¼ö widthÀÇ ¸¶Áö¸· byteÀÇ nibbleÀº 1)
              retbiSizeImage++;
              tar_data[retbiSizeImage] = src_data[j]; // Raster Pixel index
              retbiSizeImage++;
            }  
          }  
        }
        if (j >= endWidth) // ÇÑ ÇàÀÇ °è»êÀÌ ³¡³²
          break;
      }      
      tar_data[retbiSizeImage] = 0; // 0 = absolute mode
      retbiSizeImage++;
      tar_data[retbiSizeImage] = 0; // escape value: EOL(end of line)
      retbiSizeImage++;
    }    
    tar_data[retbiSizeImage] = 0; // 0 = absolute mode
    retbiSizeImage++;
    tar_data[retbiSizeImage] = 1; // escape value: EOB(end of bitmap)
    retbiSizeImage++;
*/    
  }

  else if (biBitCount == 4) { // 4 bit RLE encoding ÇÑ´Ù(ÀüºÎ nibbleÀ» byte·Î ȯ»êÇÏ¿© °è»êµÊ)
    retbiCompression = BI_RLE4;
  
    for (i=0; i < biHeight; i++) {
      if (biWidth%2 == 0) {
        startWidth  = i*(biWidth/2); // °Ë»çÇÒ rowÀÇ ½ÃÀÛ data À§Ä¡
        // 4 bytes bound °¡ raster data ¿¡ ÀÖÀ¸¹Ç·Î ½ÇÁ¦ rowÀÇ dataÀÇ À§Ä¡¸¦ º¸Á¤ ÇÑ´Ù
        if ((biWidth/2) % 4 != 0)
          startWidth  += (i*(4-(biWidth/2)%4)); // °Ë»çÇÒ rowÀÇ ½ÃÀÛ index À§Ä¡+padding bytes
        endWidth = startWidth + (biWidth/2);
      } else {
        startWidth  = i*(biWidth/2+1); // °Ë»çÇÒ rowÀÇ ½ÃÀÛ data À§Ä¡
        // 4 bytes bound °¡ raster data ¿¡ ÀÖÀ¸¹Ç·Î ½ÇÁ¦ rowÀÇ dataÀÇ À§Ä¡¸¦ º¸Á¤ ÇÑ´Ù
        if ((biWidth/2+1) % 4 != 0)
          startWidth  += i*(4-(biWidth/2+1)%4); // °Ë»çÇÒ rowÀÇ ½ÃÀÛ index À§Ä¡+padding bytes
        endWidth = startWidth + (biWidth/2+1); // nibbleÀ» byte·Î ȯ»êÇÑ rowÀÇ ³¡ À§Ä¡(¸¶Áö¸· byteÀÇ nibbleÀº °è»ê¾ÈÇÔ)
      }  
  
      j = startWidth;          
      while (1) {
        // °°Àº ¼ýÀÚ°¡ ¹Ýº¹µÇ´Â length ¸¦ ã´Â´Ù
        // ¿ø·¡´Â nibble´ÜÀ§·Î °è»êµÇ¾î¾ß Çϳª byte ´ÜÀ§·Î °è»êÇÔ
        // example: 47 53 1E 0A 0A 0A 0A 05 05 3D 4C 01 01 || 01 B2 ...
        k = j;
        while ( (src_data[k] == src_data[k+1]) && ((k+1) < endWidth) && // 8bit°¡ 2°³ ÀÌ»ó ¹Ýº¹
                ((unsigned int)(2*(k-j+1)) <= 252) )
          k++;
        if ((k-j) > 0) {
          tar_data[retbiSizeImage] = 2*(k-j+1); // Run Length
          retbiSizeImage++;
          tar_data[retbiSizeImage] = src_data[j]; // Raster Pixel index
          retbiSizeImage++;
          j = k+1; // ´ÙÀ½ °Ë»çÇÒ À§Ä¡
          
          if (tar_data[retbiSizeImage-2] >= 254)
            continue;
        }
        if (j >= endWidth) // ÇÑ ÇàÀÇ °è»êÀÌ ³¡³²
          break;
  
        // °°Àº ¼ýÀÚ°¡ ¹Ýº¹µÇÁö ¾Ê´Â length ¸¦ ã´Â´Ù
        k = j;
        while ( (src_data[k] != src_data[k+1]) && ((k+1) < endWidth) &&
                ((unsigned int)(2*(k-j+1)) <= 252) )
          k++;
        if ((k-j) > 0) { // example: 47 53 1E 0A 0A
          tar_data[retbiSizeImage] = 0; // 0 = absolute mode
          retbiSizeImage++;
          tar_data[retbiSizeImage] = 2*(k-j+1); // directly drawn >= 4
          retbiSizeImage++;
          for (bnd=0; j <= k; j++, bnd++) {
            tar_data[retbiSizeImage] = src_data[j]; // Raster Pixel index
            retbiSizeImage++;  
          }
          if (bnd%2 == 1) { // Ȧ¼ö°³¿´´Ù¸é 16 bit boundary ½ÃŲ´Ù(2 byte ¾¿ ¦À» ÀÌ·ç¾î¾ß ÇÑ´Ù)
            tar_data[retbiSizeImage] = 0;
            retbiSizeImage++;
          }
        } else { // ¾Æ¹«°Íµµ °è»êµÇÁö ¾ÊÀ½
          if (endWidth - j <= 1) { // °è»êÇÒ°ÍÀÌ 1°³ ÀÌÇÏ·Î ³²À¸¸é ±×³É Ãâ·Â
            for (; j < endWidth; j++) {
              tar_data[retbiSizeImage] = (biWidth%2)?1:2; // Run Length(Ȧ¼ö widthÀÇ ¸¶Áö¸· byteÀÇ nibbleÀº 1)
              retbiSizeImage++;
              tar_data[retbiSizeImage] = src_data[j]; // Raster Pixel index
              retbiSizeImage++;
            }  
          }  
        }
        if (j >= endWidth) // ÇÑ ÇàÀÇ °è»êÀÌ ³¡³²
          break;
      }      
      tar_data[retbiSizeImage] = 0; // 0 = absolute mode
      retbiSizeImage++;
      tar_data[retbiSizeImage] = 0; // escape value: EOL(end of line)
      retbiSizeImage++;
    }    
    tar_data[retbiSizeImage] = 0; // 0 = absolute mode
    retbiSizeImage++;
    tar_data[retbiSizeImage] = 1; // escape value: EOB(end of bitmap)
    retbiSizeImage++;
  }
  
  else if (biBitCount == 8) { // 8 bit RLE encoding ÇÑ´Ù
    retbiCompression = BI_RLE8;

    for (i=0; i < biHeight; i++) {
      startWidth  = i*biWidth; // °Ë»çÇÒ rowÀÇ ½ÃÀÛ data À§Ä¡
      // 4 bytes bound °¡ raster data ¿¡ ÀÖÀ¸¹Ç·Î ½ÇÁ¦ rowÀÇ dataÀÇ À§Ä¡¸¦ º¸Á¤ ÇÑ´Ù
      if (biWidth % 4 != 0)
        startWidth  += i*(4-biWidth%4); // °Ë»çÇÒ rowÀÇ ½ÃÀÛ index À§Ä¡+padding bytes
      endWidth = startWidth + biWidth;
  
      j = startWidth;          
      while (1) {
        // °°Àº ¼ýÀÚ°¡ ¹Ýº¹µÇ´Â length ¸¦ ã´Â´Ù
        // example: 47 53 1E 0A 0A 0A 0A 05 05 3D 4C 01 01 || 01 B2 ...
        k = j;
        while ( (src_data[k] == src_data[k+1]) && ((k+1) < endWidth) && // 8bit°¡ 2°³ ÀÌ»ó ¹Ýº¹
                ((unsigned int)(k-j+1) <= 254) )
          k++;
        if ((k-j) > 0) {
          tar_data[retbiSizeImage] = k-j+1; // Run Length
          retbiSizeImage++;
          tar_data[retbiSizeImage] = src_data[j]; // Raster Pixel index
          retbiSizeImage++;
          j = k+1; // ´ÙÀ½ °Ë»çÇÒ À§Ä¡
          
          if (tar_data[retbiSizeImage-2] >= 255)
            continue;
        }
        if (j >= endWidth) // ÇÑ ÇàÀÇ °è»êÀÌ ³¡³²
          break;
  
        // °°Àº ¼ýÀÚ°¡ ¹Ýº¹µÇÁö ¾Ê´Â length ¸¦ ã´Â´Ù
        k = j;
        while ( (src_data[k] != src_data[k+1]) && (src_data[k+1] != src_data[k+2]) &&
                ((k+2) < endWidth) &&
                ((unsigned int)(k-j+1) <= 253) )
          k += 2;
        if ((k-j) > 0) { // example: 47 53 1E 0A 0A
          tar_data[retbiSizeImage] = 0; // 0 = absolute mode
          retbiSizeImage++;
          tar_data[retbiSizeImage] = k-j+1; // directly drawn >= 3
          retbiSizeImage++;
          for (bnd=0; j <= k; j++, bnd++) {
            tar_data[retbiSizeImage] = src_data[j]; // Raster Pixel index
            retbiSizeImage++;  
          }
          if (bnd%2 == 1) { // Ȧ¼ö°³¿´´Ù¸é 16 bit boundary ½ÃŲ´Ù(2 byte ¾¿ ¦À» ÀÌ·ç¾î¾ß ÇÑ´Ù)
            tar_data[retbiSizeImage] = 0;
            retbiSizeImage++;
          }
        } else { // ¾Æ¹«°Íµµ °è»êµÇÁö ¾ÊÀ½
          if (endWidth - j <= 2) { // °è»êÇÒ°ÍÀÌ 2°³ ÀÌÇÏ·Î ³²À¸¸é ±×³É Ãâ·Â
            for (; j < endWidth; j++) {
              tar_data[retbiSizeImage] = 1; // Run Length
              retbiSizeImage++;
              tar_data[retbiSizeImage] = src_data[j]; // Raster Pixel index
              retbiSizeImage++;
            }  
          } else { // example: 1E 0A 0A ...
            tar_data[retbiSizeImage] = 1; // Run Length
            retbiSizeImage++;
            tar_data[retbiSizeImage] = src_data[j]; // Raster Pixel index
            retbiSizeImage++;
            j++; // ´ÙÀ½ °Ë»çÇÒ À§Ä¡
          }  
        }
        if (j >= endWidth) // ÇÑ ÇàÀÇ °è»êÀÌ ³¡³²
          break;
      }      
      tar_data[retbiSizeImage] = 0; // 0 = absolute mode
      retbiSizeImage++;
      tar_data[retbiSizeImage] = 0; // escape value: EOL(end of line)
      retbiSizeImage++;
    }    
    tar_data[retbiSizeImage] = 0; // 0 = absolute mode
    retbiSizeImage++;
    tar_data[retbiSizeImage] = 1; // escape value: EOB(end of bitmap)
    retbiSizeImage++;
  }

  else if (biBitCount == 16) {
          
  }

  else if (biBitCount == 24) {
          
  }
      
  // BITMAP_FILE_HEADER.bfSize
  pack_bytes(bmp_file.bfSize,
             14+40+ (biClrUsed*4) + retbiSizeImage,
             sizeof(bmp_file.bfSize));
        
  // BITMAP_INFO_HEADER.biCompression
  pack_bytes(bmp_info.biCompression,
             retbiCompression, // RLE encoding
             sizeof(bmp_info.biCompression));
        
  // BITMAP_INFO_HEADER.biSizeImage
  pack_bytes(bmp_info.biSizeImage,
             retbiSizeImage,
             sizeof(bmp_info.biSizeImage));

  // print_header(&bmp_file, &bmp_info, color_table, biClrUsed);

  // targetÆÄÀÏ¿¡ BITMAP_FILE_HEADER ¸¦ ¾´´Ù
  write(ofd, &bmp_file, sizeof(BITMAP_FILE_HEADER));

  // targetÆÄÀÏ¿¡ BITMAP_INFO_HEADER ¸¦ ¾´´Ù
  write(ofd, &bmp_info, sizeof(BITMAP_INFO_HEADER));

  // targetÆÄÀÏ¿¡ Color Table ¸¦ ¾´´Ù
  if (color_table != NULL)
    for (i=0; i < biClrUsed; i++)
      write(ofd, &color_table[i], sizeof(COLOR_TABLE));

  // targetÆÄÀÏ¿¡ RLE encoded Raster Data¸¦ ¾´´Ù
  write(ofd, tar_data, retbiSizeImage);
  
  free(color_table);
  free(src_data);
  free(tar_data);
  
  close(ifd);
  close(ofd);
}    





13   [ÄÄÇ»ÅÍ Àü°ø] [¼Ò½º] ÀÌÁø Æ®¸®(Binary Tree)  ±è¿µ´ë 2004/06/18 11271 2027
12   [ÄÄÇ»ÅÍ Àü°ø] [¼Ò½º] MASM °£´ÜÇÑ °è»ê±â ¾î¼Àºí¸® ÇÁ·Î±×·¥ ¼Ò½º  ±è¿µ´ë 2003/07/11 23301 1752
11   [ÄÄÇ»ÅÍ Àü°ø] [¼Ò½º] Top-down parsing by Recursive-Descent À» ÀÌ¿ëÇÑ °è»ê±â MASM ¾î¼Àºí¸® »ý¼º±â  ±è¿µ´ë 2003/07/11 10476 1851
10   [ÄÄÇ»ÅÍ Àü°ø] [¼Ò½º] Huffman Code Encoder  ±è¿µ´ë 2003/03/18 8805 1764
  [ÄÄÇ»ÅÍ Àü°ø] [¼Ò½º] Windows RLE(BMP) Encoder  ±è¿µ´ë 2003/03/18 8628 1506
8   [ÄÄÇ»ÅÍ Àü°ø] [¼Ò½º] CompuServe RLE Encoder  ±è¿µ´ë 2003/03/18 8529 1603
7   [ÄÄÇ»ÅÍ Àü°ø] [¼Ò½º] °è»ê±â¸¦ À§ÇÑ Lex & Yacc  ±è¿µ´ë 2003/03/15 11138 1789
6   [ÄÄÇ»ÅÍ Àü°ø] [¼Ò½º] ANSI-C Æļ­¸¦ À§ÇÑ Lex & Yacc  ±è¿µ´ë 2003/03/13 9963 2145
5   [ÄÄÇ»ÅÍ Àü°ø] [¼Ò½º] PL/0 Compiler ±¸Çö  ±è¿µ´ë 2003/03/13 8983 1973
4   [ÄÄÇ»ÅÍ Àü°ø] [¼Ò½º] Recursive-Descent ÆĽÌÀ» ÀÌ¿ëÇÑ °è»ê±â ±¸Çö  ±è¿µ´ë 2003/03/13 14215 1933
3   [ÄÄÇ»ÅÍ Àü°ø] [¼Ò½º] POSIX thread¸¦ »ç¿ëÇÑ Çà·Ä°è»ê  ±è¿µ´ë 2003/03/13 10033 1711
2   [ÄÄÇ»ÅÍ Àü°ø] [¼Ò½º] 0/1 ¹è³¶ ¹®Á¦(Knapsack Problem)  ±è¿µ´ë 2003/03/13 10243 1798
1   [ÄÄÇ»ÅÍ Àü°ø] [¼Ò½º] SIC/XE ¾î¼Àºí·¯ ±¸Çö  ±è¿µ´ë 2003/03/13 26193 2261

1
 

Copyright 1999-2024 Zeroboard / skin by zero