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