|
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 |
}
|