e280ae
#ifdef _MSC_VER
Toshihiro Shimizu 890ddd
#pragma warning(disable : 4996)
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 6a4e01
#include <memory></memory>
Shinya Kitaoka 6a4e01
Toshihiro Shimizu 890ddd
#include "tiio_bmp.h"
Toshihiro Shimizu 890ddd
// #include "bmp/filebmp.h"
Toshihiro Shimizu 890ddd
#include "tpixel.h"
Toshihiro Shimizu 890ddd
#include "tpixelgr.h"
Toshihiro Shimizu 890ddd
#include "tproperty.h"
Toshihiro Shimizu 890ddd
//#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include <stdio.h></stdio.h>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
typedef struct {
Shinya Kitaoka 120a6e
  UINT bfSize;
Shinya Kitaoka 120a6e
  UINT bfOffBits;
Shinya Kitaoka 120a6e
  UINT biSize;
Shinya Kitaoka 120a6e
  UINT biWidth;
Shinya Kitaoka 120a6e
  UINT biHeight;
Shinya Kitaoka 120a6e
  UINT biPlanes;
Shinya Kitaoka 120a6e
  UINT biBitCount;
Shinya Kitaoka 120a6e
  UINT biCompression;
Shinya Kitaoka 120a6e
  UINT biSizeImage;
Shinya Kitaoka 120a6e
  UINT biXPelsPerMeter;
Shinya Kitaoka 120a6e
  UINT biYPelsPerMeter;
Shinya Kitaoka 120a6e
  UINT biClrUsed;
Shinya Kitaoka 120a6e
  UINT biClrImportant;
Shinya Kitaoka 120a6e
  UINT biFilesize;
Shinya Kitaoka 120a6e
  UINT biPad;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} BMP_HEADER;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int BMP_WIN_SIZE = 40;
Toshihiro Shimizu 890ddd
const int BMP_OS2_SIZE = 64;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
const int BMP_BI_RGB  = 0;
Toshihiro Shimizu 890ddd
const int BMP_BI_RLE8 = 1;
Toshihiro Shimizu 890ddd
const int BMP_BI_RLE4 = 2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UINT getshort(FILE *fp) {
Shinya Kitaoka 120a6e
  int c = getc(fp), c1 = getc(fp);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return ((UINT)c) + (((UINT)c1) << 8);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UINT getint(FILE *fp) {
Shinya Kitaoka 120a6e
  int c = getc(fp), c1 = getc(fp), c2 = getc(fp), c3 = getc(fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return (((UINT)c) << 0) + (((UINT)c1) << 8) + (((UINT)c2) << 16) +
Shinya Kitaoka 120a6e
         (((UINT)c3) << 24);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void putshort(FILE *fp, int i) {
Shinya Kitaoka 120a6e
  int c = (((UINT)i)) & 0xff, c1 = (((UINT)i) >> 8) & 0xff;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  putc(c, fp);
Shinya Kitaoka 120a6e
  putc(c1, fp);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void putint(FILE *fp, int i) {
Shinya Kitaoka 120a6e
  int c = ((UINT)i) & 0xff, c1 = (((UINT)i) >> 8) & 0xff,
Shinya Kitaoka 120a6e
      c2 = (((UINT)i) >> 16) & 0xff, c3 = (((UINT)i) >> 24) & 0xff;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  putc(c, fp);
Shinya Kitaoka 120a6e
  putc(c1, fp);
Shinya Kitaoka 120a6e
  putc(c2, fp);
Shinya Kitaoka 120a6e
  putc(c3, fp);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class BmpReader final : public Tiio::Reader {
Shinya Kitaoka 120a6e
  FILE *m_chan;
Shinya Kitaoka 120a6e
  BMP_HEADER m_header;
Shinya Kitaoka 120a6e
  char *m_line;
Shinya Kitaoka 120a6e
  int m_lineSize;
Shinya Kitaoka 120a6e
  std::unique_ptr<tpixel[]> m_cmap;</tpixel[]>
Shinya Kitaoka 120a6e
  bool m_corrupted;
Shinya Kitaoka 120a6e
  typedef int (BmpReader::*ReadLineMethod)(char *buffer, int x0, int x1,
Shinya Kitaoka 120a6e
                                           int shrink);
Shinya Kitaoka 120a6e
  ReadLineMethod m_readLineMethod;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  BmpReader();
Shinya Kitaoka 120a6e
  ~BmpReader();
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void open(FILE *file) override;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int readNoLine(char *buffer, int x0, int x1, int shrink);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void skipBytes(int count) {
Shinya Kitaoka 120a6e
    // fseek(m_chan, count, SEEK_CUR);	//inefficiente se count รจ piccolo
Shinya Kitaoka 120a6e
    for (int i = 0; i < count; i++) {
Shinya Kitaoka 120a6e
      getc(m_chan);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int read1Line(char *buffer, int x0, int x1, int shrink);
Shinya Kitaoka 120a6e
  int read4Line(char *buffer, int x0, int x1, int shrink);
Shinya Kitaoka 120a6e
  int read8Line(char *buffer, int x0, int x1, int shrink);
Shinya Kitaoka 120a6e
  int read8LineRle(char *buffer, int x0, int x1, int shrink);
Shinya Kitaoka 120a6e
  int read16m555Line(char *buffer, int x0, int x1, int shrink);
Shinya Kitaoka 120a6e
  int read16m565Line(char *buffer, int x0, int x1, int shrink);
Shinya Kitaoka 120a6e
  int read24Line(char *buffer, int x0, int x1, int shrink);
Shinya Kitaoka 120a6e
  int read32Line(char *buffer, int x0, int x1, int shrink);
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void readLine(char *buffer, int x0, int x1, int shrink) override;
Shinya Kitaoka 473e70
  int skipLines(int lineCount) override {
Shinya Kitaoka 120a6e
    fseek(m_chan, lineCount * m_lineSize, SEEK_CUR);
Shinya Kitaoka 120a6e
    /* for(int i=0;i
Shinya Kitaoka 120a6e
            skipBytes(m_lineSize);*/
Shinya Kitaoka 120a6e
    return lineCount;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  void readHeader();
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
BmpReader::BmpReader()
Shinya Kitaoka 120a6e
    : m_chan(0), m_corrupted(false), m_readLineMethod(&BmpReader::readNoLine) {
Shinya Kitaoka 120a6e
  memset(&m_header, 0, sizeof m_header);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
BmpReader::~BmpReader() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void BmpReader::open(FILE *file) {
Shinya Kitaoka 120a6e
  m_chan = file;
Shinya Kitaoka 120a6e
  readHeader();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void BmpReader::readHeader() {
Shinya Kitaoka 120a6e
  if (!m_chan) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  fseek(m_chan, 0L, SEEK_END);
Shinya Kitaoka 120a6e
  m_header.biFilesize = ftell(m_chan);
Shinya Kitaoka 120a6e
  fseek(m_chan, 0L, 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* read the file type (first two bytes) */
Shinya Kitaoka 120a6e
  char signature[2];
Shinya Kitaoka 120a6e
  signature[0] = fgetc(m_chan);
Shinya Kitaoka 120a6e
  signature[1] = fgetc(m_chan);
Shinya Kitaoka 120a6e
  if (signature[0] != 'B' || signature[1] != 'M') {
Shinya Kitaoka 120a6e
    m_corrupted = true;
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_header.bfSize = getint(m_chan);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* reserved and ignored */
Shinya Kitaoka 120a6e
  getshort(m_chan);
Shinya Kitaoka 120a6e
  getshort(m_chan);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_header.bfOffBits = getint(m_chan);
Shinya Kitaoka 120a6e
  m_header.biSize    = getint(m_chan);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if ((int)m_header.biSize == BMP_WIN_SIZE ||
Shinya Kitaoka 120a6e
      (int)m_header.biSize == BMP_OS2_SIZE) {
Shinya Kitaoka 120a6e
    m_header.biWidth         = getint(m_chan);
Shinya Kitaoka 120a6e
    m_header.biHeight        = getint(m_chan);
Shinya Kitaoka 120a6e
    m_header.biPlanes        = getshort(m_chan);
Shinya Kitaoka 120a6e
    m_header.biBitCount      = getshort(m_chan);
Shinya Kitaoka 120a6e
    m_header.biCompression   = getint(m_chan);
Shinya Kitaoka 120a6e
    m_header.biSizeImage     = getint(m_chan);
Shinya Kitaoka 120a6e
    m_header.biXPelsPerMeter = getint(m_chan);
Shinya Kitaoka 120a6e
    m_header.biYPelsPerMeter = getint(m_chan);
Shinya Kitaoka 120a6e
    m_header.biClrUsed       = getint(m_chan);
Shinya Kitaoka 120a6e
    m_header.biClrImportant  = getint(m_chan);
Shinya Kitaoka 120a6e
  } else  // old bitmap format
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    m_header.biWidth    = getshort(m_chan);
Shinya Kitaoka 120a6e
    m_header.biHeight   = getshort(m_chan);
Shinya Kitaoka 120a6e
    m_header.biPlanes   = getshort(m_chan);
Shinya Kitaoka 120a6e
    m_header.biBitCount = getshort(m_chan);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /* Not in old versions so have to compute them */
Shinya Kitaoka 120a6e
    m_header.biSizeImage =
Shinya Kitaoka 120a6e
        (((m_header.biPlanes * m_header.biBitCount * m_header.biWidth) + 31) /
Shinya Kitaoka 120a6e
         32) *
Shinya Kitaoka 120a6e
        4 * m_header.biHeight;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_header.biCompression   = BMP_BI_RGB;
Shinya Kitaoka 120a6e
    m_header.biXPelsPerMeter = 0;
Shinya Kitaoka 120a6e
    m_header.biYPelsPerMeter = 0;
Shinya Kitaoka 120a6e
    m_header.biClrUsed       = 0;
Shinya Kitaoka 120a6e
    m_header.biClrImportant  = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_header.biPad = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_info.m_lx = m_header.biWidth;
Shinya Kitaoka 120a6e
  m_info.m_ly = m_header.biHeight;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
BMP_HEADER *hd = m_header;
Shinya Kitaoka 120a6e
if ((int)hd->biSize != BMP_WIN_OS2_OLD)
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
// skip ahead to colormap, using biSize
Shinya Kitaoka 120a6e
int c = hd->biSize - 40;  // 40 bytes read from biSize to biClrImportant
Shinya Kitaoka 120a6e
for (int i=0; i
Shinya Kitaoka 120a6e
hd->biPad = hd->bfOffBits - (hd->biSize + 14);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
else
Shinya Kitaoka 120a6e
hd->biPad = 0;
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // load up colormap, if any
Shinya Kitaoka 120a6e
  if (m_header.biBitCount < 16) {
Shinya Kitaoka 120a6e
    int cmaplen =
Shinya Kitaoka 120a6e
        (m_header.biClrUsed) ? m_header.biClrUsed : 1 << m_header.biBitCount;
Shinya Kitaoka 120a6e
    assert(cmaplen <= 256);
Shinya Kitaoka 120a6e
    m_cmap.reset(new TPixel[256]);
Shinya Kitaoka 120a6e
    TPixel32 *pix = m_cmap.get();
Shinya Kitaoka 120a6e
    for (int i = 0; i < cmaplen; i++) {
Shinya Kitaoka 120a6e
      pix->b = getc(m_chan);
Shinya Kitaoka 120a6e
      pix->g = getc(m_chan);
Shinya Kitaoka 120a6e
      pix->r = getc(m_chan);
Shinya Kitaoka 120a6e
      pix->m = 255;
Shinya Kitaoka 120a6e
      getc(m_chan);
Shinya Kitaoka 120a6e
      ++pix;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
if (hd->biSize != BMP_WIN_OS2_OLD)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
// Waste any unused bytes between the colour map (if present)
Shinya Kitaoka 120a6e
// and the start of the actual bitmap data.
Shinya Kitaoka 120a6e
while (hd->biPad > 0)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
  (void) getc(m_chan);
Shinya Kitaoka 120a6e
  hd->biPad--;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  // get information about the portion of the image to load
Shinya Kitaoka 120a6e
  // get_info_region(&info, x1, y1, x2, y2, scale,
Shinya Kitaoka 120a6e
  //		  (int)hd->biWidth,   (int)hd->biHeight, TNZ_BOTLEFT);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //   skip_bmp_lines(fp, hd->biWidth, (unsigned int)(info.startScanRow-1),
Shinya Kitaoka 120a6e
  //   (unsigned int)SEEK_CUR, subtype);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int lx = m_info.m_lx;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch (m_header.biBitCount) {
Shinya Kitaoka 120a6e
  case 1:
Shinya Kitaoka 120a6e
    m_info.m_samplePerPixel = 1;
Shinya Kitaoka 120a6e
    m_readLineMethod        = &BmpReader::read1Line;
Shinya Kitaoka 120a6e
    m_lineSize              = (lx + 7) / 8;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 4:
Shinya Kitaoka 120a6e
    m_info.m_samplePerPixel                           = 1;
Shinya Kitaoka 120a6e
    if (m_header.biCompression == 0) m_readLineMethod = &BmpReader::read4Line;
Shinya Kitaoka 120a6e
    m_lineSize                                        = (lx + 1) / 2;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 8:
Shinya Kitaoka 120a6e
    m_info.m_samplePerPixel = 1;
Shinya Kitaoka 120a6e
    if (m_header.biCompression == 0)
Shinya Kitaoka 120a6e
      m_readLineMethod = &BmpReader::read8Line;
Shinya Kitaoka 120a6e
    else if (m_header.biCompression == 1)
Shinya Kitaoka 120a6e
      m_readLineMethod = &BmpReader::read8LineRle;
Shinya Kitaoka 120a6e
    m_lineSize         = lx;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 16:
Shinya Kitaoka 120a6e
    m_info.m_samplePerPixel = 3;
Shinya Kitaoka 120a6e
    if (m_header.biCompression == 0)  // BI_RGB
Shinya Kitaoka 120a6e
      m_readLineMethod = &BmpReader::read16m555Line;
Shinya Kitaoka 120a6e
    else if (m_header.biCompression == 3)  // BI_BITFIELDS
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      unsigned int rmask = 0, gmask = 0, bmask = 0;
Shinya Kitaoka 120a6e
      rmask = getint(m_chan);
Shinya Kitaoka 120a6e
      gmask = getint(m_chan);
Shinya Kitaoka 120a6e
      bmask = getint(m_chan);
Shinya Kitaoka 120a6e
      if (gmask == 0x7E0)
Shinya Kitaoka 120a6e
        m_readLineMethod = &BmpReader::read16m565Line;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        m_readLineMethod = &BmpReader::read16m555Line;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    m_lineSize = lx * 2;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 24:
Shinya Kitaoka 120a6e
    m_info.m_samplePerPixel = 3;
Shinya Kitaoka 120a6e
    m_readLineMethod        = &BmpReader::read24Line;
Shinya Kitaoka 120a6e
    m_lineSize              = lx * 3;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 32:
Shinya Kitaoka 120a6e
    m_info.m_samplePerPixel = 3;
Shinya Kitaoka 120a6e
    m_readLineMethod        = &BmpReader::read32Line;
Shinya Kitaoka 120a6e
    m_lineSize              = lx * 4;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_lineSize += 3 - ((m_lineSize + 3) & 3);
Shinya Kitaoka 120a6e
  fseek(m_chan, m_header.bfOffBits, SEEK_SET);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void BmpReader::readLine(char *buffer, int x0, int x1, int shrink) {
Shinya Kitaoka 120a6e
  (this->*m_readLineMethod)(buffer, x0, x1, shrink);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int BmpReader::readNoLine(char *buffer, int x0, int x1, int shrink) {
Shinya Kitaoka 120a6e
  skipBytes(m_lineSize);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int BmpReader::read1Line(char *buffer, int x0, int x1, int shrink) {
Shinya Kitaoka 120a6e
  TPixel32 *pix = (TPixel32 *)buffer;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // pix += x0;
Shinya Kitaoka 120a6e
  if (x0 > 0) skipBytes(x0 / 8);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPixel32 *endPix = pix + x1 + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int value = 0;
Shinya Kitaoka 120a6e
  int index = x0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (x0 % 8 != 0) {
Shinya Kitaoka 120a6e
    value = getc(m_chan);
Shinya Kitaoka 120a6e
    for (index = x0; index < x0 + 8 - (x0 % 8); index += shrink) {
Shinya Kitaoka 120a6e
      pix[index] = m_cmap[(value >> (7 - ((index) % 8))) & 1];
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  value         = getc(m_chan);
Shinya Kitaoka 120a6e
  int prevBlock = index / 8;
Shinya Kitaoka 120a6e
  for (int j = index; pix + j < endPix; j += shrink) {
Shinya Kitaoka 120a6e
    if (j / 8 > prevBlock) value = getc(m_chan);
Shinya Kitaoka 120a6e
    prevBlock                    = j / 8;
Shinya Kitaoka 120a6e
    pix[j]                       = m_cmap[(value >> (7 - (j % 8))) & 1];
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
while(pix+8<=endPix)
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
value = getc(m_chan);
Shinya Kitaoka 120a6e
pix[0] = m_cmap[(value>>7)&1];
Shinya Kitaoka 120a6e
pix[1] = m_cmap[(value>>6)&1];
Shinya Kitaoka 120a6e
pix[2] = m_cmap[(value>>5)&1];
Shinya Kitaoka 120a6e
pix[3] = m_cmap[(value>>4)&1];
Shinya Kitaoka 120a6e
pix[4] = m_cmap[(value>>3)&1];
Shinya Kitaoka 120a6e
pix[5] = m_cmap[(value>>2)&1];
Shinya Kitaoka 120a6e
pix[6] = m_cmap[(value>>1)&1];
Shinya Kitaoka 120a6e
pix[7] = m_cmap[(value>>0)&1];
Shinya Kitaoka 120a6e
   pix +=8*shrink;
Shinya Kitaoka 120a6e
   if(shrink>1) value = getc(m_chan);
Shinya Kitaoka 120a6e
//pix+=8*shrink;
Shinya Kitaoka 120a6e
   //if(pix+8<endpix &&="" shrink="">1) skipBytes(shrink-1);</endpix>
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
if(pix
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
value = getc(m_chan);
Shinya Kitaoka 120a6e
assert(pix+8>=endPix);
Shinya Kitaoka 120a6e
for(int j=0; pix+j
Shinya Kitaoka 120a6e
pix[j] = m_cmap[(value>>(7-j))&1];
Shinya Kitaoka 120a6e
}		*/
Shinya Kitaoka 120a6e
  if ((m_info.m_lx - x1) / 8 > 0) {
Shinya Kitaoka 120a6e
    skipBytes((m_info.m_lx - x1) / 8);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int bytes = (m_info.m_lx + 7) / 8;
Shinya Kitaoka 120a6e
  if (m_lineSize - bytes > 0) skipBytes(m_lineSize - bytes);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int BmpReader::read4Line(char *buffer, int x0, int x1, int shrink) {
Shinya Kitaoka 120a6e
  TPixel32 *pix = (TPixel32 *)buffer;
Shinya Kitaoka 120a6e
  pix += 2 * x0;
Shinya Kitaoka 120a6e
  if (x0 > 0) skipBytes(x0 / 2);
Shinya Kitaoka 120a6e
  TPixel32 *endPix = pix + x1 - x0 + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int value;
Shinya Kitaoka 120a6e
  while (pix + 2 <= endPix) {
Shinya Kitaoka 120a6e
    value  = getc(m_chan);
Shinya Kitaoka 120a6e
    pix[0] = m_cmap[value & 0xF];
Shinya Kitaoka 120a6e
    pix[1] = m_cmap[(value >> 4) & 0xF];
Shinya Kitaoka 120a6e
    // pix+=2*shrink;
Shinya Kitaoka 120a6e
    pix++;
Shinya Kitaoka 120a6e
    // if(pix+2<=endPix && shrink>1) skipBytes(shrink-1);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (pix < endPix) {
Shinya Kitaoka 120a6e
    value  = getc(m_chan);
Shinya Kitaoka 120a6e
    pix[0] = m_cmap[value & 0xF];
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if ((m_info.m_lx - x1) / 2 > 0) {
Shinya Kitaoka 120a6e
    skipBytes((m_info.m_lx - x1) / 2);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int bytes = (m_info.m_lx + 1) / 2;
Shinya Kitaoka 120a6e
  if (m_lineSize - bytes) skipBytes(m_lineSize - bytes);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int BmpReader::read8Line(char *buffer, int x0, int x1, int shrink) {
Shinya Kitaoka 120a6e
  TPixel32 *pix = (TPixel32 *)buffer;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (x0 > 0) skipBytes(x0);
Shinya Kitaoka 120a6e
  pix += x0;
Shinya Kitaoka 120a6e
  TPixel32 *endPix = pix + x1 - x0 + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (pix < endPix) {
Shinya Kitaoka 120a6e
    int value = getc(m_chan);
Shinya Kitaoka 120a6e
    *pix++    = m_cmap[value];
Shinya Kitaoka 120a6e
    if (pix < endPix && shrink > 1) {
Shinya Kitaoka 120a6e
      skipBytes(shrink - 1);
Shinya Kitaoka 120a6e
      pix += (shrink - 1);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_info.m_lx - x1 - 1 > 0) {
Shinya Kitaoka 120a6e
    skipBytes(m_info.m_lx - x1 - 1);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_lineSize - m_info.m_lx > 0) skipBytes(m_lineSize - m_info.m_lx);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int BmpReader::read8LineRle(char *buffer, int x0, int x1, int shrink) {
Shinya Kitaoka 120a6e
  TPixel32 *pix = (TPixel32 *)buffer;
Shinya Kitaoka 120a6e
  if (x0 > 0) skipBytes(x0);
Shinya Kitaoka 120a6e
  pix += x0;
Shinya Kitaoka 120a6e
  TPixel32 *endPix = pix + (x1 - x0 + 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (pix < endPix) {
Shinya Kitaoka 120a6e
    int i, count = getc(m_chan);
Shinya Kitaoka 120a6e
    assert(count >= 0);
Shinya Kitaoka 120a6e
    if (count == 0) {
Shinya Kitaoka 120a6e
      int pixels = getc(m_chan);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      assert(pixels >= 0 && pixels != 2);
Shinya Kitaoka 120a6e
      if (pixels < 3) return 0;
Shinya Kitaoka 120a6e
      for (i = 0; i < pixels; i++) *pix++ = m_cmap[getc(m_chan)];
Shinya Kitaoka 120a6e
      if ((1 + 1 + pixels) & 0x1) getc(m_chan);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      int value = getc(m_chan);
Shinya Kitaoka 120a6e
      assert(value >= 0);
Shinya Kitaoka 120a6e
      for (i = 0; i < count; i++) *pix++ = m_cmap[value];
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (pix < endPix && shrink > 1) {
Shinya Kitaoka 120a6e
      skipBytes(shrink - 1);
Shinya Kitaoka 120a6e
      pix += (shrink - 1);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_info.m_lx - x1 - 1 > 0) {
Shinya Kitaoka 120a6e
    skipBytes(m_info.m_lx - x1 - 1);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_lineSize - m_info.m_lx > 0) skipBytes(m_lineSize - m_info.m_lx);
Shinya Kitaoka 120a6e
  int val = getc(m_chan);
Shinya Kitaoka 120a6e
  assert(val == 0);  // end scanline or end bmp
Shinya Kitaoka 120a6e
  val = getc(m_chan);
Shinya Kitaoka 120a6e
  assert(val == 0 || val == 1);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int BmpReader::read16m555Line(char *buffer, int x0, int x1, int shrink) {
Shinya Kitaoka 120a6e
  TPixel32 *pix = (TPixel32 *)buffer;
Shinya Kitaoka 120a6e
  if (x0 > 0) skipBytes(2 * x0);
Shinya Kitaoka 120a6e
  pix += x0;
Shinya Kitaoka 120a6e
  TPixel32 *endPix = pix + x1 - x0 + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (pix < endPix) {
Shinya Kitaoka 120a6e
    int v  = getshort(m_chan);
Shinya Kitaoka 120a6e
    int r  = (v >> 10) & 0x1F;
Shinya Kitaoka 120a6e
    int g  = (v >> 5) & 0x1F;
Shinya Kitaoka 120a6e
    int b  = v & 0x1F;
Shinya Kitaoka 120a6e
    pix->r = r << 3 | r >> 2;
Shinya Kitaoka 120a6e
    pix->g = g << 3 | g >> 2;
Shinya Kitaoka 120a6e
    pix->b = b << 3 | b >> 2;
Shinya Kitaoka 120a6e
    pix->m = 255;
Shinya Kitaoka 120a6e
    pix += shrink;
Shinya Kitaoka 120a6e
    if (pix < endPix && shrink > 1) skipBytes(2 * (shrink - 1));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (m_info.m_lx - x1 - 1 > 0) skipBytes(2 * (m_info.m_lx - x1 - 1));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_lineSize - 2 * m_info.m_lx > 0) skipBytes(m_lineSize - 2 * m_info.m_lx);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int BmpReader::read16m565Line(char *buffer, int x0, int x1, int shrink) {
Shinya Kitaoka 120a6e
  TPixel32 *pix = (TPixel32 *)buffer;
Shinya Kitaoka 120a6e
  if (x0 > 0) skipBytes(2 * x0);
Shinya Kitaoka 120a6e
  pix += x0;
Shinya Kitaoka 120a6e
  TPixel32 *endPix = pix + x1 - x0 + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (pix < endPix) {
Shinya Kitaoka 120a6e
    int v  = getshort(m_chan);
Shinya Kitaoka 120a6e
    int r  = (v >> 11) & 0x1F;
Shinya Kitaoka 120a6e
    int g  = (v >> 5) & 0x3F;
Shinya Kitaoka 120a6e
    int b  = v & 0x1F;
Shinya Kitaoka 120a6e
    pix->r = r << 3 | r >> 2;
Shinya Kitaoka 120a6e
    pix->g = g << 2 | g >> 4;
Shinya Kitaoka 120a6e
    pix->b = b << 3 | b >> 2;
Shinya Kitaoka 120a6e
    pix->m = 255;
Shinya Kitaoka 120a6e
    pix += shrink;
Shinya Kitaoka 120a6e
    if (pix < endPix && shrink > 1) skipBytes(2 * (shrink - 1));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (m_info.m_lx - x1 - 1 > 0) skipBytes(2 * (m_info.m_lx - x1 - 1));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_lineSize - 2 * m_info.m_lx > 0) skipBytes(m_lineSize - 2 * m_info.m_lx);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int BmpReader::read24Line(char *buffer, int x0, int x1, int shrink) {
Shinya Kitaoka 120a6e
  TPixel32 *pix = (TPixel32 *)buffer;
Shinya Kitaoka 120a6e
  if (x0 > 0) skipBytes(3 * x0);
Shinya Kitaoka 120a6e
  pix += x0;
Shinya Kitaoka 120a6e
  TPixel32 *endPix = pix + x1 - x0 + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (pix < endPix) {
Shinya Kitaoka 120a6e
    pix->b = getc(m_chan);
Shinya Kitaoka 120a6e
    pix->g = getc(m_chan);
Shinya Kitaoka 120a6e
    pix->r = getc(m_chan);
Shinya Kitaoka 120a6e
    pix->m = 255;
Shinya Kitaoka 120a6e
    pix += shrink;
Shinya Kitaoka 120a6e
    if (pix < endPix && shrink > 1) skipBytes(3 * (shrink - 1));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (m_info.m_lx - x1 - 1 > 0) skipBytes(3 * (m_info.m_lx - x1 - 1));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_lineSize - 3 * m_info.m_lx > 0) skipBytes(m_lineSize - 3 * m_info.m_lx);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int BmpReader::read32Line(char *buffer, int x0, int x1, int shrink) {
Shinya Kitaoka 120a6e
  TPixel32 *pix = (TPixel32 *)buffer;
Shinya Kitaoka 120a6e
  if (x0 > 0) skipBytes(4 * x0);
Shinya Kitaoka 120a6e
  pix += x0;
Shinya Kitaoka 120a6e
  TPixel32 *endPix = pix + x1 - x0 + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (pix < endPix) {
Shinya Kitaoka 120a6e
    pix->b = getc(m_chan);
Shinya Kitaoka 120a6e
    pix->g = getc(m_chan);
Shinya Kitaoka 120a6e
    pix->r = getc(m_chan);
Shinya Kitaoka 120a6e
    pix->m = getc(m_chan);
Shinya Kitaoka 120a6e
    pix += shrink;
Shinya Kitaoka 120a6e
    if (pix < endPix && shrink > 1) skipBytes(4 * (shrink - 1));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (m_info.m_lx - x1 - 1 > 0) skipBytes(4 * (m_info.m_lx - x1 - 1));
Shinya Kitaoka 120a6e
  if (m_lineSize - 4 * m_info.m_lx > 0) skipBytes(m_lineSize - 4 * m_info.m_lx);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class BmpWriter final : public Tiio::Writer {
Shinya Kitaoka 120a6e
  FILE *m_chan;
Shinya Kitaoka 120a6e
  int m_bitPerPixel;
Shinya Kitaoka 120a6e
  int m_compression;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  BmpWriter();
Shinya Kitaoka 120a6e
  ~BmpWriter();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void open(FILE *file, const TImageInfo &info) override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void flush() override { fflush(m_chan); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void writeLine(char *buffer) override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
BmpWriter::BmpWriter() : m_chan(0) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
BmpWriter::~BmpWriter() { delete m_properties; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void BmpWriter::open(FILE *file, const TImageInfo &info) {
Shinya Kitaoka 120a6e
  m_chan = file;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_info = info;
Shinya Kitaoka 120a6e
  int lx = m_info.m_lx;
Shinya Kitaoka 120a6e
  int ly = m_info.m_ly;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_properties) m_properties = new Tiio::BmpWriterProperties();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TEnumProperty *p =
Shinya Kitaoka 120a6e
      (TEnumProperty *)(m_properties->getProperty("Bits Per Pixel"));
Shinya Kitaoka 120a6e
  assert(p);
Shinya Kitaoka 120a6e
  std::string str = ::to_string(p->getValue());
Shinya Kitaoka 120a6e
  m_bitPerPixel   = atoi(str.c_str());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int cmapSize                  = 0;
Shinya Kitaoka 120a6e
  std::vector<tpixel> *colormap = 0;</tpixel>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_bitPerPixel == 8) {
Shinya Kitaoka 120a6e
    TPointerProperty *colormapProp =
Shinya Kitaoka 120a6e
        (TPointerProperty *)(m_properties->getProperty("Colormap"));
Shinya Kitaoka 120a6e
    if (colormapProp) {
Shinya Kitaoka 120a6e
      colormap = (std::vector<tpixel> *)colormapProp->getValue();</tpixel>
Shinya Kitaoka 120a6e
      cmapSize = colormap->size();
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      cmapSize = 256;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(m_bitPerPixel == 8 || m_bitPerPixel == 24);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int bytePerLine =
Shinya Kitaoka 120a6e
      ((lx * m_bitPerPixel + 31) / 32) * (m_bitPerPixel == 8 ? 1 : 4);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int fileSize = 14                  // file header
Shinya Kitaoka 120a6e
                 + 40                // info header
Shinya Kitaoka 120a6e
                 + cmapSize * 4      // colormap size
Shinya Kitaoka 120a6e
                 + bytePerLine * ly  // image size
Shinya Kitaoka 120a6e
      ;
Shinya Kitaoka 120a6e
  int offset      = 14 + 40 + cmapSize * 4;
Shinya Kitaoka 120a6e
  int compression = 0;
Shinya Kitaoka 120a6e
  int imageSize   = bytePerLine * ly;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  putc('B', m_chan);
Shinya Kitaoka 120a6e
  putc('M', m_chan);  // BMP file magic number
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  putint(m_chan, fileSize);
Shinya Kitaoka 120a6e
  putshort(m_chan, 0);  // reserved1
Shinya Kitaoka 120a6e
  putshort(m_chan, 0);  // reserved2
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  putint(m_chan, offset);  // offset from BOfile to BObitmap
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  putint(m_chan, 40);               // size of bitmap info header
Shinya Kitaoka 120a6e
  putint(m_chan, m_info.m_lx);      // width
Shinya Kitaoka 120a6e
  putint(m_chan, m_info.m_ly);      // height
Shinya Kitaoka 120a6e
  putshort(m_chan, 1);              // must be '1'
Shinya Kitaoka 120a6e
  putshort(m_chan, m_bitPerPixel);  // 1,4,8, or 24
Shinya Kitaoka 120a6e
  putint(m_chan, compression);      // BMP_BI_RGB, BMP_BI_RLE8 or BMP_BI_RLE4
Shinya Kitaoka 120a6e
  putint(m_chan, imageSize);        // size of raw image data
Shinya Kitaoka 120a6e
  putint(m_chan, 0);                // dpi * 39" per meter
Shinya Kitaoka 120a6e
  putint(m_chan, 0);                // dpi * 39" per meter
Shinya Kitaoka 120a6e
  putint(m_chan, cmapSize);         // colors used in cmap
Shinya Kitaoka 120a6e
  putint(m_chan, 0);                // same as above
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (colormap)
Shinya Kitaoka 120a6e
    for (int i = 0; i < (int)colormap->size(); i++) {
Shinya Kitaoka 120a6e
      putc((*colormap)[i].b, m_chan);
Shinya Kitaoka 120a6e
      putc((*colormap)[i].g, m_chan);
Shinya Kitaoka 120a6e
      putc((*colormap)[i].r, m_chan);
Shinya Kitaoka 120a6e
      putc(0, m_chan);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    for (int i = 0; i < cmapSize; i++)  // palette!!
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      putc(i, m_chan);
Shinya Kitaoka 120a6e
      putc(i, m_chan);
Shinya Kitaoka 120a6e
      putc(i, m_chan);
Shinya Kitaoka 120a6e
      putc(0, m_chan);
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void BmpWriter::writeLine(char *buffer) {
Shinya Kitaoka 120a6e
  int lx = m_info.m_lx;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int j;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch (m_bitPerPixel) {
Shinya Kitaoka 120a6e
  case 24: {
Shinya Kitaoka 120a6e
    TPixel32 *pix = (TPixel32 *)buffer;
Shinya Kitaoka 120a6e
    for (j = 0; j < lx; j++) {
Shinya Kitaoka 120a6e
      putc(pix->b, m_chan);
Shinya Kitaoka 120a6e
      putc(pix->g, m_chan);
Shinya Kitaoka 120a6e
      putc(pix->r, m_chan);
Shinya Kitaoka 120a6e
      ++pix;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    int bytes = lx * 3;
Shinya Kitaoka 120a6e
    while (bytes & 3) {
Shinya Kitaoka 120a6e
      putc(0, m_chan);
Shinya Kitaoka 120a6e
      bytes++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  case 8: {
Shinya Kitaoka 120a6e
    TPixelGR8 *pix = (TPixelGR8 *)buffer;
Shinya Kitaoka 120a6e
    for (j = 0; j < lx; j++) {
Shinya Kitaoka 120a6e
      putc(pix->value, m_chan);
Shinya Kitaoka 120a6e
      ++pix;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    while (lx & 3) {
Shinya Kitaoka 120a6e
      putc(0, m_chan);
Shinya Kitaoka 120a6e
      lx++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    assert(false);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  ftell(m_chan);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Tiio::Reader *Tiio::makeBmpReader() { return new BmpReader(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Tiio::Writer *Tiio::makeBmpWriter() { return new BmpWriter(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Tiio::BmpWriterProperties::BmpWriterProperties()
Shinya Kitaoka 120a6e
    : m_pixelSize("Bits Per Pixel") {
Shinya Kitaoka 120a6e
  m_pixelSize.addValue(L"24 bits");
Shinya Kitaoka 120a6e
  m_pixelSize.addValue(L"8 bits (Greyscale)");
Shinya Kitaoka 120a6e
  bind(m_pixelSize);
Toshihiro Shimizu 890ddd
}