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