|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
d869b5 |
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
|
Toshihiro Shimizu |
890ddd |
#define _CRT_SECURE_NO_DEPRECATE 1
|
|
Toshihiro Shimizu |
890ddd |
#pragma warning(disable : 4996)
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//#include "texception.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "tfilepath.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tiio_tga.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tpixel.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//#include <iostream.h></iostream.h>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline unsigned short fgetUSHORT(FILE *chan) {
|
|
Shinya Kitaoka |
120a6e |
int b0 = fgetc(chan);
|
|
Shinya Kitaoka |
120a6e |
int b1 = fgetc(chan);
|
|
Shinya Kitaoka |
120a6e |
return b1 << 8 | b0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Shinya Kitaoka |
120a6e |
inline unsigned short fgetULONG(FILE *chan)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int a = fgetc(chan);
|
|
Toshihiro Shimizu |
890ddd |
int b = fgetc(chan);
|
|
Toshihiro Shimizu |
890ddd |
int c = fgetc(chan);
|
|
Toshihiro Shimizu |
890ddd |
int d = fgetc(chan);
|
|
Toshihiro Shimizu |
890ddd |
return a<<24|b<<16|c<<8|d;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void fputUSHORT(unsigned short x, FILE *chan) {
|
|
Shinya Kitaoka |
120a6e |
int b1 = x >> 8;
|
|
Shinya Kitaoka |
120a6e |
int b0 = x & 0xFF;
|
|
Shinya Kitaoka |
120a6e |
fputc(b0, chan);
|
|
Shinya Kitaoka |
120a6e |
fputc(b1, chan);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
inline void fputULONG(unsigned long x, FILE *chan)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int a = x>>24;
|
|
Toshihiro Shimizu |
890ddd |
int b = (x>>16)&0xff;
|
|
Toshihiro Shimizu |
890ddd |
int c = (x>>8)&0xff;
|
|
Toshihiro Shimizu |
890ddd |
int d = x&0xFF;
|
|
Toshihiro Shimizu |
890ddd |
fputc(a, chan);
|
|
Toshihiro Shimizu |
890ddd |
fputc(b, chan);
|
|
Toshihiro Shimizu |
890ddd |
fputc(c, chan);
|
|
Toshihiro Shimizu |
890ddd |
fputc(d, chan);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef unsigned char UCHAR;
|
|
Toshihiro Shimizu |
890ddd |
typedef unsigned short USHORT;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
struct TgaHeader {
|
|
Shinya Kitaoka |
120a6e |
UCHAR IdentificationField;
|
|
Shinya Kitaoka |
120a6e |
UCHAR ColorMapType;
|
|
Shinya Kitaoka |
120a6e |
UCHAR ImageTypeCode;
|
|
Shinya Kitaoka |
120a6e |
USHORT ColorMapOrigin;
|
|
Shinya Kitaoka |
120a6e |
USHORT ColorMapLength;
|
|
Shinya Kitaoka |
120a6e |
UCHAR ColorMapSize;
|
|
Shinya Kitaoka |
120a6e |
USHORT Ximage;
|
|
Shinya Kitaoka |
120a6e |
USHORT Yimage;
|
|
Shinya Kitaoka |
120a6e |
USHORT Width;
|
|
Shinya Kitaoka |
120a6e |
USHORT Height;
|
|
Shinya Kitaoka |
120a6e |
UCHAR ImagePixelSize;
|
|
Shinya Kitaoka |
120a6e |
UCHAR ImageDescriptor;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static void readTgaHeader(TgaHeader &header, FILE *chan) {
|
|
Shinya Kitaoka |
120a6e |
header.IdentificationField = fgetc(chan);
|
|
Shinya Kitaoka |
120a6e |
header.ColorMapType = fgetc(chan);
|
|
Shinya Kitaoka |
120a6e |
header.ImageTypeCode = fgetc(chan);
|
|
Shinya Kitaoka |
120a6e |
header.ColorMapOrigin = fgetUSHORT(chan);
|
|
Shinya Kitaoka |
120a6e |
header.ColorMapLength = fgetUSHORT(chan);
|
|
Shinya Kitaoka |
120a6e |
header.ColorMapSize = fgetc(chan);
|
|
Shinya Kitaoka |
120a6e |
header.Ximage = fgetUSHORT(chan);
|
|
Shinya Kitaoka |
120a6e |
header.Yimage = fgetUSHORT(chan);
|
|
Shinya Kitaoka |
120a6e |
header.Width = fgetUSHORT(chan);
|
|
Shinya Kitaoka |
120a6e |
header.Height = fgetUSHORT(chan);
|
|
Shinya Kitaoka |
120a6e |
header.ImagePixelSize = fgetc(chan);
|
|
Shinya Kitaoka |
120a6e |
header.ImageDescriptor = fgetc(chan);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static void writeTgaHeader(TgaHeader &header, FILE *chan) {
|
|
Shinya Kitaoka |
120a6e |
fputc(header.IdentificationField, chan);
|
|
Shinya Kitaoka |
120a6e |
fputc(header.ColorMapType, chan);
|
|
Shinya Kitaoka |
120a6e |
fputc(header.ImageTypeCode, chan);
|
|
Shinya Kitaoka |
120a6e |
fputUSHORT(header.ColorMapOrigin, chan);
|
|
Shinya Kitaoka |
120a6e |
fputUSHORT(header.ColorMapLength, chan);
|
|
Shinya Kitaoka |
120a6e |
fputc(header.ColorMapSize, chan);
|
|
Shinya Kitaoka |
120a6e |
fputUSHORT(header.Ximage, chan);
|
|
Shinya Kitaoka |
120a6e |
fputUSHORT(header.Yimage, chan);
|
|
Shinya Kitaoka |
120a6e |
fputUSHORT(header.Width, chan);
|
|
Shinya Kitaoka |
120a6e |
fputUSHORT(header.Height, chan);
|
|
Shinya Kitaoka |
120a6e |
fputc(header.ImagePixelSize, chan);
|
|
Shinya Kitaoka |
120a6e |
fputc(header.ImageDescriptor, chan);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class TgaReader final : public Tiio::Reader {
|
|
Shinya Kitaoka |
120a6e |
FILE *m_chan;
|
|
Shinya Kitaoka |
120a6e |
TgaHeader m_header;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *m_palette;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
typedef void (TgaReader::*ReadLineProc)(char *buffer, int x0, int x1,
|
|
Shinya Kitaoka |
120a6e |
int shrink);
|
|
Shinya Kitaoka |
120a6e |
ReadLineProc m_readLineProc;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
typedef int (TgaReader::*SkipLineProc)(int count);
|
|
Shinya Kitaoka |
120a6e |
SkipLineProc m_skipLineProc;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TgaReader()
|
|
Shinya Kitaoka |
120a6e |
: m_chan(0)
|
|
Shinya Kitaoka |
120a6e |
, m_readLineProc(&TgaReader::readNoLine)
|
|
Shinya Kitaoka |
120a6e |
, m_skipLineProc(&TgaReader::skipLines0)
|
|
Shinya Kitaoka |
120a6e |
, m_palette(0) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
~TgaReader();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void open(FILE *file) override;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int skipLines0(int count) {
|
|
Shinya Kitaoka |
120a6e |
int lineSize = m_info.m_lx;
|
|
Shinya Kitaoka |
120a6e |
fseek(m_chan, count * lineSize, SEEK_CUR);
|
|
Shinya Kitaoka |
120a6e |
return count;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
int skipNoLines(int count) { return 0; };
|
|
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++) getc(m_chan);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int skipLines32(int count) {
|
|
Shinya Kitaoka |
120a6e |
skipLines0(4 * count);
|
|
Shinya Kitaoka |
120a6e |
return count;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
int skipLines24(int count) {
|
|
Shinya Kitaoka |
120a6e |
skipLines0(3 * count);
|
|
Shinya Kitaoka |
120a6e |
return count;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
int skipLines16(int count) {
|
|
Shinya Kitaoka |
120a6e |
skipLines0(2 * count);
|
|
Shinya Kitaoka |
120a6e |
return count;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
inline TPixel32 fgetPixel32(FILE *chan) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 pix;
|
|
Shinya Kitaoka |
120a6e |
pix.b = fgetc(chan);
|
|
Shinya Kitaoka |
120a6e |
pix.g = fgetc(chan);
|
|
Shinya Kitaoka |
120a6e |
pix.r = fgetc(chan);
|
|
Shinya Kitaoka |
120a6e |
pix.m = fgetc(chan);
|
|
Shinya Kitaoka |
120a6e |
return pix;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
inline TPixel32 fgetPixel24(FILE *chan) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 pix;
|
|
Shinya Kitaoka |
120a6e |
pix.b = fgetc(chan);
|
|
Shinya Kitaoka |
120a6e |
pix.g = fgetc(chan);
|
|
Shinya Kitaoka |
120a6e |
pix.r = fgetc(chan);
|
|
Shinya Kitaoka |
120a6e |
pix.m = 255;
|
|
Shinya Kitaoka |
120a6e |
return pix;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
inline TPixel32 fgetPixel16(FILE *chan) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 pix;
|
|
Shinya Kitaoka |
120a6e |
unsigned short s = fgetUSHORT(chan);
|
|
Shinya Kitaoka |
120a6e |
int b = s & 0x1f;
|
|
Shinya Kitaoka |
120a6e |
int g = (s >> 5) & 0x1f;
|
|
Shinya Kitaoka |
120a6e |
int r = (s >> 10) & 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 |
return pix;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
Tiio::RowOrder getRowOrder() const override {
|
|
Shinya Kitaoka |
120a6e |
return ((m_header.ImageDescriptor >> 5) & 1) == 0 ? Tiio::BOTTOM2TOP
|
|
Shinya Kitaoka |
120a6e |
: Tiio::TOP2BOTTOM;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void readLine(char *buffer, int x0, int x1, int shrink) override {
|
|
Shinya Kitaoka |
120a6e |
(this->*m_readLineProc)(buffer, x0, x1, shrink);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
473e70 |
int skipLines(int count) override { return (this->*m_skipLineProc)(count); }
|
|
Shinya Kitaoka |
120a6e |
void readPalette();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void readNoLine(char *buffer, int x0, int x1, int shrink) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void readLineRGB32(char *buffer, int x0, int x1, int shrink);
|
|
Shinya Kitaoka |
120a6e |
void readLineRGB32rle(char *buffer, int x0, int x1, int shrink);
|
|
Shinya Kitaoka |
120a6e |
void readLineRGB24(char *buffer, int x0, int x1, int shrink);
|
|
Shinya Kitaoka |
120a6e |
void readLineRGB24rle(char *buffer, int x0, int x1, int shrink);
|
|
Shinya Kitaoka |
120a6e |
void readLineRGB16(char *buffer, int x0, int x1, int shrink);
|
|
Shinya Kitaoka |
120a6e |
void readLineRGB16rle(char *buffer, int x0, int x1, int shrink);
|
|
Shinya Kitaoka |
120a6e |
void readLineGR8(char *buffer, int x0, int x1, int shrink);
|
|
Shinya Kitaoka |
120a6e |
void readLineGR8rle(char *buffer, int x0, int x1, int shrink);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void readLineCmapped(char *buffer, int x0, int x1, int shrink);
|
|
Shinya Kitaoka |
120a6e |
void readLineCmappedRle(char *buffer, int x0, int x1, int shrink);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TgaReader::~TgaReader() { delete m_palette; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaReader::open(FILE *file) {
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
m_chan = file;
|
|
Shinya Kitaoka |
120a6e |
} catch (...) {
|
|
Shinya Kitaoka |
120a6e |
perror("uffa");
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
readTgaHeader(m_header, m_chan);
|
|
Shinya Kitaoka |
120a6e |
m_info.m_lx = m_header.Width;
|
|
Shinya Kitaoka |
120a6e |
m_info.m_ly = m_header.Height;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_header.IdentificationField > 0) {
|
|
Shinya Kitaoka |
120a6e |
char tmp[256];
|
|
Shinya Kitaoka |
120a6e |
fread(tmp, 1, m_header.IdentificationField, m_chan);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (m_header.ColorMapType > 0) {
|
|
Shinya Kitaoka |
120a6e |
readPalette();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
Tiio::TgaWriterProperties *prop = new Tiio::TgaWriterProperties();
|
|
Shinya Kitaoka |
120a6e |
m_info.m_properties = prop;
|
|
Shinya Kitaoka |
120a6e |
prop->m_compressed.setValue(false);
|
|
Shinya Kitaoka |
120a6e |
switch (m_header.ImageTypeCode) {
|
|
Shinya Kitaoka |
120a6e |
case 0:
|
|
Shinya Kitaoka |
120a6e |
// cout << "NO IMAGE" << endl;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 1:
|
|
Shinya Kitaoka |
120a6e |
// cout << "Uncompressed Cmapped; pixelsize=" << m_header.ImagePixelSize
|
|
Shinya Kitaoka |
120a6e |
// << endl;
|
|
Shinya Kitaoka |
120a6e |
m_readLineProc = &TgaReader::readLineCmapped;
|
|
Shinya Kitaoka |
120a6e |
m_info.m_samplePerPixel = 4;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 2:
|
|
Shinya Kitaoka |
120a6e |
// cout << "Uncompressed RGB; pixelsize=" << m_header.ImagePixelSize <<
|
|
Shinya Kitaoka |
120a6e |
// endl;
|
|
Shinya Kitaoka |
120a6e |
m_info.m_samplePerPixel = 4;
|
|
Shinya Kitaoka |
120a6e |
if (m_header.ImagePixelSize == 32) {
|
|
Shinya Kitaoka |
120a6e |
m_readLineProc = &TgaReader::readLineRGB32;
|
|
Shinya Kitaoka |
120a6e |
m_skipLineProc = &TgaReader::skipLines32;
|
|
Shinya Kitaoka |
120a6e |
} else if (m_header.ImagePixelSize == 24) {
|
|
Shinya Kitaoka |
120a6e |
m_info.m_samplePerPixel = 3;
|
|
Shinya Kitaoka |
120a6e |
m_readLineProc = &TgaReader::readLineRGB24;
|
|
Shinya Kitaoka |
120a6e |
m_skipLineProc = &TgaReader::skipLines24;
|
|
Shinya Kitaoka |
120a6e |
} else if (m_header.ImagePixelSize == 16) {
|
|
Shinya Kitaoka |
120a6e |
m_readLineProc = &TgaReader::readLineRGB16;
|
|
Shinya Kitaoka |
120a6e |
m_skipLineProc = &TgaReader::skipLines16;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 3:
|
|
Shinya Kitaoka |
120a6e |
m_info.m_samplePerPixel = 1;
|
|
Shinya Kitaoka |
120a6e |
m_readLineProc = &TgaReader::readLineGR8;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 9:
|
|
Shinya Kitaoka |
120a6e |
// cout << "Compressed Cmapped; pixelsize=" << m_header.ImagePixelSize <<
|
|
Shinya Kitaoka |
120a6e |
// endl;
|
|
Shinya Kitaoka |
120a6e |
prop->m_compressed.setValue(true);
|
|
Shinya Kitaoka |
120a6e |
m_readLineProc = &TgaReader::readLineCmappedRle;
|
|
Shinya Kitaoka |
120a6e |
m_info.m_samplePerPixel = 4;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 10:
|
|
Shinya Kitaoka |
120a6e |
// cout << "Compressed RGB; pixelsize=" << m_header.ImagePixelSize <<
|
|
Shinya Kitaoka |
120a6e |
// endl;
|
|
Shinya Kitaoka |
120a6e |
prop->m_compressed.setValue(true);
|
|
Shinya Kitaoka |
120a6e |
m_info.m_samplePerPixel = 4;
|
|
Shinya Kitaoka |
120a6e |
if (m_header.ImagePixelSize == 32) {
|
|
Shinya Kitaoka |
120a6e |
m_readLineProc = &TgaReader::readLineRGB32rle;
|
|
Shinya Kitaoka |
120a6e |
m_skipLineProc = &TgaReader::skipNoLines;
|
|
Shinya Kitaoka |
120a6e |
} else if (m_header.ImagePixelSize == 24) {
|
|
Shinya Kitaoka |
120a6e |
m_info.m_samplePerPixel = 3;
|
|
Shinya Kitaoka |
120a6e |
m_readLineProc = &TgaReader::readLineRGB24rle;
|
|
Shinya Kitaoka |
120a6e |
m_skipLineProc = &TgaReader::skipNoLines;
|
|
Shinya Kitaoka |
120a6e |
} else if (m_header.ImagePixelSize == 16) {
|
|
Shinya Kitaoka |
120a6e |
m_readLineProc = &TgaReader::readLineRGB16rle;
|
|
Shinya Kitaoka |
120a6e |
m_skipLineProc = &TgaReader::skipNoLines;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 11:
|
|
Shinya Kitaoka |
120a6e |
m_info.m_samplePerPixel = 1;
|
|
Shinya Kitaoka |
120a6e |
m_readLineProc = &TgaReader::readLineGR8rle;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
default:;
|
|
Shinya Kitaoka |
120a6e |
// cout << "***Unknown***" << endl;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaReader::readPalette() {
|
|
Shinya Kitaoka |
120a6e |
int colorCount = m_header.ColorMapLength;
|
|
Shinya Kitaoka |
120a6e |
int bitPerColor = m_header.ColorMapSize;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// cout << "Reading palette: " << colorCount << " " << bitPerColor <<
|
|
Shinya Kitaoka |
120a6e |
// "-entries" << endl;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_palette = new TPixel32[colorCount];
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
switch (bitPerColor) {
|
|
Shinya Kitaoka |
120a6e |
case 16:
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < colorCount; i++) m_palette[i] = fgetPixel16(m_chan);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 24:
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < colorCount; i++) m_palette[i] = fgetPixel24(m_chan);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 32:
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < colorCount; i++) m_palette[i] = fgetPixel32(m_chan);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaReader::readLineRGB32(char *buffer, int x0, int x1, int shrink) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *pix = (TPixel32 *)buffer;
|
|
Shinya Kitaoka |
120a6e |
pix += x0;
|
|
Shinya Kitaoka |
120a6e |
if (x0 > 0) skipBytes(4 * x0);
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *endPix = pix + x1 - x0 + 1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (pix < endPix) {
|
|
Shinya Kitaoka |
120a6e |
*pix++ = fgetPixel32(m_chan);
|
|
Shinya Kitaoka |
120a6e |
if (pix < endPix && shrink > 1) {
|
|
Shinya Kitaoka |
120a6e |
pix += (shrink - 1);
|
|
Shinya Kitaoka |
120a6e |
skipBytes(4 * (shrink - 1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (m_info.m_lx - x1 - 1 > 0) skipBytes(4 * (m_info.m_lx - x1 - 1));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaReader::readLineRGB24(char *buffer, int x0, int x1, int shrink) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *pix = (TPixel32 *)buffer;
|
|
Shinya Kitaoka |
120a6e |
pix += x0;
|
|
Shinya Kitaoka |
120a6e |
if (x0 > 0) skipBytes(3 * x0);
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *endPix = pix + x1 - x0 + 1;
|
|
Shinya Kitaoka |
120a6e |
while (pix < endPix) {
|
|
Shinya Kitaoka |
120a6e |
*pix++ = fgetPixel24(m_chan);
|
|
Shinya Kitaoka |
120a6e |
if (pix < endPix && shrink > 1) {
|
|
Shinya Kitaoka |
120a6e |
pix += (shrink - 1);
|
|
Shinya Kitaoka |
120a6e |
skipBytes(3 * (shrink - 1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (m_info.m_lx - x1 - 1 > 0) skipBytes(3 * (m_info.m_lx - x1 - 1));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaReader::readLineRGB16(char *buffer, int x0, int x1, int shrink) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *pix = (TPixel32 *)buffer;
|
|
Shinya Kitaoka |
120a6e |
pix += x0;
|
|
Shinya Kitaoka |
120a6e |
if (x0 > 0) skipBytes(2 * x0);
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *endPix = pix + x1 - x0 + 1;
|
|
Shinya Kitaoka |
120a6e |
while (pix < endPix) {
|
|
Shinya Kitaoka |
120a6e |
*pix++ = fgetPixel16(m_chan);
|
|
Shinya Kitaoka |
120a6e |
if (pix < endPix && shrink > 1) {
|
|
Shinya Kitaoka |
120a6e |
pix += (shrink - 1);
|
|
Shinya Kitaoka |
120a6e |
skipBytes(2 * (shrink - 1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (m_info.m_lx - x1 - 1 > 0) skipBytes(2 * (m_info.m_lx - x1 - 1));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaReader::readLineCmapped(char *buffer, int x0, int x1, int shrink) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *pix = (TPixel32 *)buffer;
|
|
Shinya Kitaoka |
120a6e |
pix += x0;
|
|
Shinya Kitaoka |
120a6e |
if (x0 > 0) skipBytes(x0);
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *endPix = pix + x1 - x0 + 1;
|
|
Shinya Kitaoka |
120a6e |
while (pix < endPix) {
|
|
Shinya Kitaoka |
120a6e |
int index = fgetc(m_chan);
|
|
Shinya Kitaoka |
120a6e |
*pix++ = m_palette[index];
|
|
Shinya Kitaoka |
120a6e |
if (pix < endPix && shrink > 1) {
|
|
Shinya Kitaoka |
120a6e |
pix += (shrink - 1);
|
|
Shinya Kitaoka |
120a6e |
skipBytes(shrink - 1);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (m_info.m_lx - x1 - 1 > 0) skipBytes(m_info.m_lx - x1 - 1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaReader::readLineRGB32rle(char *buffer, int x0, int x1, int shrink) {
|
|
Shinya Kitaoka |
120a6e |
int x = 0;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *row = (TPixel32 *)buffer;
|
|
Shinya Kitaoka |
120a6e |
while (x < m_info.m_lx) {
|
|
Shinya Kitaoka |
120a6e |
UCHAR h = fgetc(m_chan);
|
|
Shinya Kitaoka |
120a6e |
int count = (h & 0x7F) + 1;
|
|
Shinya Kitaoka |
120a6e |
if (h & 0x80) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 pix = fgetPixel32(m_chan);
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < count && x < m_info.m_lx; i++) row[x++] = pix;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < count && x < m_info.m_lx; i++)
|
|
Shinya Kitaoka |
120a6e |
row[x++] = fgetPixel32(m_chan);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaReader::readLineRGB24rle(char *buffer, int x0, int x1, int shrink) {
|
|
Shinya Kitaoka |
120a6e |
int x = 0;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *row = (TPixel32 *)buffer;
|
|
Shinya Kitaoka |
120a6e |
while (x < m_info.m_lx) {
|
|
Shinya Kitaoka |
120a6e |
UCHAR h = fgetc(m_chan);
|
|
Shinya Kitaoka |
120a6e |
int count = (h & 0x7F) + 1;
|
|
Shinya Kitaoka |
120a6e |
if (h & 0x80) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 pix = fgetPixel24(m_chan);
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < count && x < m_info.m_lx; i++) row[x++] = pix;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < count && x < m_info.m_lx; i++)
|
|
Shinya Kitaoka |
120a6e |
row[x++] = fgetPixel24(m_chan);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaReader::readLineRGB16rle(char *buffer, int x0, int x1, int shrink) {
|
|
Shinya Kitaoka |
120a6e |
int x = 0;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *row = (TPixel32 *)buffer;
|
|
Shinya Kitaoka |
120a6e |
while (x < m_info.m_lx) {
|
|
Shinya Kitaoka |
120a6e |
UCHAR h = fgetc(m_chan);
|
|
Shinya Kitaoka |
120a6e |
int count = (h & 0x7F) + 1;
|
|
Shinya Kitaoka |
120a6e |
if (h & 0x80) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 pix = fgetPixel16(m_chan);
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < count && x < m_info.m_lx; i++) row[x++] = pix;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < count && x < m_info.m_lx; i++)
|
|
Shinya Kitaoka |
120a6e |
row[x++] = fgetPixel16(m_chan);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaReader::readLineGR8(char *buffer, int x0, int x1, int shrink) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *row = (TPixel32 *)buffer;
|
|
Shinya Kitaoka |
120a6e |
int w = x1 - x0 + 1;
|
|
Shinya Kitaoka |
120a6e |
while (w--) {
|
|
Shinya Kitaoka |
120a6e |
row->r = row->g = row->b = fgetc(m_chan);
|
|
Shinya Kitaoka |
120a6e |
row->m = 0xff;
|
|
Shinya Kitaoka |
120a6e |
++row;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaReader::readLineGR8rle(char *buffer, int x0, int x1, int shrink) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *row = (TPixel32 *)buffer;
|
|
Shinya Kitaoka |
120a6e |
UCHAR count, byte;
|
|
Shinya Kitaoka |
120a6e |
int nx, x, i;
|
|
Shinya Kitaoka |
120a6e |
int width = x1 - x0 + 1;
|
|
Shinya Kitaoka |
120a6e |
for (nx = 0; nx < width;) {
|
|
Shinya Kitaoka |
120a6e |
count = fgetc(m_chan);
|
|
Shinya Kitaoka |
120a6e |
if ((count >> 7) & 0x01) {
|
|
Shinya Kitaoka |
120a6e |
count -= 127;
|
|
Shinya Kitaoka |
120a6e |
byte = fgetc(m_chan);
|
|
Shinya Kitaoka |
120a6e |
for (x = 0; x < count; x++) {
|
|
Shinya Kitaoka |
120a6e |
row->r = row->g = row->b = byte;
|
|
Shinya Kitaoka |
120a6e |
row->m = 0xff;
|
|
Shinya Kitaoka |
120a6e |
++row;
|
|
Shinya Kitaoka |
120a6e |
nx++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < count + 1; i++) {
|
|
Shinya Kitaoka |
120a6e |
byte = fgetc(m_chan);
|
|
Shinya Kitaoka |
120a6e |
row->r = row->g = row->b = byte;
|
|
Shinya Kitaoka |
120a6e |
row->m = 0xff;
|
|
Shinya Kitaoka |
120a6e |
++row;
|
|
Shinya Kitaoka |
120a6e |
nx++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (nx != width) fprintf(stderr, "tga read error: decode failed\n");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaReader::readLineCmappedRle(char *buffer, int x0, int x1, int shrink) {
|
|
Shinya Kitaoka |
120a6e |
int x = 0;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *row = (TPixel32 *)buffer;
|
|
Shinya Kitaoka |
120a6e |
while (x < m_info.m_lx) {
|
|
Shinya Kitaoka |
120a6e |
UCHAR h = fgetc(m_chan);
|
|
Shinya Kitaoka |
120a6e |
int count = (h & 0x7F) + 1;
|
|
Shinya Kitaoka |
120a6e |
if (h & 0x80) {
|
|
Shinya Kitaoka |
120a6e |
int index = fgetc(m_chan);
|
|
Shinya Kitaoka |
120a6e |
TPixel32 pix = m_palette[index];
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < count && x < m_info.m_lx; i++) row[x++] = pix;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < count && x < m_info.m_lx; i++) {
|
|
Shinya Kitaoka |
120a6e |
int index = fgetc(m_chan);
|
|
Shinya Kitaoka |
120a6e |
row[x++] = m_palette[index];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Tiio::TgaWriterProperties::TgaWriterProperties()
|
|
Shinya Kitaoka |
120a6e |
: m_pixelSize("Bits Per Pixel"), m_compressed("Compression", true) {
|
|
Shinya Kitaoka |
120a6e |
m_pixelSize.addValue(L"16 bits");
|
|
Shinya Kitaoka |
120a6e |
m_pixelSize.addValue(L"24 bits");
|
|
Shinya Kitaoka |
120a6e |
m_pixelSize.addValue(L"32 bits");
|
|
Shinya Kitaoka |
120a6e |
m_pixelSize.setValue(L"24 bits");
|
|
Shinya Kitaoka |
120a6e |
bind(m_pixelSize);
|
|
Shinya Kitaoka |
120a6e |
bind(m_compressed);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
e87e08 |
void Tiio::TgaWriterProperties::updateTranslation() {
|
|
shun-iwasawa |
e87e08 |
m_pixelSize.setQStringName(tr("Bits Per Pixel"));
|
|
shun-iwasawa |
e87e08 |
m_pixelSize.setItemUIName(L"16 bits", tr("16 bits"));
|
|
shun-iwasawa |
e87e08 |
m_pixelSize.setItemUIName(L"24 bits", tr("24 bits"));
|
|
shun-iwasawa |
e87e08 |
m_pixelSize.setItemUIName(L"32 bits", tr("32 bits"));
|
|
shun-iwasawa |
e87e08 |
m_compressed.setQStringName(tr("Compression"));
|
|
shun-iwasawa |
e87e08 |
}
|
|
shun-iwasawa |
e87e08 |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class TgaWriter final : public Tiio::Writer {
|
|
Shinya Kitaoka |
120a6e |
FILE *m_chan;
|
|
Shinya Kitaoka |
120a6e |
TgaHeader m_header;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
typedef void (TgaWriter::*WriteLineProc)(char *buffer);
|
|
Shinya Kitaoka |
120a6e |
WriteLineProc m_writeLineProc;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TgaWriter() : m_chan(0), m_writeLineProc(&TgaWriter::writeNoLine) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void open(FILE *file, const TImageInfo &info) override {
|
|
Shinya Kitaoka |
120a6e |
m_info = info;
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
m_chan = file;
|
|
Shinya Kitaoka |
120a6e |
} catch (...) {
|
|
Shinya Kitaoka |
120a6e |
perror("uffa");
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (!m_properties) m_properties = new Tiio::TgaWriterProperties();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool compressed =
|
|
Shinya Kitaoka |
120a6e |
((TBoolProperty *)(m_properties->getProperty("Compression")))
|
|
Shinya Kitaoka |
120a6e |
->getValue();
|
|
Shinya Kitaoka |
120a6e |
memset(&m_header, 0, sizeof(m_header));
|
|
Shinya Kitaoka |
120a6e |
m_header.ImageTypeCode = compressed ? 10 : 2;
|
|
Shinya Kitaoka |
120a6e |
m_header.Width = m_info.m_lx;
|
|
Shinya Kitaoka |
120a6e |
m_header.Height = m_info.m_ly;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::wstring pixelSizeW =
|
|
Shinya Kitaoka |
120a6e |
((TEnumProperty *)(m_properties->getProperty("Bits Per Pixel")))
|
|
Shinya Kitaoka |
120a6e |
->getValue()
|
|
Shinya Kitaoka |
120a6e |
.substr(0, 2);
|
|
Shinya Kitaoka |
120a6e |
if (pixelSizeW == L"16") {
|
|
Shinya Kitaoka |
120a6e |
m_header.ImagePixelSize = 16;
|
|
Shinya Kitaoka |
120a6e |
m_writeLineProc =
|
|
Shinya Kitaoka |
120a6e |
compressed ? &TgaWriter::writeLine16rle : &TgaWriter::writeLine16;
|
|
Shinya Kitaoka |
120a6e |
} else if (pixelSizeW == L"24") {
|
|
Shinya Kitaoka |
120a6e |
m_header.ImagePixelSize = 24;
|
|
Shinya Kitaoka |
120a6e |
m_writeLineProc =
|
|
Shinya Kitaoka |
120a6e |
compressed ? &TgaWriter::writeLine24rle : &TgaWriter::writeLine24;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
m_header.ImagePixelSize = 32;
|
|
Shinya Kitaoka |
120a6e |
m_writeLineProc =
|
|
Shinya Kitaoka |
120a6e |
compressed ? &TgaWriter::writeLine32rle : &TgaWriter::writeLine32;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
writeTgaHeader(m_header, m_chan);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void flush() override { fflush(m_chan); }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
~TgaWriter() { delete m_properties; }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inline void fputPixel32(const TPixel32 &pix, FILE *chan) {
|
|
Shinya Kitaoka |
120a6e |
fputc(pix.b, m_chan);
|
|
Shinya Kitaoka |
120a6e |
fputc(pix.g, m_chan);
|
|
Shinya Kitaoka |
120a6e |
fputc(pix.r, m_chan);
|
|
Shinya Kitaoka |
120a6e |
fputc(pix.m, m_chan);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
inline void fputPixel24(const TPixel32 &pix, FILE *chan) {
|
|
Shinya Kitaoka |
120a6e |
fputc(pix.b, m_chan);
|
|
Shinya Kitaoka |
120a6e |
fputc(pix.g, m_chan);
|
|
Shinya Kitaoka |
120a6e |
fputc(pix.r, m_chan);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
inline void fputPixel16(const TPixel32 &pix, FILE *chan) {
|
|
Shinya Kitaoka |
120a6e |
unsigned short word;
|
|
Shinya Kitaoka |
120a6e |
word = (pix.r >> 3) << 10 | (pix.g >> 3) << 5 | (pix.b >> 3);
|
|
Shinya Kitaoka |
120a6e |
fputc(word & 0xFF, m_chan);
|
|
Shinya Kitaoka |
120a6e |
fputc((word >> 8) & 0xFF, m_chan);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void writeNoLine(char *buffer) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void writeLine16(char *buffer);
|
|
Shinya Kitaoka |
120a6e |
void writeLine24(char *buffer);
|
|
Shinya Kitaoka |
120a6e |
void writeLine32(char *buffer);
|
|
Shinya Kitaoka |
120a6e |
void writeLine16rle(char *buffer);
|
|
Shinya Kitaoka |
120a6e |
void writeLine24rle(char *buffer);
|
|
Shinya Kitaoka |
120a6e |
void writeLine32rle(char *buffer);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void writeLine(char *buffer) override { (this->*m_writeLineProc)(buffer); }
|
|
shun-iwasawa |
93fdd4 |
|
|
shun-iwasawa |
93fdd4 |
// m_header.ImagePixelSize is set to "Bits Per Pixel" property value
|
|
shun-iwasawa |
93fdd4 |
// in the function open()
|
|
shun-iwasawa |
93fdd4 |
bool writeAlphaSupported() const override {
|
|
shun-iwasawa |
93fdd4 |
return m_header.ImagePixelSize == 32;
|
|
shun-iwasawa |
93fdd4 |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaWriter::writeLine32rle(char *buffer) {
|
|
Shinya Kitaoka |
120a6e |
int x = 0;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *row = (TPixel32 *)buffer;
|
|
Shinya Kitaoka |
120a6e |
while (x < m_info.m_lx) {
|
|
Shinya Kitaoka |
120a6e |
if (x + 1 < m_info.m_lx && row[x] == row[x + 1]) {
|
|
Shinya Kitaoka |
120a6e |
int count = 2;
|
|
Shinya Kitaoka |
120a6e |
int max = std::min(128, m_info.m_lx - x);
|
|
Shinya Kitaoka |
120a6e |
while (count < max && row[x + count - 1] == row[x + count]) count++;
|
|
Shinya Kitaoka |
120a6e |
fputc((count - 1) | 0x80, m_chan);
|
|
Shinya Kitaoka |
120a6e |
fputPixel32(row[x], m_chan);
|
|
Shinya Kitaoka |
120a6e |
x += count;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
int count = 1;
|
|
Shinya Kitaoka |
120a6e |
int max = std::min(128, m_info.m_lx - x);
|
|
Shinya Kitaoka |
120a6e |
while (count < max && row[x + count - 1] != row[x + count]) count++;
|
|
Shinya Kitaoka |
120a6e |
fputc(count - 1, m_chan);
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < count; i++) fputPixel32(row[x++], m_chan);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaWriter::writeLine24rle(char *buffer) {
|
|
Shinya Kitaoka |
120a6e |
int x = 0;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *row = (TPixel32 *)buffer;
|
|
Shinya Kitaoka |
120a6e |
while (x < m_info.m_lx) {
|
|
Shinya Kitaoka |
120a6e |
if (x + 1 < m_info.m_lx && row[x] == row[x + 1]) {
|
|
Shinya Kitaoka |
120a6e |
int count = 2;
|
|
Shinya Kitaoka |
120a6e |
int max = std::min(128, m_info.m_lx - x);
|
|
Shinya Kitaoka |
120a6e |
while (count < max && row[x + count - 1] == row[x + count]) count++;
|
|
Shinya Kitaoka |
120a6e |
fputc((count - 1) | 0x80, m_chan);
|
|
Shinya Kitaoka |
120a6e |
fputPixel24(row[x], m_chan);
|
|
Shinya Kitaoka |
120a6e |
x += count;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
int count = 1;
|
|
Shinya Kitaoka |
120a6e |
int max = std::min(128, m_info.m_lx - x);
|
|
Shinya Kitaoka |
120a6e |
while (count < max && row[x + count - 1] != row[x + count]) count++;
|
|
Shinya Kitaoka |
120a6e |
fputc(count - 1, m_chan);
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < count; i++) fputPixel24(row[x++], m_chan);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaWriter::writeLine16rle(char *buffer) {
|
|
Shinya Kitaoka |
120a6e |
int x = 0;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *row = (TPixel32 *)buffer;
|
|
Shinya Kitaoka |
120a6e |
while (x < m_info.m_lx) {
|
|
Shinya Kitaoka |
120a6e |
if (x + 1 < m_info.m_lx && row[x] == row[x + 1]) {
|
|
Shinya Kitaoka |
120a6e |
int count = 2;
|
|
Shinya Kitaoka |
120a6e |
int max = std::min(128, m_info.m_lx - x);
|
|
Shinya Kitaoka |
120a6e |
while (count < max && row[x + count - 1] == row[x + count]) count++;
|
|
Shinya Kitaoka |
120a6e |
fputc((count - 1) | 0x80, m_chan);
|
|
Shinya Kitaoka |
120a6e |
fputPixel16(row[x], m_chan);
|
|
Shinya Kitaoka |
120a6e |
x += count;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
int count = 1;
|
|
Shinya Kitaoka |
120a6e |
int max = std::min(128, m_info.m_lx - x);
|
|
Shinya Kitaoka |
120a6e |
while (count < max && row[x + count - 1] != row[x + count]) count++;
|
|
Shinya Kitaoka |
120a6e |
fputc(count - 1, m_chan);
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < count; i++) fputPixel16(row[x++], m_chan);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaWriter::writeLine32(char *buffer) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *pix = (TPixel32 *)buffer;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *endPix = pix + m_info.m_lx;
|
|
Shinya Kitaoka |
120a6e |
while (pix < endPix) fputPixel32(*pix++, m_chan);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaWriter::writeLine24(char *buffer) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *pix = (TPixel32 *)buffer;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *endPix = pix + m_info.m_lx;
|
|
Shinya Kitaoka |
120a6e |
while (pix < endPix) fputPixel24(*pix++, m_chan);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TgaWriter::writeLine16(char *buffer) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *pix = (TPixel32 *)buffer;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *endPix = pix + m_info.m_lx;
|
|
Shinya Kitaoka |
120a6e |
while (pix < endPix) fputPixel16(*pix++, m_chan);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Tiio::Reader *Tiio::makeTgaReader() { return new TgaReader(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Tiio::Writer *Tiio::makeTgaWriter() { return new TgaWriter(); }
|