mirror of
https://invent.kde.org/frameworks/kimageformats.git
synced 2026-02-13 21:43:02 -05:00
Code reformatted using kde-dev-scripts/astyle-kdelibs.
Use git blame -w 47df948 to show authorship as it was before this commit.
This commit is contained in:
@ -79,7 +79,6 @@ union Color4444 {
|
|||||||
ushort u;
|
ushort u;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' ');
|
static const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' ');
|
||||||
static const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1');
|
static const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1');
|
||||||
static const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2');
|
static const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2');
|
||||||
@ -126,7 +125,6 @@ enum DDSType {
|
|||||||
DDS_UNKNOWN
|
DDS_UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct DDSPixelFormat {
|
struct DDSPixelFormat {
|
||||||
uint size;
|
uint size;
|
||||||
uint flags;
|
uint flags;
|
||||||
@ -138,7 +136,7 @@ struct DDSPixelFormat {
|
|||||||
uint amask;
|
uint amask;
|
||||||
};
|
};
|
||||||
|
|
||||||
static QDataStream & operator>> (QDataStream & s, DDSPixelFormat & pf)
|
static QDataStream &operator>> (QDataStream &s, DDSPixelFormat &pf)
|
||||||
{
|
{
|
||||||
s >> pf.size;
|
s >> pf.size;
|
||||||
s >> pf.flags;
|
s >> pf.flags;
|
||||||
@ -158,7 +156,7 @@ struct DDSCaps {
|
|||||||
uint caps4;
|
uint caps4;
|
||||||
};
|
};
|
||||||
|
|
||||||
static QDataStream & operator>> (QDataStream & s, DDSCaps & caps)
|
static QDataStream &operator>> (QDataStream &s, DDSCaps &caps)
|
||||||
{
|
{
|
||||||
s >> caps.caps1;
|
s >> caps.caps1;
|
||||||
s >> caps.caps2;
|
s >> caps.caps2;
|
||||||
@ -181,7 +179,7 @@ struct DDSHeader {
|
|||||||
uint notused;
|
uint notused;
|
||||||
};
|
};
|
||||||
|
|
||||||
static QDataStream & operator>> (QDataStream & s, DDSHeader & header)
|
static QDataStream &operator>> (QDataStream &s, DDSHeader &header)
|
||||||
{
|
{
|
||||||
s >> header.size;
|
s >> header.size;
|
||||||
s >> header.flags;
|
s >> header.flags;
|
||||||
@ -199,7 +197,7 @@ static QDataStream & operator>> (QDataStream & s, DDSHeader & header)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsValid(const DDSHeader & header)
|
static bool IsValid(const DDSHeader &header)
|
||||||
{
|
{
|
||||||
if (header.size != 124) {
|
if (header.size != 124) {
|
||||||
return false;
|
return false;
|
||||||
@ -217,9 +215,8 @@ static bool IsValid(const DDSHeader & header)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Get supported type. We currently support 10 different types.
|
// Get supported type. We currently support 10 different types.
|
||||||
static DDSType GetType(const DDSHeader & header)
|
static DDSType GetType(const DDSHeader &header)
|
||||||
{
|
{
|
||||||
if (header.pf.flags & DDPF_RGB) {
|
if (header.pf.flags & DDPF_RGB) {
|
||||||
if (header.pf.flags & DDPF_ALPHAPIXELS) {
|
if (header.pf.flags & DDPF_ALPHAPIXELS) {
|
||||||
@ -258,17 +255,17 @@ static DDSType GetType(const DDSHeader & header)
|
|||||||
return DDS_UNKNOWN;
|
return DDS_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool HasAlpha(const DDSHeader & header)
|
static bool HasAlpha(const DDSHeader &header)
|
||||||
{
|
{
|
||||||
return header.pf.flags & DDPF_ALPHAPIXELS;
|
return header.pf.flags & DDPF_ALPHAPIXELS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsCubeMap(const DDSHeader & header)
|
static bool IsCubeMap(const DDSHeader &header)
|
||||||
{
|
{
|
||||||
return header.caps.caps2 & DDSCAPS2_CUBEMAP;
|
return header.caps.caps2 & DDSCAPS2_CUBEMAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsSupported(const DDSHeader & header)
|
static bool IsSupported(const DDSHeader &header)
|
||||||
{
|
{
|
||||||
if (header.caps.caps2 & DDSCAPS2_VOLUME) {
|
if (header.caps.caps2 & DDSCAPS2_VOLUME) {
|
||||||
return false;
|
return false;
|
||||||
@ -279,13 +276,13 @@ static bool IsSupported(const DDSHeader & header)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LoadA8R8G8B8(QDataStream & s, const DDSHeader & header, QImage & img)
|
static bool LoadA8R8G8B8(QDataStream &s, const DDSHeader &header, QImage &img)
|
||||||
{
|
{
|
||||||
const uint w = header.width;
|
const uint w = header.width;
|
||||||
const uint h = header.height;
|
const uint h = header.height;
|
||||||
|
|
||||||
for (uint y = 0; y < h; y++) {
|
for (uint y = 0; y < h; y++) {
|
||||||
QRgb * scanline = (QRgb *) img.scanLine(y);
|
QRgb *scanline = (QRgb *) img.scanLine(y);
|
||||||
for (uint x = 0; x < w; x++) {
|
for (uint x = 0; x < w; x++) {
|
||||||
uchar r, g, b, a;
|
uchar r, g, b, a;
|
||||||
s >> b >> g >> r >> a;
|
s >> b >> g >> r >> a;
|
||||||
@ -296,13 +293,13 @@ static bool LoadA8R8G8B8(QDataStream & s, const DDSHeader & header, QImage & img
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LoadR8G8B8(QDataStream & s, const DDSHeader & header, QImage & img)
|
static bool LoadR8G8B8(QDataStream &s, const DDSHeader &header, QImage &img)
|
||||||
{
|
{
|
||||||
const uint w = header.width;
|
const uint w = header.width;
|
||||||
const uint h = header.height;
|
const uint h = header.height;
|
||||||
|
|
||||||
for (uint y = 0; y < h; y++) {
|
for (uint y = 0; y < h; y++) {
|
||||||
QRgb * scanline = (QRgb *) img.scanLine(y);
|
QRgb *scanline = (QRgb *) img.scanLine(y);
|
||||||
for (uint x = 0; x < w; x++) {
|
for (uint x = 0; x < w; x++) {
|
||||||
uchar r, g, b;
|
uchar r, g, b;
|
||||||
s >> b >> g >> r;
|
s >> b >> g >> r;
|
||||||
@ -313,13 +310,13 @@ static bool LoadR8G8B8(QDataStream & s, const DDSHeader & header, QImage & img)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LoadA1R5G5B5(QDataStream & s, const DDSHeader & header, QImage & img)
|
static bool LoadA1R5G5B5(QDataStream &s, const DDSHeader &header, QImage &img)
|
||||||
{
|
{
|
||||||
const uint w = header.width;
|
const uint w = header.width;
|
||||||
const uint h = header.height;
|
const uint h = header.height;
|
||||||
|
|
||||||
for (uint y = 0; y < h; y++) {
|
for (uint y = 0; y < h; y++) {
|
||||||
QRgb * scanline = (QRgb *) img.scanLine(y);
|
QRgb *scanline = (QRgb *) img.scanLine(y);
|
||||||
for (uint x = 0; x < w; x++) {
|
for (uint x = 0; x < w; x++) {
|
||||||
Color1555 color;
|
Color1555 color;
|
||||||
s >> color.u;
|
s >> color.u;
|
||||||
@ -334,13 +331,13 @@ static bool LoadA1R5G5B5(QDataStream & s, const DDSHeader & header, QImage & img
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LoadA4R4G4B4(QDataStream & s, const DDSHeader & header, QImage & img)
|
static bool LoadA4R4G4B4(QDataStream &s, const DDSHeader &header, QImage &img)
|
||||||
{
|
{
|
||||||
const uint w = header.width;
|
const uint w = header.width;
|
||||||
const uint h = header.height;
|
const uint h = header.height;
|
||||||
|
|
||||||
for (uint y = 0; y < h; y++) {
|
for (uint y = 0; y < h; y++) {
|
||||||
QRgb * scanline = (QRgb *) img.scanLine(y);
|
QRgb *scanline = (QRgb *) img.scanLine(y);
|
||||||
for (uint x = 0; x < w; x++) {
|
for (uint x = 0; x < w; x++) {
|
||||||
Color4444 color;
|
Color4444 color;
|
||||||
s >> color.u;
|
s >> color.u;
|
||||||
@ -355,13 +352,13 @@ static bool LoadA4R4G4B4(QDataStream & s, const DDSHeader & header, QImage & img
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LoadR5G6B5(QDataStream & s, const DDSHeader & header, QImage & img)
|
static bool LoadR5G6B5(QDataStream &s, const DDSHeader &header, QImage &img)
|
||||||
{
|
{
|
||||||
const uint w = header.width;
|
const uint w = header.width;
|
||||||
const uint h = header.height;
|
const uint h = header.height;
|
||||||
|
|
||||||
for (uint y = 0; y < h; y++) {
|
for (uint y = 0; y < h; y++) {
|
||||||
QRgb * scanline = (QRgb *) img.scanLine(y);
|
QRgb *scanline = (QRgb *) img.scanLine(y);
|
||||||
for (uint x = 0; x < w; x++) {
|
for (uint x = 0; x < w; x++) {
|
||||||
Color565 color;
|
Color565 color;
|
||||||
s >> color.u;
|
s >> color.u;
|
||||||
@ -375,18 +372,18 @@ static bool LoadR5G6B5(QDataStream & s, const DDSHeader & header, QImage & img)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QDataStream & operator>> (QDataStream & s, Color565 & c)
|
static QDataStream &operator>> (QDataStream &s, Color565 &c)
|
||||||
{
|
{
|
||||||
return s >> c.u;
|
return s >> c.u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct BlockDXT {
|
struct BlockDXT {
|
||||||
Color565 col0;
|
Color565 col0;
|
||||||
Color565 col1;
|
Color565 col1;
|
||||||
uchar row[4];
|
uchar row[4];
|
||||||
|
|
||||||
void GetColors(Color8888 color_array[4]) {
|
void GetColors(Color8888 color_array[4])
|
||||||
|
{
|
||||||
color_array[0].r = (col0.c.r << 3) | (col0.c.r >> 2);
|
color_array[0].r = (col0.c.r << 3) | (col0.c.r >> 2);
|
||||||
color_array[0].g = (col0.c.g << 2) | (col0.c.g >> 4);
|
color_array[0].g = (col0.c.g << 2) | (col0.c.g >> 4);
|
||||||
color_array[0].b = (col0.c.b << 3) | (col0.c.b >> 2);
|
color_array[0].b = (col0.c.b << 3) | (col0.c.b >> 2);
|
||||||
@ -424,8 +421,7 @@ struct BlockDXT {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static QDataStream &operator>> (QDataStream &s, BlockDXT &c)
|
||||||
static QDataStream & operator>> (QDataStream & s, BlockDXT & c)
|
|
||||||
{
|
{
|
||||||
return s >> c.col0 >> c.col1 >> c.row[0] >> c.row[1] >> c.row[2] >> c.row[3];
|
return s >> c.col0 >> c.col1 >> c.row[0] >> c.row[1] >> c.row[2] >> c.row[3];
|
||||||
}
|
}
|
||||||
@ -434,7 +430,7 @@ struct BlockDXTAlphaExplicit {
|
|||||||
ushort row[4];
|
ushort row[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
static QDataStream & operator>> (QDataStream & s, BlockDXTAlphaExplicit & c)
|
static QDataStream &operator>> (QDataStream &s, BlockDXTAlphaExplicit &c)
|
||||||
{
|
{
|
||||||
return s >> c.row[0] >> c.row[1] >> c.row[2] >> c.row[3];
|
return s >> c.row[0] >> c.row[1] >> c.row[2] >> c.row[3];
|
||||||
}
|
}
|
||||||
@ -444,7 +440,8 @@ struct BlockDXTAlphaLinear {
|
|||||||
uchar alpha1;
|
uchar alpha1;
|
||||||
uchar bits[6];
|
uchar bits[6];
|
||||||
|
|
||||||
void GetAlphas(uchar alpha_array[8]) {
|
void GetAlphas(uchar alpha_array[8])
|
||||||
|
{
|
||||||
alpha_array[0] = alpha0;
|
alpha_array[0] = alpha0;
|
||||||
alpha_array[1] = alpha1;
|
alpha_array[1] = alpha1;
|
||||||
|
|
||||||
@ -472,7 +469,8 @@ struct BlockDXTAlphaLinear {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetBits(uchar bit_array[16]) {
|
void GetBits(uchar bit_array[16])
|
||||||
|
{
|
||||||
// Split 24 packed bits into 8 bytes, 3 bits at a time.
|
// Split 24 packed bits into 8 bytes, 3 bits at a time.
|
||||||
uint b = bits[0] | bits[1] << 8 | bits[2] << 16;
|
uint b = bits[0] | bits[1] << 8 | bits[2] << 16;
|
||||||
bit_array[0] = uchar(b & 0x07); b >>= 3;
|
bit_array[0] = uchar(b & 0x07); b >>= 3;
|
||||||
@ -496,19 +494,19 @@ struct BlockDXTAlphaLinear {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static QDataStream & operator>> (QDataStream & s, BlockDXTAlphaLinear & c)
|
static QDataStream &operator>> (QDataStream &s, BlockDXTAlphaLinear &c)
|
||||||
{
|
{
|
||||||
s >> c.alpha0 >> c.alpha1;
|
s >> c.alpha0 >> c.alpha1;
|
||||||
return s >> c.bits[0] >> c.bits[1] >> c.bits[2] >> c.bits[3] >> c.bits[4] >> c.bits[5];
|
return s >> c.bits[0] >> c.bits[1] >> c.bits[2] >> c.bits[3] >> c.bits[4] >> c.bits[5];
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LoadDXT1(QDataStream & s, const DDSHeader & header, QImage & img)
|
static bool LoadDXT1(QDataStream &s, const DDSHeader &header, QImage &img)
|
||||||
{
|
{
|
||||||
const uint w = header.width;
|
const uint w = header.width;
|
||||||
const uint h = header.height;
|
const uint h = header.height;
|
||||||
|
|
||||||
BlockDXT block;
|
BlockDXT block;
|
||||||
QRgb * scanline[4];
|
QRgb *scanline[4];
|
||||||
|
|
||||||
for (uint y = 0; y < h; y += 4) {
|
for (uint y = 0; y < h; y += 4) {
|
||||||
for (uint j = 0; j < 4; j++) {
|
for (uint j = 0; j < 4; j++) {
|
||||||
@ -541,14 +539,14 @@ static bool LoadDXT1(QDataStream & s, const DDSHeader & header, QImage & img)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LoadDXT3(QDataStream & s, const DDSHeader & header, QImage & img)
|
static bool LoadDXT3(QDataStream &s, const DDSHeader &header, QImage &img)
|
||||||
{
|
{
|
||||||
const uint w = header.width;
|
const uint w = header.width;
|
||||||
const uint h = header.height;
|
const uint h = header.height;
|
||||||
|
|
||||||
BlockDXT block;
|
BlockDXT block;
|
||||||
BlockDXTAlphaExplicit alpha;
|
BlockDXTAlphaExplicit alpha;
|
||||||
QRgb * scanline[4];
|
QRgb *scanline[4];
|
||||||
|
|
||||||
for (uint y = 0; y < h; y += 4) {
|
for (uint y = 0; y < h; y += 4) {
|
||||||
for (uint j = 0; j < 4; j++) {
|
for (uint j = 0; j < 4; j++) {
|
||||||
@ -586,21 +584,23 @@ static bool LoadDXT3(QDataStream & s, const DDSHeader & header, QImage & img)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LoadDXT2(QDataStream & s, const DDSHeader & header, QImage & img)
|
static bool LoadDXT2(QDataStream &s, const DDSHeader &header, QImage &img)
|
||||||
{
|
{
|
||||||
if (!LoadDXT3(s, header, img)) return false;
|
if (!LoadDXT3(s, header, img)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
//UndoPremultiplyAlpha(img);
|
//UndoPremultiplyAlpha(img);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LoadDXT5(QDataStream & s, const DDSHeader & header, QImage & img)
|
static bool LoadDXT5(QDataStream &s, const DDSHeader &header, QImage &img)
|
||||||
{
|
{
|
||||||
const uint w = header.width;
|
const uint w = header.width;
|
||||||
const uint h = header.height;
|
const uint h = header.height;
|
||||||
|
|
||||||
BlockDXT block;
|
BlockDXT block;
|
||||||
BlockDXTAlphaLinear alpha;
|
BlockDXTAlphaLinear alpha;
|
||||||
QRgb * scanline[4];
|
QRgb *scanline[4];
|
||||||
|
|
||||||
for (uint y = 0; y < h; y += 4) {
|
for (uint y = 0; y < h; y += 4) {
|
||||||
for (uint j = 0; j < 4; j++) {
|
for (uint j = 0; j < 4; j++) {
|
||||||
@ -641,21 +641,23 @@ static bool LoadDXT5(QDataStream & s, const DDSHeader & header, QImage & img)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
static bool LoadDXT4(QDataStream & s, const DDSHeader & header, QImage & img)
|
static bool LoadDXT4(QDataStream &s, const DDSHeader &header, QImage &img)
|
||||||
{
|
{
|
||||||
if (!LoadDXT5(s, header, img)) return false;
|
if (!LoadDXT5(s, header, img)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
//UndoPremultiplyAlpha(img);
|
//UndoPremultiplyAlpha(img);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LoadRXGB(QDataStream & s, const DDSHeader & header, QImage & img)
|
static bool LoadRXGB(QDataStream &s, const DDSHeader &header, QImage &img)
|
||||||
{
|
{
|
||||||
const uint w = header.width;
|
const uint w = header.width;
|
||||||
const uint h = header.height;
|
const uint h = header.height;
|
||||||
|
|
||||||
BlockDXT block;
|
BlockDXT block;
|
||||||
BlockDXTAlphaLinear alpha;
|
BlockDXTAlphaLinear alpha;
|
||||||
QRgb * scanline[4];
|
QRgb *scanline[4];
|
||||||
|
|
||||||
for (uint y = 0; y < h; y += 4) {
|
for (uint y = 0; y < h; y += 4) {
|
||||||
for (uint j = 0; j < 4; j++) {
|
for (uint j = 0; j < 4; j++) {
|
||||||
@ -697,14 +699,14 @@ static bool LoadRXGB(QDataStream & s, const DDSHeader & header, QImage & img)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LoadATI2(QDataStream & s, const DDSHeader & header, QImage & img)
|
static bool LoadATI2(QDataStream &s, const DDSHeader &header, QImage &img)
|
||||||
{
|
{
|
||||||
const uint w = header.width;
|
const uint w = header.width;
|
||||||
const uint h = header.height;
|
const uint h = header.height;
|
||||||
|
|
||||||
BlockDXTAlphaLinear xblock;
|
BlockDXTAlphaLinear xblock;
|
||||||
BlockDXTAlphaLinear yblock;
|
BlockDXTAlphaLinear yblock;
|
||||||
QRgb * scanline[4];
|
QRgb *scanline[4];
|
||||||
|
|
||||||
for (uint y = 0; y < h; y += 4) {
|
for (uint y = 0; y < h; y += 4) {
|
||||||
for (uint j = 0; j < 4; j++) {
|
for (uint j = 0; j < 4; j++) {
|
||||||
@ -751,9 +753,7 @@ static bool LoadATI2(QDataStream & s, const DDSHeader & header, QImage & img)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef bool (* TextureLoader)(QDataStream &s, const DDSHeader &header, QImage &img);
|
||||||
|
|
||||||
typedef bool (* TextureLoader)(QDataStream & s, const DDSHeader & header, QImage & img);
|
|
||||||
|
|
||||||
// Get an appropriate texture loader for the given type.
|
// Get an appropriate texture loader for the given type.
|
||||||
static TextureLoader GetTextureLoader(DDSType type)
|
static TextureLoader GetTextureLoader(DDSType type)
|
||||||
@ -788,9 +788,8 @@ static TextureLoader GetTextureLoader(DDSType type)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Load a 2d texture.
|
// Load a 2d texture.
|
||||||
static bool LoadTexture(QDataStream & s, const DDSHeader & header, QImage & img)
|
static bool LoadTexture(QDataStream &s, const DDSHeader &header, QImage &img)
|
||||||
{
|
{
|
||||||
// Create dst image.
|
// Create dst image.
|
||||||
img = QImage(header.width, header.height, QImage::Format_RGB32);
|
img = QImage(header.width, header.height, QImage::Format_RGB32);
|
||||||
@ -811,8 +810,7 @@ static bool LoadTexture(QDataStream & s, const DDSHeader & header, QImage & img)
|
|||||||
return loader(s, header, img);
|
return loader(s, header, img);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int FaceOffset(const DDSHeader &header)
|
||||||
static int FaceOffset(const DDSHeader & header)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
DDSType type = GetType(header);
|
DDSType type = GetType(header);
|
||||||
@ -858,7 +856,7 @@ static int face_flags[6] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Load unwrapped cube map.
|
// Load unwrapped cube map.
|
||||||
static bool LoadCubeMap(QDataStream & s, const DDSHeader & header, QImage & img)
|
static bool LoadCubeMap(QDataStream &s, const DDSHeader &header, QImage &img)
|
||||||
{
|
{
|
||||||
// Create dst image.
|
// Create dst image.
|
||||||
#if CUBE_LAYOUT == HORIZONTAL
|
#if CUBE_LAYOUT == HORIZONTAL
|
||||||
@ -917,8 +915,8 @@ static bool LoadCubeMap(QDataStream & s, const DDSHeader & header, QImage & img)
|
|||||||
|
|
||||||
// Copy face on the image.
|
// Copy face on the image.
|
||||||
for (uint y = 0; y < header.height; y++) {
|
for (uint y = 0; y < header.height; y++) {
|
||||||
QRgb * src = (QRgb *) face.scanLine(y);
|
QRgb *src = (QRgb *) face.scanLine(y);
|
||||||
QRgb * dst = (QRgb *) img.scanLine(y + offset_y) + offset_x;
|
QRgb *dst = (QRgb *) img.scanLine(y + offset_y) + offset_x;
|
||||||
memcpy(dst, src, sizeof(QRgb) * header.width);
|
memcpy(dst, src, sizeof(QRgb) * header.width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -926,8 +924,6 @@ static bool LoadCubeMap(QDataStream & s, const DDSHeader & header, QImage & img)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DDSHandler::DDSHandler()
|
DDSHandler::DDSHandler()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -994,8 +990,9 @@ bool DDSHandler::canRead(QIODevice *device)
|
|||||||
qint64 readBytes = device->read(head, sizeof(head));
|
qint64 readBytes = device->read(head, sizeof(head));
|
||||||
if (readBytes != sizeof(head)) {
|
if (readBytes != sizeof(head)) {
|
||||||
if (device->isSequential()) {
|
if (device->isSequential()) {
|
||||||
while (readBytes > 0)
|
while (readBytes > 0) {
|
||||||
device->ungetChar(head[readBytes-- - 1]);
|
device->ungetChar(head[readBytes-- - 1]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
device->seek(oldPos);
|
device->seek(oldPos);
|
||||||
}
|
}
|
||||||
@ -1003,8 +1000,9 @@ bool DDSHandler::canRead(QIODevice *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (device->isSequential()) {
|
if (device->isSequential()) {
|
||||||
while (readBytes > 0)
|
while (readBytes > 0) {
|
||||||
device->ungetChar(head[readBytes-- - 1]);
|
device->ungetChar(head[readBytes-- - 1]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
device->seek(oldPos);
|
device->seek(oldPos);
|
||||||
}
|
}
|
||||||
@ -1014,16 +1012,20 @@ bool DDSHandler::canRead(QIODevice *device)
|
|||||||
|
|
||||||
QImageIOPlugin::Capabilities DDSPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
QImageIOPlugin::Capabilities DDSPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
||||||
{
|
{
|
||||||
if (format == "dds")
|
if (format == "dds") {
|
||||||
return Capabilities(CanRead);
|
return Capabilities(CanRead);
|
||||||
if (!format.isEmpty())
|
}
|
||||||
|
if (!format.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
if (!device->isOpen())
|
}
|
||||||
|
if (!device->isOpen()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Capabilities cap;
|
Capabilities cap;
|
||||||
if (device->isReadable() && DDSHandler::canRead(device))
|
if (device->isReadable() && DDSHandler::canRead(device)) {
|
||||||
cap |= CanRead;
|
cap |= CanRead;
|
||||||
|
}
|
||||||
return cap;
|
return cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -49,7 +49,7 @@ static bool seekToCodeStart(QIODevice *io, qint64 &ps_offset, qint64 &ps_size)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ps_offset // Offset is in little endian
|
ps_offset // Offset is in little endian
|
||||||
= qint64( ((unsigned char)buf[0])
|
= qint64(((unsigned char)buf[0])
|
||||||
+ ((unsigned char)buf[1] << 8)
|
+ ((unsigned char)buf[1] << 8)
|
||||||
+ ((unsigned char)buf[2] << 16)
|
+ ((unsigned char)buf[2] << 16)
|
||||||
+ ((unsigned char)buf[3] << 24));
|
+ ((unsigned char)buf[3] << 24));
|
||||||
@ -58,11 +58,11 @@ static bool seekToCodeStart(QIODevice *io, qint64 &ps_offset, qint64 &ps_size)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ps_size // Size is in little endian
|
ps_size // Size is in little endian
|
||||||
= qint64( ((unsigned char)buf[0])
|
= qint64(((unsigned char)buf[0])
|
||||||
+ ((unsigned char)buf[1] << 8)
|
+ ((unsigned char)buf[1] << 8)
|
||||||
+ ((unsigned char)buf[2] << 16)
|
+ ((unsigned char)buf[2] << 16)
|
||||||
+ ((unsigned char)buf[3] << 24));
|
+ ((unsigned char)buf[3] << 24));
|
||||||
qCDebug(EPSPLUGIN) << "Offset: " << ps_offset <<" Size: " << ps_size;
|
qCDebug(EPSPLUGIN) << "Offset: " << ps_offset << " Size: " << ps_size;
|
||||||
if (!io->seek(ps_offset)) { // Get offset of PostScript code in the MS-DOS EPS file.
|
if (!io->seek(ps_offset)) { // Get offset of PostScript code in the MS-DOS EPS file.
|
||||||
qCDebug(EPSPLUGIN) << "cannot seek in MS-DOS EPS file";
|
qCDebug(EPSPLUGIN) << "cannot seek in MS-DOS EPS file";
|
||||||
return false;
|
return false;
|
||||||
@ -138,12 +138,13 @@ bool EPSHandler::read(QImage *image)
|
|||||||
dt.start();
|
dt.start();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QIODevice* io = device();
|
QIODevice *io = device();
|
||||||
qint64 ps_offset, ps_size;
|
qint64 ps_offset, ps_size;
|
||||||
|
|
||||||
// find start of PostScript code
|
// find start of PostScript code
|
||||||
if (!seekToCodeStart(io, ps_offset, ps_size))
|
if (!seekToCodeStart(io, ps_offset, ps_size)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
qCDebug(EPSPLUGIN) << "Offset:" << ps_offset << "; size:" << ps_size;
|
qCDebug(EPSPLUGIN) << "Offset:" << ps_offset << "; size:" << ps_size;
|
||||||
|
|
||||||
@ -202,15 +203,16 @@ bool EPSHandler::read(QImage *image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QByteArray intro = "\n";
|
QByteArray intro = "\n";
|
||||||
intro += QByteArray::number(-qRound(x1*xScale));
|
intro += QByteArray::number(-qRound(x1 * xScale));
|
||||||
intro += " ";
|
intro += " ";
|
||||||
intro += QByteArray::number(-qRound(y1*yScale));
|
intro += QByteArray::number(-qRound(y1 * yScale));
|
||||||
intro += " translate\n";
|
intro += " translate\n";
|
||||||
converter.write(intro);
|
converter.write(intro);
|
||||||
|
|
||||||
io->reset();
|
io->reset();
|
||||||
if (ps_offset > 0)
|
if (ps_offset > 0) {
|
||||||
io->seek(ps_offset);
|
io->seek(ps_offset);
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray buffer;
|
QByteArray buffer;
|
||||||
buffer.resize(4096);
|
buffer.resize(4096);
|
||||||
@ -246,15 +248,15 @@ bool EPSHandler::read(QImage *image)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool EPSHandler::write(const QImage &image)
|
bool EPSHandler::write(const QImage &image)
|
||||||
{
|
{
|
||||||
QPrinter psOut(QPrinter::PrinterResolution);
|
QPrinter psOut(QPrinter::PrinterResolution);
|
||||||
QPainter p;
|
QPainter p;
|
||||||
|
|
||||||
QTemporaryFile tmpFile(QStringLiteral("XXXXXXXX.pdf"));
|
QTemporaryFile tmpFile(QStringLiteral("XXXXXXXX.pdf"));
|
||||||
if (!tmpFile.open())
|
if (!tmpFile.open()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
psOut.setCreator(QStringLiteral("KDE EPS image plugin"));
|
psOut.setCreator(QStringLiteral("KDE EPS image plugin"));
|
||||||
psOut.setOutputFileName(tmpFile.fileName());
|
psOut.setOutputFileName(tmpFile.fileName());
|
||||||
@ -319,8 +321,9 @@ bool EPSHandler::canRead(QIODevice *device)
|
|||||||
QByteArray head = device->readLine(64);
|
QByteArray head = device->readLine(64);
|
||||||
int readBytes = head.size();
|
int readBytes = head.size();
|
||||||
if (device->isSequential()) {
|
if (device->isSequential()) {
|
||||||
while (readBytes > 0)
|
while (readBytes > 0) {
|
||||||
device->ungetChar(head[readBytes-- - 1]);
|
device->ungetChar(head[readBytes-- - 1]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
device->seek(oldPos);
|
device->seek(oldPos);
|
||||||
}
|
}
|
||||||
@ -330,18 +333,23 @@ bool EPSHandler::canRead(QIODevice *device)
|
|||||||
|
|
||||||
QImageIOPlugin::Capabilities EPSPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
QImageIOPlugin::Capabilities EPSPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
||||||
{
|
{
|
||||||
if (format == "eps" || format == "epsi" || format == "epsf")
|
if (format == "eps" || format == "epsi" || format == "epsf") {
|
||||||
return Capabilities(CanRead | CanWrite);
|
return Capabilities(CanRead | CanWrite);
|
||||||
if (!format.isEmpty())
|
}
|
||||||
|
if (!format.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
if (!device->isOpen())
|
}
|
||||||
|
if (!device->isOpen()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Capabilities cap;
|
Capabilities cap;
|
||||||
if (device->isReadable() && EPSHandler::canRead(device))
|
if (device->isReadable() && EPSHandler::canRead(device)) {
|
||||||
cap |= CanRead;
|
cap |= CanRead;
|
||||||
if (device->isWritable())
|
}
|
||||||
|
if (device->isWritable()) {
|
||||||
cap |= CanWrite;
|
cap |= CanWrite;
|
||||||
|
}
|
||||||
return cap;
|
return cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
// -*- C++;indent-tabs-mode: t; tab-width: 4; c-basic-offset: 4; -*-
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* KImageIO Routines to read (and perhaps in the future, write) images
|
* KImageIO Routines to read (and perhaps in the future, write) images
|
||||||
@ -37,8 +36,9 @@
|
|||||||
class K_IStream: public Imf::IStream
|
class K_IStream: public Imf::IStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
K_IStream(QIODevice *dev, const QByteArray& fileName):
|
K_IStream(QIODevice *dev, const QByteArray &fileName):
|
||||||
IStream(fileName.data()), m_dev(dev) {
|
IStream(fileName.data()), m_dev(dev)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool read(char c[], int n);
|
virtual bool read(char c[], int n);
|
||||||
@ -57,8 +57,9 @@ bool K_IStream::read(char c[], int n)
|
|||||||
return true;
|
return true;
|
||||||
} else if (result == 0) {
|
} else if (result == 0) {
|
||||||
throw Iex::InputExc("Unexpected end of file");
|
throw Iex::InputExc("Unexpected end of file");
|
||||||
} else // negative value {
|
} else { // negative value {
|
||||||
Iex::throwErrnoExc("Error in read", result);
|
Iex::throwErrnoExc("Error in read", result);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,14 +116,18 @@ QRgb RgbaToQrgba(struct Imf::Rgba imagePixel)
|
|||||||
// this value will be mapped to the display's
|
// this value will be mapped to the display's
|
||||||
// maximum intensity).
|
// maximum intensity).
|
||||||
// Response: kneeLow = 0.0 (2^0.0 => 1); kneeHigh = 5.0 (2^5 =>32)
|
// Response: kneeLow = 0.0 (2^0.0 => 1); kneeHigh = 5.0 (2^5 =>32)
|
||||||
if (r > 1.0)
|
if (r > 1.0) {
|
||||||
r = 1.0 + Imath::Math<float>::log((r - 1.0) * 0.184874 + 1) / 0.184874;
|
r = 1.0 + Imath::Math<float>::log((r - 1.0) * 0.184874 + 1) / 0.184874;
|
||||||
if (g > 1.0)
|
}
|
||||||
|
if (g > 1.0) {
|
||||||
g = 1.0 + Imath::Math<float>::log((g - 1.0) * 0.184874 + 1) / 0.184874;
|
g = 1.0 + Imath::Math<float>::log((g - 1.0) * 0.184874 + 1) / 0.184874;
|
||||||
if (b > 1.0)
|
}
|
||||||
|
if (b > 1.0) {
|
||||||
b = 1.0 + Imath::Math<float>::log((b - 1.0) * 0.184874 + 1) / 0.184874;
|
b = 1.0 + Imath::Math<float>::log((b - 1.0) * 0.184874 + 1) / 0.184874;
|
||||||
if (a > 1.0)
|
}
|
||||||
|
if (a > 1.0) {
|
||||||
a = 1.0 + Imath::Math<float>::log((a - 1.0) * 0.184874 + 1) / 0.184874;
|
a = 1.0 + Imath::Math<float>::log((a - 1.0) * 0.184874 + 1) / 0.184874;
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// 5) Gamma-correct the pixel values, assuming that the
|
// 5) Gamma-correct the pixel values, assuming that the
|
||||||
// screen's gamma is 0.4545 (or 1/2.2).
|
// screen's gamma is 0.4545 (or 1/2.2).
|
||||||
@ -174,8 +179,9 @@ bool EXRHandler::read(QImage *outImage)
|
|||||||
file.readPixels(dw.min.y, dw.max.y);
|
file.readPixels(dw.min.y, dw.max.y);
|
||||||
|
|
||||||
QImage image(width, height, QImage::Format_RGB32);
|
QImage image(width, height, QImage::Format_RGB32);
|
||||||
if (image.isNull())
|
if (image.isNull()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// somehow copy pixels into image
|
// somehow copy pixels into image
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
@ -194,7 +200,6 @@ bool EXRHandler::read(QImage *outImage)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool EXRHandler::write(const QImage &image)
|
bool EXRHandler::write(const QImage &image)
|
||||||
{
|
{
|
||||||
// TODO: stub
|
// TODO: stub
|
||||||
@ -202,7 +207,6 @@ bool EXRHandler::write(const QImage &image)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool EXRHandler::canRead(QIODevice *device)
|
bool EXRHandler::canRead(QIODevice *device)
|
||||||
{
|
{
|
||||||
if (!device) {
|
if (!device) {
|
||||||
@ -217,16 +221,20 @@ bool EXRHandler::canRead(QIODevice *device)
|
|||||||
|
|
||||||
QImageIOPlugin::Capabilities EXRPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
QImageIOPlugin::Capabilities EXRPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
||||||
{
|
{
|
||||||
if (format == "exr")
|
if (format == "exr") {
|
||||||
return Capabilities(CanRead);
|
return Capabilities(CanRead);
|
||||||
if (!format.isEmpty())
|
}
|
||||||
|
if (!format.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
if (!device->isOpen())
|
}
|
||||||
|
if (!device->isOpen()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Capabilities cap;
|
Capabilities cap;
|
||||||
if (device->isReadable() && EXRHandler::canRead(device))
|
if (device->isReadable() && EXRHandler::canRead(device)) {
|
||||||
cap |= CanRead;
|
cap |= CanRead;
|
||||||
|
}
|
||||||
return cap;
|
return cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -178,7 +178,7 @@ inline int INT_BLEND(int a, int b, int alpha)
|
|||||||
* \param green the green component (modified in place).
|
* \param green the green component (modified in place).
|
||||||
* \param blue the blue component (modified in place).
|
* \param blue the blue component (modified in place).
|
||||||
*/
|
*/
|
||||||
static void RGBTOHSV(uchar& red, uchar& green, uchar& blue)
|
static void RGBTOHSV(uchar &red, uchar &green, uchar &blue)
|
||||||
{
|
{
|
||||||
int r, g, b;
|
int r, g, b;
|
||||||
double h, s, v;
|
double h, s, v;
|
||||||
@ -200,27 +200,31 @@ static void RGBTOHSV(uchar& red, uchar& green, uchar& blue)
|
|||||||
|
|
||||||
v = max;
|
v = max;
|
||||||
|
|
||||||
if (max != 0)
|
if (max != 0) {
|
||||||
s = ((max - min) * 255) / (double)max;
|
s = ((max - min) * 255) / (double)max;
|
||||||
else
|
} else {
|
||||||
s = 0;
|
s = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (s == 0)
|
if (s == 0) {
|
||||||
h = 0;
|
h = 0;
|
||||||
else {
|
} else {
|
||||||
int delta = max - min;
|
int delta = max - min;
|
||||||
if (r == max)
|
if (r == max) {
|
||||||
h = (g - b) / (double)delta;
|
h = (g - b) / (double)delta;
|
||||||
else if (g == max)
|
} else if (g == max) {
|
||||||
h = 2 + (b - r) / (double)delta;
|
h = 2 + (b - r) / (double)delta;
|
||||||
else if (b == max)
|
} else if (b == max) {
|
||||||
h = 4 + (r - g) / (double)delta;
|
h = 4 + (r - g) / (double)delta;
|
||||||
|
}
|
||||||
h *= 42.5;
|
h *= 42.5;
|
||||||
|
|
||||||
if (h < 0)
|
if (h < 0) {
|
||||||
h += 255;
|
h += 255;
|
||||||
if (h > 255)
|
}
|
||||||
|
if (h > 255) {
|
||||||
h -= 255;
|
h -= 255;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
red = (uchar)h;
|
red = (uchar)h;
|
||||||
@ -234,7 +238,7 @@ static void RGBTOHSV(uchar& red, uchar& green, uchar& blue)
|
|||||||
* \param saturation the saturation component (modified in place).
|
* \param saturation the saturation component (modified in place).
|
||||||
* \param value the value component (modified in place).
|
* \param value the value component (modified in place).
|
||||||
*/
|
*/
|
||||||
static void HSVTORGB(uchar& hue, uchar& saturation, uchar& value)
|
static void HSVTORGB(uchar &hue, uchar &saturation, uchar &value)
|
||||||
{
|
{
|
||||||
if (saturation == 0) {
|
if (saturation == 0) {
|
||||||
hue = value;
|
hue = value;
|
||||||
@ -293,7 +297,7 @@ static void HSVTORGB(uchar& hue, uchar& saturation, uchar& value)
|
|||||||
* \param green the green component (modified in place).
|
* \param green the green component (modified in place).
|
||||||
* \param blue the blue component (modified in place).
|
* \param blue the blue component (modified in place).
|
||||||
*/
|
*/
|
||||||
static void RGBTOHLS(uchar& red, uchar& green, uchar& blue)
|
static void RGBTOHLS(uchar &red, uchar &green, uchar &blue)
|
||||||
{
|
{
|
||||||
int r = red;
|
int r = red;
|
||||||
int g = green;
|
int g = green;
|
||||||
@ -319,24 +323,27 @@ static void RGBTOHLS(uchar& red, uchar& green, uchar& blue)
|
|||||||
} else {
|
} else {
|
||||||
int delta = max - min;
|
int delta = max - min;
|
||||||
|
|
||||||
if (l < 128)
|
if (l < 128) {
|
||||||
s = 255 * (double)delta / (double)(max + min);
|
s = 255 * (double)delta / (double)(max + min);
|
||||||
else
|
} else {
|
||||||
s = 255 * (double)delta / (double)(511 - max - min);
|
s = 255 * (double)delta / (double)(511 - max - min);
|
||||||
|
}
|
||||||
|
|
||||||
if (r == max)
|
if (r == max) {
|
||||||
h = (g - b) / (double)delta;
|
h = (g - b) / (double)delta;
|
||||||
else if (g == max)
|
} else if (g == max) {
|
||||||
h = 2 + (b - r) / (double)delta;
|
h = 2 + (b - r) / (double)delta;
|
||||||
else
|
} else {
|
||||||
h = 4 + (r - g) / (double)delta;
|
h = 4 + (r - g) / (double)delta;
|
||||||
|
}
|
||||||
|
|
||||||
h *= 42.5;
|
h *= 42.5;
|
||||||
|
|
||||||
if (h < 0)
|
if (h < 0) {
|
||||||
h += 255;
|
h += 255;
|
||||||
else if (h > 255)
|
} else if (h > 255) {
|
||||||
h -= 255;
|
h -= 255;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
red = (uchar)h;
|
red = (uchar)h;
|
||||||
@ -355,19 +362,21 @@ static int HLSVALUE(double n1, double n2, double hue)
|
|||||||
{
|
{
|
||||||
double value;
|
double value;
|
||||||
|
|
||||||
if (hue > 255)
|
if (hue > 255) {
|
||||||
hue -= 255;
|
hue -= 255;
|
||||||
else if (hue < 0)
|
} else if (hue < 0) {
|
||||||
hue += 255;
|
hue += 255;
|
||||||
|
}
|
||||||
|
|
||||||
if (hue < 42.5)
|
if (hue < 42.5) {
|
||||||
value = n1 + (n2 - n1) * (hue / 42.5);
|
value = n1 + (n2 - n1) * (hue / 42.5);
|
||||||
else if (hue < 127.5)
|
} else if (hue < 127.5) {
|
||||||
value = n2;
|
value = n2;
|
||||||
else if (hue < 170)
|
} else if (hue < 170) {
|
||||||
value = n1 + (n2 - n1) * ((170 - hue) / 42.5);
|
value = n1 + (n2 - n1) * ((170 - hue) / 42.5);
|
||||||
else
|
} else {
|
||||||
value = n1;
|
value = n1;
|
||||||
|
}
|
||||||
|
|
||||||
return (int)(value * 255);
|
return (int)(value * 255);
|
||||||
}
|
}
|
||||||
@ -378,7 +387,7 @@ static int HLSVALUE(double n1, double n2, double hue)
|
|||||||
* \param lightness the lightness component (modified in place).
|
* \param lightness the lightness component (modified in place).
|
||||||
* \param saturation the saturation component (modified in place).
|
* \param saturation the saturation component (modified in place).
|
||||||
*/
|
*/
|
||||||
static void HLSTORGB(uchar& hue, uchar& lightness, uchar& saturation)
|
static void HLSTORGB(uchar &hue, uchar &lightness, uchar &saturation)
|
||||||
{
|
{
|
||||||
double h = hue;
|
double h = hue;
|
||||||
double l = lightness;
|
double l = lightness;
|
||||||
@ -391,10 +400,11 @@ static void HLSTORGB(uchar& hue, uchar& lightness, uchar& saturation)
|
|||||||
} else {
|
} else {
|
||||||
double m1, m2;
|
double m1, m2;
|
||||||
|
|
||||||
if (l < 128)
|
if (l < 128) {
|
||||||
m2 = (l * (255 + s)) / 65025.;
|
m2 = (l * (255 + s)) / 65025.;
|
||||||
else
|
} else {
|
||||||
m2 = (l + s - (l * s) / 255.) / 255.;
|
m2 = (l + s - (l * s) / 255.) / 255.;
|
||||||
|
}
|
||||||
|
|
||||||
m1 = (l / 127.5) - m2;
|
m1 = (l / 127.5) - m2;
|
||||||
|
|
||||||
|
|||||||
@ -26,14 +26,16 @@ namespace // Private.
|
|||||||
|
|
||||||
static inline uchar ClipToByte(float value)
|
static inline uchar ClipToByte(float value)
|
||||||
{
|
{
|
||||||
if (value > 255.0f) return 255;
|
if (value > 255.0f) {
|
||||||
|
return 255;
|
||||||
|
}
|
||||||
//else if (value < 0.0f) return 0; // we know value is positive.
|
//else if (value < 0.0f) return 0; // we know value is positive.
|
||||||
return uchar(value);
|
return uchar(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// read an old style line from the hdr image file
|
// read an old style line from the hdr image file
|
||||||
// if 'first' is true the first byte is already read
|
// if 'first' is true the first byte is already read
|
||||||
static bool Read_Old_Line(uchar * image, int width, QDataStream & s)
|
static bool Read_Old_Line(uchar *image, int width, QDataStream &s)
|
||||||
{
|
{
|
||||||
int rshift = 0;
|
int rshift = 0;
|
||||||
int i;
|
int i;
|
||||||
@ -44,7 +46,9 @@ static bool Read_Old_Line(uchar * image, int width, QDataStream & s)
|
|||||||
s >> image[2];
|
s >> image[2];
|
||||||
s >> image[3];
|
s >> image[3];
|
||||||
|
|
||||||
if (s.atEnd()) return false;
|
if (s.atEnd()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if ((image[0] == 1) && (image[1] == 1) && (image[2] == 1)) {
|
if ((image[0] == 1) && (image[1] == 1) && (image[2] == 1)) {
|
||||||
for (i = image[3] << rshift; i > 0; i--) {
|
for (i = image[3] << rshift; i > 0; i--) {
|
||||||
@ -63,8 +67,7 @@ static bool Read_Old_Line(uchar * image, int width, QDataStream & s)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void RGBE_To_QRgbLine(uchar *image, QRgb *scanline, int width)
|
||||||
static void RGBE_To_QRgbLine(uchar * image, QRgb * scanline, int width)
|
|
||||||
{
|
{
|
||||||
for (int j = 0; j < width; j++) {
|
for (int j = 0; j < width; j++) {
|
||||||
// v = ldexp(1.0, int(image[3]) - 128);
|
// v = ldexp(1.0, int(image[3]) - 128);
|
||||||
@ -85,7 +88,7 @@ static void RGBE_To_QRgbLine(uchar * image, QRgb * scanline, int width)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load the HDR image.
|
// Load the HDR image.
|
||||||
static bool LoadHDR(QDataStream & s, const int width, const int height, QImage & img)
|
static bool LoadHDR(QDataStream &s, const int width, const int height, QImage &img)
|
||||||
{
|
{
|
||||||
uchar val, code;
|
uchar val, code;
|
||||||
|
|
||||||
@ -97,7 +100,7 @@ static bool LoadHDR(QDataStream & s, const int width, const int height, QImage &
|
|||||||
QMemArray<uchar> image(width * 4);
|
QMemArray<uchar> image(width * 4);
|
||||||
|
|
||||||
for (int cline = 0; cline < height; cline++) {
|
for (int cline = 0; cline < height; cline++) {
|
||||||
QRgb * scanline = (QRgb *) img.scanLine(cline);
|
QRgb *scanline = (QRgb *) img.scanLine(cline);
|
||||||
|
|
||||||
// determine scanline type
|
// determine scanline type
|
||||||
if ((width < MINELEN) || (MAXELEN < width)) {
|
if ((width < MINELEN) || (MAXELEN < width)) {
|
||||||
@ -173,8 +176,7 @@ static bool LoadHDR(QDataStream & s, const int width, const int height, QImage &
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
Q_DECL_EXPORT void kimgio_hdr_read(QImageIO *io)
|
||||||
Q_DECL_EXPORT void kimgio_hdr_read(QImageIO * io)
|
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
char line[MAXLINE];
|
char line[MAXLINE];
|
||||||
@ -229,7 +231,6 @@ Q_DECL_EXPORT void kimgio_hdr_read(QImageIO * io)
|
|||||||
io->setStatus(0);
|
io->setStatus(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Q_DECL_EXPORT void kimgio_hdr_write(QImageIO *)
|
Q_DECL_EXPORT void kimgio_hdr_write(QImageIO *)
|
||||||
{
|
{
|
||||||
// intentionally not implemented (since writing low dynamic range data to a HDR file is nonsense.)
|
// intentionally not implemented (since writing low dynamic range data to a HDR file is nonsense.)
|
||||||
|
|||||||
@ -31,7 +31,6 @@
|
|||||||
#define DEFAULT_RATE 0.10
|
#define DEFAULT_RATE 0.10
|
||||||
#define MAXCMPTS 256
|
#define MAXCMPTS 256
|
||||||
|
|
||||||
|
|
||||||
/************************* JasPer QIODevice stream ***********************/
|
/************************* JasPer QIODevice stream ***********************/
|
||||||
|
|
||||||
//unfortunately this is declared as static in JasPer libraries
|
//unfortunately this is declared as static in JasPer libraries
|
||||||
@ -39,7 +38,7 @@ static jas_stream_t *jas_stream_create()
|
|||||||
{
|
{
|
||||||
jas_stream_t *stream;
|
jas_stream_t *stream;
|
||||||
|
|
||||||
if (!(stream = (jas_stream_t*)jas_malloc(sizeof(jas_stream_t)))) {
|
if (!(stream = (jas_stream_t *)jas_malloc(sizeof(jas_stream_t)))) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
stream->openmode_ = 0;
|
stream->openmode_ = 0;
|
||||||
@ -71,7 +70,7 @@ static void jas_stream_initbuf(jas_stream_t *stream, int bufmode, char *buf,
|
|||||||
if (!buf) {
|
if (!buf) {
|
||||||
/* The caller has not specified a buffer to employ, so allocate
|
/* The caller has not specified a buffer to employ, so allocate
|
||||||
one. */
|
one. */
|
||||||
if ((stream->bufbase_ = (unsigned char*)jas_malloc(JAS_STREAM_BUFSIZE +
|
if ((stream->bufbase_ = (unsigned char *)jas_malloc(JAS_STREAM_BUFSIZE +
|
||||||
JAS_STREAM_MAXPUTBACK))) {
|
JAS_STREAM_MAXPUTBACK))) {
|
||||||
stream->bufmode_ |= JAS_STREAM_FREEBUF;
|
stream->bufmode_ |= JAS_STREAM_FREEBUF;
|
||||||
stream->bufsize_ = JAS_STREAM_BUFSIZE;
|
stream->bufsize_ = JAS_STREAM_BUFSIZE;
|
||||||
@ -105,19 +104,19 @@ static void jas_stream_initbuf(jas_stream_t *stream, int bufmode, char *buf,
|
|||||||
|
|
||||||
static int qiodevice_read(jas_stream_obj_t *obj, char *buf, int cnt)
|
static int qiodevice_read(jas_stream_obj_t *obj, char *buf, int cnt)
|
||||||
{
|
{
|
||||||
QIODevice *io = (QIODevice*) obj;
|
QIODevice *io = (QIODevice *) obj;
|
||||||
return io->read(buf, cnt);
|
return io->read(buf, cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qiodevice_write(jas_stream_obj_t *obj, char *buf, int cnt)
|
static int qiodevice_write(jas_stream_obj_t *obj, char *buf, int cnt)
|
||||||
{
|
{
|
||||||
QIODevice *io = (QIODevice*) obj;
|
QIODevice *io = (QIODevice *) obj;
|
||||||
return io->write(buf, cnt);
|
return io->write(buf, cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static long qiodevice_seek(jas_stream_obj_t *obj, long offset, int origin)
|
static long qiodevice_seek(jas_stream_obj_t *obj, long offset, int origin)
|
||||||
{
|
{
|
||||||
QIODevice *io = (QIODevice*) obj;
|
QIODevice *io = (QIODevice *) obj;
|
||||||
long newpos;
|
long newpos;
|
||||||
|
|
||||||
switch (origin) {
|
switch (origin) {
|
||||||
@ -136,10 +135,11 @@ static long qiodevice_seek(jas_stream_obj_t *obj, long offset, int origin)
|
|||||||
if (newpos < 0) {
|
if (newpos < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (io->seek(newpos))
|
if (io->seek(newpos)) {
|
||||||
return newpos;
|
return newpos;
|
||||||
else
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qiodevice_close(jas_stream_obj_t *)
|
static int qiodevice_close(jas_stream_obj_t *)
|
||||||
@ -158,7 +158,9 @@ static jas_stream_t *jas_stream_qiodevice(QIODevice *iodevice)
|
|||||||
{
|
{
|
||||||
jas_stream_t *stream;
|
jas_stream_t *stream;
|
||||||
|
|
||||||
if (!iodevice) return 0;
|
if (!iodevice) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (!(stream = jas_stream_create())) {
|
if (!(stream = jas_stream_create())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -179,24 +181,25 @@ static jas_stream_t *jas_stream_qiodevice(QIODevice *iodevice)
|
|||||||
/************************ End of JasPer QIODevice stream ****************/
|
/************************ End of JasPer QIODevice stream ****************/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
jas_image_t* image;
|
jas_image_t *image;
|
||||||
|
|
||||||
int cmptlut[MAXCMPTS];
|
int cmptlut[MAXCMPTS];
|
||||||
|
|
||||||
jas_image_t* altimage;
|
jas_image_t *altimage;
|
||||||
} gs_t;
|
} gs_t;
|
||||||
|
|
||||||
|
static jas_image_t *
|
||||||
static jas_image_t*
|
read_image(QIODevice *io)
|
||||||
read_image(QIODevice* io)
|
|
||||||
{
|
{
|
||||||
jas_stream_t* in = 0;
|
jas_stream_t *in = 0;
|
||||||
|
|
||||||
in = jas_stream_qiodevice(io);
|
in = jas_stream_qiodevice(io);
|
||||||
|
|
||||||
if (!in) return 0;
|
if (!in) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
jas_image_t* image = jas_image_decode(in, -1, 0);
|
jas_image_t *image = jas_image_decode(in, -1, 0);
|
||||||
jas_stream_close(in);
|
jas_stream_close(in);
|
||||||
|
|
||||||
// image may be 0, but that's Ok
|
// image may be 0, but that's Ok
|
||||||
@ -204,22 +207,28 @@ read_image(QIODevice* io)
|
|||||||
} // read_image
|
} // read_image
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
convert_colorspace(gs_t& gs)
|
convert_colorspace(gs_t &gs)
|
||||||
{
|
{
|
||||||
jas_cmprof_t *outprof = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB);
|
jas_cmprof_t *outprof = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB);
|
||||||
if (!outprof) return false;
|
if (!outprof) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
gs.altimage = jas_image_chclrspc(gs.image, outprof,
|
gs.altimage = jas_image_chclrspc(gs.image, outprof,
|
||||||
JAS_CMXFORM_INTENT_PER);
|
JAS_CMXFORM_INTENT_PER);
|
||||||
if (!gs.altimage) return false;
|
if (!gs.altimage) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} // convert_colorspace
|
} // convert_colorspace
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
render_view(gs_t& gs, QImage* outImage)
|
render_view(gs_t &gs, QImage *outImage)
|
||||||
{
|
{
|
||||||
if (!gs.altimage) return false;
|
if (!gs.altimage) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
QImage qti;
|
QImage qti;
|
||||||
if ((gs.cmptlut[0] = jas_image_getcmptbytype(gs.altimage,
|
if ((gs.cmptlut[0] = jas_image_getcmptbytype(gs.altimage,
|
||||||
JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R))) < 0 ||
|
JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R))) < 0 ||
|
||||||
@ -230,7 +239,7 @@ render_view(gs_t& gs, QImage* outImage)
|
|||||||
return false;
|
return false;
|
||||||
} // if
|
} // if
|
||||||
|
|
||||||
const int* cmptlut = gs.cmptlut;
|
const int *cmptlut = gs.cmptlut;
|
||||||
int v[3];
|
int v[3];
|
||||||
|
|
||||||
// check that all components have the same size.
|
// check that all components have the same size.
|
||||||
@ -238,8 +247,9 @@ render_view(gs_t& gs, QImage* outImage)
|
|||||||
const int height = jas_image_cmptheight(gs.altimage, cmptlut[0]);
|
const int height = jas_image_cmptheight(gs.altimage, cmptlut[0]);
|
||||||
for (int i = 1; i < 3; ++i) {
|
for (int i = 1; i < 3; ++i) {
|
||||||
if (jas_image_cmptwidth(gs.altimage, cmptlut[i]) != width ||
|
if (jas_image_cmptwidth(gs.altimage, cmptlut[i]) != width ||
|
||||||
jas_image_cmptheight(gs.altimage, cmptlut[i]) != height)
|
jas_image_cmptheight(gs.altimage, cmptlut[i]) != height) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
} // for
|
} // for
|
||||||
|
|
||||||
jas_matrix_t *cmptmatrix[3];
|
jas_matrix_t *cmptmatrix[3];
|
||||||
@ -258,7 +268,7 @@ render_view(gs_t& gs, QImage* outImage)
|
|||||||
if (qti.isNull()) {
|
if (qti.isNull()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
uint32_t* data = (uint32_t*)qti.bits();
|
uint32_t *data = (uint32_t *)qti.bits();
|
||||||
|
|
||||||
for (int y = 0; y < height; ++y) {
|
for (int y = 0; y < height; ++y) {
|
||||||
for (int k = 0; k < 3; ++k) {
|
for (int k = 0; k < 3; ++k) {
|
||||||
@ -274,8 +284,11 @@ render_view(gs_t& gs, QImage* outImage)
|
|||||||
// it to use the complete value range.
|
// it to use the complete value range.
|
||||||
v[k] <<= 8 - prec[k];
|
v[k] <<= 8 - prec[k];
|
||||||
|
|
||||||
if (v[k] < 0) v[k] = 0;
|
if (v[k] < 0) {
|
||||||
else if (v[k] > 255) v[k] = 255;
|
v[k] = 0;
|
||||||
|
} else if (v[k] > 255) {
|
||||||
|
v[k] = 255;
|
||||||
|
}
|
||||||
++buf[k];
|
++buf[k];
|
||||||
} // for k
|
} // for k
|
||||||
|
|
||||||
@ -293,12 +306,11 @@ render_view(gs_t& gs, QImage* outImage)
|
|||||||
return true;
|
return true;
|
||||||
} // render_view
|
} // render_view
|
||||||
|
|
||||||
|
static jas_image_t *
|
||||||
static jas_image_t*
|
create_image(const QImage &qi)
|
||||||
create_image(const QImage& qi)
|
|
||||||
{
|
{
|
||||||
// prepare the component parameters
|
// prepare the component parameters
|
||||||
jas_image_cmptparm_t* cmptparms = new jas_image_cmptparm_t[ 3 ];
|
jas_image_cmptparm_t *cmptparms = new jas_image_cmptparm_t[ 3 ];
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
// x and y offset
|
// x and y offset
|
||||||
@ -316,41 +328,45 @@ create_image(const QImage& qi)
|
|||||||
cmptparms[i].sgnd = false;
|
cmptparms[i].sgnd = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
jas_image_t* ji = jas_image_create(3 /* number components */, cmptparms, JAS_CLRSPC_UNKNOWN);
|
jas_image_t *ji = jas_image_create(3 /* number components */, cmptparms, JAS_CLRSPC_UNKNOWN);
|
||||||
delete[] cmptparms;
|
delete[] cmptparms;
|
||||||
|
|
||||||
// returning 0 is ok
|
// returning 0 is ok
|
||||||
return ji;
|
return ji;
|
||||||
} // create_image
|
} // create_image
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
write_components(jas_image_t* ji, const QImage& qi)
|
write_components(jas_image_t *ji, const QImage &qi)
|
||||||
{
|
{
|
||||||
const unsigned height = qi.height();
|
const unsigned height = qi.height();
|
||||||
const unsigned width = qi.width();
|
const unsigned width = qi.width();
|
||||||
|
|
||||||
jas_matrix_t* m = jas_matrix_create(height, width);
|
jas_matrix_t *m = jas_matrix_create(height, width);
|
||||||
if (!m) return false;
|
if (!m) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
jas_image_setclrspc(ji, JAS_CLRSPC_SRGB);
|
jas_image_setclrspc(ji, JAS_CLRSPC_SRGB);
|
||||||
|
|
||||||
jas_image_setcmpttype(ji, 0, JAS_IMAGE_CT_RGB_R);
|
jas_image_setcmpttype(ji, 0, JAS_IMAGE_CT_RGB_R);
|
||||||
for (uint y = 0; y < height; ++y)
|
for (uint y = 0; y < height; ++y)
|
||||||
for (uint x = 0; x < width; ++x)
|
for (uint x = 0; x < width; ++x) {
|
||||||
jas_matrix_set(m, y, x, qRed(qi.pixel(x, y)));
|
jas_matrix_set(m, y, x, qRed(qi.pixel(x, y)));
|
||||||
|
}
|
||||||
jas_image_writecmpt(ji, 0, 0, 0, width, height, m);
|
jas_image_writecmpt(ji, 0, 0, 0, width, height, m);
|
||||||
|
|
||||||
jas_image_setcmpttype(ji, 1, JAS_IMAGE_CT_RGB_G);
|
jas_image_setcmpttype(ji, 1, JAS_IMAGE_CT_RGB_G);
|
||||||
for (uint y = 0; y < height; ++y)
|
for (uint y = 0; y < height; ++y)
|
||||||
for (uint x = 0; x < width; ++x)
|
for (uint x = 0; x < width; ++x) {
|
||||||
jas_matrix_set(m, y, x, qGreen(qi.pixel(x, y)));
|
jas_matrix_set(m, y, x, qGreen(qi.pixel(x, y)));
|
||||||
|
}
|
||||||
jas_image_writecmpt(ji, 1, 0, 0, width, height, m);
|
jas_image_writecmpt(ji, 1, 0, 0, width, height, m);
|
||||||
|
|
||||||
jas_image_setcmpttype(ji, 2, JAS_IMAGE_CT_RGB_B);
|
jas_image_setcmpttype(ji, 2, JAS_IMAGE_CT_RGB_B);
|
||||||
for (uint y = 0; y < height; ++y)
|
for (uint y = 0; y < height; ++y)
|
||||||
for (uint x = 0; x < width; ++x)
|
for (uint x = 0; x < width; ++x) {
|
||||||
jas_matrix_set(m, y, x, qBlue(qi.pixel(x, y)));
|
jas_matrix_set(m, y, x, qBlue(qi.pixel(x, y)));
|
||||||
|
}
|
||||||
jas_image_writecmpt(ji, 2, 0, 0, width, height, m);
|
jas_image_writecmpt(ji, 2, 0, 0, width, height, m);
|
||||||
jas_matrix_destroy(m);
|
jas_matrix_destroy(m);
|
||||||
|
|
||||||
@ -358,15 +374,17 @@ write_components(jas_image_t* ji, const QImage& qi)
|
|||||||
} // write_components
|
} // write_components
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
write_image(const QImage &image, QIODevice* io, int quality)
|
write_image(const QImage &image, QIODevice *io, int quality)
|
||||||
{
|
{
|
||||||
jas_stream_t* stream = 0;
|
jas_stream_t *stream = 0;
|
||||||
stream = jas_stream_qiodevice(io);
|
stream = jas_stream_qiodevice(io);
|
||||||
|
|
||||||
// by here, a jas_stream_t is open
|
// by here, a jas_stream_t is open
|
||||||
if (!stream) return false;
|
if (!stream) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
jas_image_t* ji = create_image(image);
|
jas_image_t *ji = create_image(image);
|
||||||
if (!ji) {
|
if (!ji) {
|
||||||
jas_stream_close(stream);
|
jas_stream_close(stream);
|
||||||
return false;
|
return false;
|
||||||
@ -390,7 +408,9 @@ write_image(const QImage &image, QIODevice* io, int quality)
|
|||||||
jas_image_destroy(ji);
|
jas_image_destroy(ji);
|
||||||
jas_stream_close(stream);
|
jas_stream_close(stream);
|
||||||
|
|
||||||
if (i != 0) return false;
|
if (i != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -425,17 +445,27 @@ bool JP2Handler::canRead(QIODevice *device)
|
|||||||
|
|
||||||
bool JP2Handler::read(QImage *image)
|
bool JP2Handler::read(QImage *image)
|
||||||
{
|
{
|
||||||
if (!canRead()) return false;
|
if (!canRead()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
gs_t gs;
|
gs_t gs;
|
||||||
if (!(gs.image = read_image(device()))) return false;
|
if (!(gs.image = read_image(device()))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!convert_colorspace(gs)) return false;
|
if (!convert_colorspace(gs)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
render_view(gs, image);
|
render_view(gs, image);
|
||||||
|
|
||||||
if (gs.image) jas_image_destroy(gs.image);
|
if (gs.image) {
|
||||||
if (gs.altimage) jas_image_destroy(gs.altimage);
|
jas_image_destroy(gs.image);
|
||||||
|
}
|
||||||
|
if (gs.altimage) {
|
||||||
|
jas_image_destroy(gs.altimage);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -452,31 +482,38 @@ bool JP2Handler::supportsOption(ImageOption option) const
|
|||||||
|
|
||||||
QVariant JP2Handler::option(ImageOption option) const
|
QVariant JP2Handler::option(ImageOption option) const
|
||||||
{
|
{
|
||||||
if (option == Quality)
|
if (option == Quality) {
|
||||||
return quality;
|
return quality;
|
||||||
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JP2Handler::setOption(ImageOption option, const QVariant &value)
|
void JP2Handler::setOption(ImageOption option, const QVariant &value)
|
||||||
{
|
{
|
||||||
if (option == Quality)
|
if (option == Quality) {
|
||||||
quality = qBound(-1, value.toInt(), 100);
|
quality = qBound(-1, value.toInt(), 100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QImageIOPlugin::Capabilities JP2Plugin::capabilities(QIODevice *device, const QByteArray &format) const
|
QImageIOPlugin::Capabilities JP2Plugin::capabilities(QIODevice *device, const QByteArray &format) const
|
||||||
{
|
{
|
||||||
if (format == "jp2")
|
if (format == "jp2") {
|
||||||
return Capabilities(CanRead | CanWrite);
|
return Capabilities(CanRead | CanWrite);
|
||||||
if (!format.isEmpty())
|
}
|
||||||
|
if (!format.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
if (!device->isOpen())
|
}
|
||||||
|
if (!device->isOpen()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Capabilities cap;
|
Capabilities cap;
|
||||||
if (device->isReadable() && JP2Handler::canRead(device))
|
if (device->isReadable() && JP2Handler::canRead(device)) {
|
||||||
cap |= CanRead;
|
cap |= CanRead;
|
||||||
if (device->isWritable())
|
}
|
||||||
|
if (device->isWritable()) {
|
||||||
cap |= CanWrite;
|
cap |= CanWrite;
|
||||||
|
}
|
||||||
return cap;
|
return cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,8 @@ public:
|
|||||||
quint8 g;
|
quint8 g;
|
||||||
quint8 b;
|
quint8 b;
|
||||||
|
|
||||||
static RGB from(const QRgb &color) {
|
static RGB from(const QRgb &color)
|
||||||
|
{
|
||||||
RGB c;
|
RGB c;
|
||||||
c.r = qRed(color);
|
c.r = qRed(color);
|
||||||
c.g = qGreen(color);
|
c.g = qGreen(color);
|
||||||
@ -34,14 +35,16 @@ public:
|
|||||||
class Palette
|
class Palette
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void setColor(int i, const QRgb color) {
|
void setColor(int i, const QRgb color)
|
||||||
|
{
|
||||||
RGB &c = rgb[ i ];
|
RGB &c = rgb[ i ];
|
||||||
c.r = qRed(color);
|
c.r = qRed(color);
|
||||||
c.g = qGreen(color);
|
c.g = qGreen(color);
|
||||||
c.b = qBlue(color);
|
c.b = qBlue(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
QRgb color(int i) const {
|
QRgb color(int i) const
|
||||||
|
{
|
||||||
return qRgb(rgb[ i ].r, rgb[ i ].g, rgb[ i ].b);
|
return qRgb(rgb[ i ].r, rgb[ i ].g, rgb[ i ].b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,13 +56,16 @@ class PCXHEADER
|
|||||||
public:
|
public:
|
||||||
PCXHEADER();
|
PCXHEADER();
|
||||||
|
|
||||||
inline int width() const {
|
inline int width() const
|
||||||
|
{
|
||||||
return (XMax - XMin) + 1;
|
return (XMax - XMin) + 1;
|
||||||
}
|
}
|
||||||
inline int height() const {
|
inline int height() const
|
||||||
|
{
|
||||||
return (YMax - YMin) + 1;
|
return (YMax - YMin) + 1;
|
||||||
}
|
}
|
||||||
inline bool isCompressed() const {
|
inline bool isCompressed() const
|
||||||
|
{
|
||||||
return (Encoding == 1);
|
return (Encoding == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,8 +117,9 @@ static QDataStream &operator>>(QDataStream &s, RGB &rgb)
|
|||||||
|
|
||||||
static QDataStream &operator>>(QDataStream &s, Palette &pal)
|
static QDataStream &operator>>(QDataStream &s, Palette &pal)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 16; ++i)
|
for (int i = 0; i < 16; ++i) {
|
||||||
s >> pal.rgb[ i ];
|
s >> pal.rgb[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -151,8 +158,9 @@ static QDataStream &operator>>(QDataStream &s, PCXHEADER &ph)
|
|||||||
|
|
||||||
// Skip the rest of the header
|
// Skip the rest of the header
|
||||||
quint8 byte;
|
quint8 byte;
|
||||||
while (s.device()->pos() < 128)
|
while (s.device()->pos() < 128) {
|
||||||
s >> byte;
|
s >> byte;
|
||||||
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -166,8 +174,9 @@ static QDataStream &operator<<(QDataStream &s, const RGB &rgb)
|
|||||||
|
|
||||||
static QDataStream &operator<<(QDataStream &s, const Palette &pal)
|
static QDataStream &operator<<(QDataStream &s, const Palette &pal)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 16; ++i)
|
for (int i = 0; i < 16; ++i) {
|
||||||
s << pal.rgb[ i ];
|
s << pal.rgb[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -189,8 +198,9 @@ static QDataStream &operator<<(QDataStream &s, const PCXHEADER &ph)
|
|||||||
s << ph.VScreenSize;
|
s << ph.VScreenSize;
|
||||||
|
|
||||||
quint8 byte = 0;
|
quint8 byte = 0;
|
||||||
for (int i = 0; i < 54; ++i)
|
for (int i = 0; i < 54; ++i) {
|
||||||
s << byte;
|
s << byte;
|
||||||
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -219,8 +229,9 @@ static void readLine(QDataStream &s, QByteArray &buf, const PCXHEADER &header)
|
|||||||
count = byte - 0xc0;
|
count = byte - 0xc0;
|
||||||
s >> byte;
|
s >> byte;
|
||||||
}
|
}
|
||||||
while (count-- && i < size)
|
while (count-- && i < size) {
|
||||||
buf[ i++ ] = byte;
|
buf[ i++ ] = byte;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Image is not compressed (possible?)
|
// Image is not compressed (possible?)
|
||||||
@ -247,8 +258,9 @@ static void readImage1(QImage &img, QDataStream &s, const PCXHEADER &header)
|
|||||||
readLine(s, buf, header);
|
readLine(s, buf, header);
|
||||||
uchar *p = img.scanLine(y);
|
uchar *p = img.scanLine(y);
|
||||||
unsigned int bpl = qMin((quint16)((header.width() + 7) / 8), header.BytesPerLine);
|
unsigned int bpl = qMin((quint16)((header.width() + 7) / 8), header.BytesPerLine);
|
||||||
for (unsigned int x = 0; x < bpl; ++x)
|
for (unsigned int x = 0; x < bpl; ++x) {
|
||||||
p[ x ] = buf[x];
|
p[ x ] = buf[x];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the color palette
|
// Set the color palette
|
||||||
@ -276,18 +288,21 @@ static void readImage4(QImage &img, QDataStream &s, const PCXHEADER &header)
|
|||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
quint32 offset = i * header.BytesPerLine;
|
quint32 offset = i * header.BytesPerLine;
|
||||||
for (int x = 0; x < header.width(); ++x)
|
for (int x = 0; x < header.width(); ++x)
|
||||||
if (buf[ offset + (x / 8) ] & (128 >> (x % 8)))
|
if (buf[ offset + (x / 8) ] & (128 >> (x % 8))) {
|
||||||
pixbuf[ x ] = (int)(pixbuf[ x ]) + (1 << i);
|
pixbuf[ x ] = (int)(pixbuf[ x ]) + (1 << i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uchar *p = img.scanLine(y);
|
uchar *p = img.scanLine(y);
|
||||||
for (int x = 0; x < header.width(); ++x)
|
for (int x = 0; x < header.width(); ++x) {
|
||||||
p[ x ] = pixbuf[ x ];
|
p[ x ] = pixbuf[ x ];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the palette
|
// Read the palette
|
||||||
for (int i = 0; i < 16; ++i)
|
for (int i = 0; i < 16; ++i) {
|
||||||
img.setColor(i, header.ColorMap.color(i));
|
img.setColor(i, header.ColorMap.color(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void readImage8(QImage &img, QDataStream &s, const PCXHEADER &header)
|
static void readImage8(QImage &img, QDataStream &s, const PCXHEADER &header)
|
||||||
@ -307,8 +322,9 @@ static void readImage8(QImage &img, QDataStream &s, const PCXHEADER &header)
|
|||||||
|
|
||||||
uchar *p = img.scanLine(y);
|
uchar *p = img.scanLine(y);
|
||||||
unsigned int bpl = qMin(header.BytesPerLine, (quint16)header.width());
|
unsigned int bpl = qMin(header.BytesPerLine, (quint16)header.width());
|
||||||
for (unsigned int x = 0; x < bpl; ++x)
|
for (unsigned int x = 0; x < bpl; ++x) {
|
||||||
p[ x ] = buf[ x ];
|
p[ x ] = buf[ x ];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
quint8 flag;
|
quint8 flag;
|
||||||
@ -344,8 +360,9 @@ static void readImage24(QImage &img, QDataStream &s, const PCXHEADER &header)
|
|||||||
readLine(s, b_buf, header);
|
readLine(s, b_buf, header);
|
||||||
|
|
||||||
uint *p = (uint *)img.scanLine(y);
|
uint *p = (uint *)img.scanLine(y);
|
||||||
for (int x = 0; x < header.width(); ++x)
|
for (int x = 0; x < header.width(); ++x) {
|
||||||
p[ x ] = qRgb(r_buf[ x ], g_buf[ x ], b_buf[ x ]);
|
p[ x ] = qRgb(r_buf[ x ], g_buf[ x ], b_buf[ x ]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,8 +409,9 @@ static void writeImage1(QImage &img, QDataStream &s, PCXHEADER &header)
|
|||||||
quint8 *p = img.scanLine(y);
|
quint8 *p = img.scanLine(y);
|
||||||
|
|
||||||
// Invert as QImage uses reverse palette for monochrome images?
|
// Invert as QImage uses reverse palette for monochrome images?
|
||||||
for (int i = 0; i < header.BytesPerLine; ++i)
|
for (int i = 0; i < header.BytesPerLine; ++i) {
|
||||||
buf[ i ] = ~p[ i ];
|
buf[ i ] = ~p[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
writeLine(s, buf);
|
writeLine(s, buf);
|
||||||
}
|
}
|
||||||
@ -405,30 +423,35 @@ static void writeImage4(QImage &img, QDataStream &s, PCXHEADER &header)
|
|||||||
header.NPlanes = 4;
|
header.NPlanes = 4;
|
||||||
header.BytesPerLine = header.width() / 8;
|
header.BytesPerLine = header.width() / 8;
|
||||||
|
|
||||||
for (int i = 0; i < 16; ++i)
|
for (int i = 0; i < 16; ++i) {
|
||||||
header.ColorMap.setColor(i, img.color(i));
|
header.ColorMap.setColor(i, img.color(i));
|
||||||
|
}
|
||||||
|
|
||||||
s << header;
|
s << header;
|
||||||
|
|
||||||
QByteArray buf[ 4 ];
|
QByteArray buf[ 4 ];
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i) {
|
||||||
buf[ i ].resize(header.BytesPerLine);
|
buf[ i ].resize(header.BytesPerLine);
|
||||||
|
}
|
||||||
|
|
||||||
for (int y = 0; y < header.height(); ++y) {
|
for (int y = 0; y < header.height(); ++y) {
|
||||||
quint8 *p = img.scanLine(y);
|
quint8 *p = img.scanLine(y);
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i) {
|
||||||
buf[ i ].fill(0);
|
buf[ i ].fill(0);
|
||||||
|
}
|
||||||
|
|
||||||
for (int x = 0; x < header.width(); ++x) {
|
for (int x = 0; x < header.width(); ++x) {
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i)
|
||||||
if (*(p + x) & (1 << i))
|
if (*(p + x) & (1 << i)) {
|
||||||
buf[ i ][ x / 8 ] = (int)(buf[ i ][ x / 8 ]) | 1 << (7 - x % 8);
|
buf[ i ][ x / 8 ] = (int)(buf[ i ][ x / 8 ]) | 1 << (7 - x % 8);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i) {
|
||||||
writeLine(s, buf[ i ]);
|
writeLine(s, buf[ i ]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,8 +468,9 @@ static void writeImage8(QImage &img, QDataStream &s, PCXHEADER &header)
|
|||||||
for (int y = 0; y < header.height(); ++y) {
|
for (int y = 0; y < header.height(); ++y) {
|
||||||
quint8 *p = img.scanLine(y);
|
quint8 *p = img.scanLine(y);
|
||||||
|
|
||||||
for (int i = 0; i < header.BytesPerLine; ++i)
|
for (int i = 0; i < header.BytesPerLine; ++i) {
|
||||||
buf[ i ] = p[ i ];
|
buf[ i ] = p[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
writeLine(s, buf);
|
writeLine(s, buf);
|
||||||
}
|
}
|
||||||
@ -456,8 +480,9 @@ static void writeImage8(QImage &img, QDataStream &s, PCXHEADER &header)
|
|||||||
s << byte;
|
s << byte;
|
||||||
|
|
||||||
// Write palette
|
// Write palette
|
||||||
for (int i = 0; i < 256; ++i)
|
for (int i = 0; i < 256; ++i) {
|
||||||
s << RGB::from(img.color(i));
|
s << RGB::from(img.color(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void writeImage24(QImage &img, QDataStream &s, PCXHEADER &header)
|
static void writeImage24(QImage &img, QDataStream &s, PCXHEADER &header)
|
||||||
@ -488,7 +513,6 @@ static void writeImage24(QImage &img, QDataStream &s, PCXHEADER &header)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PCXHandler::PCXHandler()
|
PCXHandler::PCXHandler()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -613,8 +637,9 @@ bool PCXHandler::canRead(QIODevice *device)
|
|||||||
qint64 readBytes = device->read(head, sizeof(head));
|
qint64 readBytes = device->read(head, sizeof(head));
|
||||||
if (readBytes != sizeof(head)) {
|
if (readBytes != sizeof(head)) {
|
||||||
if (device->isSequential()) {
|
if (device->isSequential()) {
|
||||||
while (readBytes > 0)
|
while (readBytes > 0) {
|
||||||
device->ungetChar(head[readBytes-- - 1]);
|
device->ungetChar(head[readBytes-- - 1]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
device->seek(oldPos);
|
device->seek(oldPos);
|
||||||
}
|
}
|
||||||
@ -622,8 +647,9 @@ bool PCXHandler::canRead(QIODevice *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (device->isSequential()) {
|
if (device->isSequential()) {
|
||||||
while (readBytes > 0)
|
while (readBytes > 0) {
|
||||||
device->ungetChar(head[readBytes-- - 1]);
|
device->ungetChar(head[readBytes-- - 1]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
device->seek(oldPos);
|
device->seek(oldPos);
|
||||||
}
|
}
|
||||||
@ -633,18 +659,23 @@ bool PCXHandler::canRead(QIODevice *device)
|
|||||||
|
|
||||||
QImageIOPlugin::Capabilities PCXPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
QImageIOPlugin::Capabilities PCXPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
||||||
{
|
{
|
||||||
if (format == "pcx")
|
if (format == "pcx") {
|
||||||
return Capabilities(CanRead | CanWrite);
|
return Capabilities(CanRead | CanWrite);
|
||||||
if (!format.isEmpty())
|
}
|
||||||
|
if (!format.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
if (!device->isOpen())
|
}
|
||||||
|
if (!device->isOpen()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Capabilities cap;
|
Capabilities cap;
|
||||||
if (device->isReadable() && PCXHandler::canRead(device))
|
if (device->isReadable() && PCXHandler::canRead(device)) {
|
||||||
cap |= CanRead;
|
cap |= CanRead;
|
||||||
if (device->isWritable())
|
}
|
||||||
|
if (device->isWritable()) {
|
||||||
cap |= CanWrite;
|
cap |= CanWrite;
|
||||||
|
}
|
||||||
return cap;
|
return cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -77,12 +77,15 @@ bool SoftimagePICHandler::supportsOption(ImageOption option) const
|
|||||||
|
|
||||||
QImageIOPlugin::Capabilities SoftimagePICPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
QImageIOPlugin::Capabilities SoftimagePICPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
||||||
{
|
{
|
||||||
if (format == "pic")
|
if (format == "pic") {
|
||||||
return Capabilities(CanRead | CanWrite);
|
return Capabilities(CanRead | CanWrite);
|
||||||
if (!format.isEmpty())
|
}
|
||||||
|
if (!format.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
if (!device->isOpen())
|
}
|
||||||
|
if (!device->isOpen()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Capabilities cap;
|
Capabilities cap;
|
||||||
if (device->isReadable() && SoftimagePICHandler::canRead(device)) {
|
if (device->isReadable() && SoftimagePICHandler::canRead(device)) {
|
||||||
@ -94,9 +97,9 @@ QImageIOPlugin::Capabilities SoftimagePICPlugin::capabilities(QIODevice *device,
|
|||||||
return cap;
|
return cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImageIOHandler * SoftimagePICPlugin::create(QIODevice *device, const QByteArray &format) const
|
QImageIOHandler *SoftimagePICPlugin::create(QIODevice *device, const QByteArray &format) const
|
||||||
{
|
{
|
||||||
QImageIOHandler * handler = new SoftimagePICHandler();
|
QImageIOHandler *handler = new SoftimagePICHandler();
|
||||||
handler->setDevice(device);
|
handler->setDevice(device);
|
||||||
handler->setFormat(format);
|
handler->setFormat(format);
|
||||||
return handler;
|
return handler;
|
||||||
|
|||||||
@ -27,7 +27,7 @@ class SoftimagePICHandler : public QImageIOHandler
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual bool canRead() const;
|
virtual bool canRead() const;
|
||||||
virtual bool read(QImage * image);
|
virtual bool read(QImage *image);
|
||||||
virtual bool write(const QImage &);
|
virtual bool write(const QImage &);
|
||||||
|
|
||||||
virtual QVariant option(ImageOption option) const;
|
virtual QVariant option(ImageOption option) const;
|
||||||
|
|||||||
@ -42,9 +42,9 @@ bool picReadHeader(QIODevice *dev, PICHeader *hdr, bool peek)
|
|||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
if (peek) {
|
if (peek) {
|
||||||
result = dev->peek((char*) hdr, HEADER_SIZE);
|
result = dev->peek((char *) hdr, HEADER_SIZE);
|
||||||
} else {
|
} else {
|
||||||
result = dev->read((char*) hdr, HEADER_SIZE);
|
result = dev->read((char *) hdr, HEADER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr->magic = ntohl(hdr->magic);
|
hdr->magic = ntohl(hdr->magic);
|
||||||
@ -85,7 +85,7 @@ static bool readChannels(QIODevice *dev, PICChannel *channels, int &bpp)
|
|||||||
int c = 0;
|
int c = 0;
|
||||||
memset(channels, 0, sizeof(PICChannel) * 8);
|
memset(channels, 0, sizeof(PICChannel) * 8);
|
||||||
do {
|
do {
|
||||||
int result = dev->read((char*) & channels[c], CHANNEL_SIZE);
|
int result = dev->read((char *) & channels[c], CHANNEL_SIZE);
|
||||||
if (result != CHANNEL_SIZE) {
|
if (result != CHANNEL_SIZE) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@ -164,7 +164,7 @@ static int decodeRLE(QIODevice *dev, void *row, unsigned max, unsigned bpp, unsi
|
|||||||
|
|
||||||
makeComponentMap(channels, component_map);
|
makeComponentMap(channels, component_map);
|
||||||
|
|
||||||
if (dev->read((char*) buf, 1) != 1) {
|
if (dev->read((char *) buf, 1) != 1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,16 +174,16 @@ static int decodeRLE(QIODevice *dev, void *row, unsigned max, unsigned bpp, unsi
|
|||||||
if (len > max) {
|
if (len > max) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
unsigned count = dev->read((char*) buf, bpp);
|
unsigned count = dev->read((char *) buf, bpp);
|
||||||
if (count != bpp) {
|
if (count != bpp) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < len; i++) {
|
for (unsigned i = 0; i < len; i++) {
|
||||||
pic2RGBA(buf, (unsigned char*)(ptr + i), component_map, bpp);
|
pic2RGBA(buf, (unsigned char *)(ptr + i), component_map, bpp);
|
||||||
}
|
}
|
||||||
} /* If the value is exactly 10000000, it means that it is more than 127 repetitions */
|
} /* If the value is exactly 10000000, it means that it is more than 127 repetitions */
|
||||||
else if (buf[0] == 128) {
|
else if (buf[0] == 128) {
|
||||||
unsigned count = dev->read((char*) buf, bpp + 2);
|
unsigned count = dev->read((char *) buf, bpp + 2);
|
||||||
if (count != bpp + 2) {
|
if (count != bpp + 2) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -192,7 +192,7 @@ static int decodeRLE(QIODevice *dev, void *row, unsigned max, unsigned bpp, unsi
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < len; i++) {
|
for (unsigned i = 0; i < len; i++) {
|
||||||
pic2RGBA(buf + 2, (unsigned char*)(ptr + i), component_map, bpp);
|
pic2RGBA(buf + 2, (unsigned char *)(ptr + i), component_map, bpp);
|
||||||
}
|
}
|
||||||
} /** No repetitions */
|
} /** No repetitions */
|
||||||
else {
|
else {
|
||||||
@ -200,12 +200,12 @@ static int decodeRLE(QIODevice *dev, void *row, unsigned max, unsigned bpp, unsi
|
|||||||
if (len > max) {
|
if (len > max) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
unsigned count = dev->read((char*) buf, len * bpp);
|
unsigned count = dev->read((char *) buf, len * bpp);
|
||||||
if (count != len * bpp) {
|
if (count != len * bpp) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < len; i++) {
|
for (unsigned i = 0; i < len; i++) {
|
||||||
pic2RGBA(buf + (i * bpp), (unsigned char*)(ptr + i), component_map, bpp);
|
pic2RGBA(buf + (i * bpp), (unsigned char *)(ptr + i), component_map, bpp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
@ -236,14 +236,14 @@ static bool readRow(QIODevice *dev, unsigned *row, unsigned width, PICChannel *c
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unsigned char component_map[8];
|
unsigned char component_map[8];
|
||||||
unsigned count = dev->read((char*) row, width * bpp);
|
unsigned count = dev->read((char *) row, width * bpp);
|
||||||
if (count != width * bpp) {
|
if (count != width * bpp) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
makeComponentMap(channels[c].channel, component_map);
|
makeComponentMap(channels[c].channel, component_map);
|
||||||
for (unsigned i = 0; i < width; i++) {
|
for (unsigned i = 0; i < width; i++) {
|
||||||
pic2RGBA(((unsigned char*) row) + (i * bpp), (unsigned char*)(row + i), component_map, bpp);
|
pic2RGBA(((unsigned char *) row) + (i * bpp), (unsigned char *)(row + i), component_map, bpp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,7 +281,7 @@ void pic_read(QIODevice *dev, QImage *result)
|
|||||||
QImage img(header.width, header.height, QImage::Format_ARGB32);
|
QImage img(header.width, header.height, QImage::Format_ARGB32);
|
||||||
|
|
||||||
for (int r = 0; r < header.height; r++) {
|
for (int r = 0; r < header.height; r++) {
|
||||||
unsigned *row = (unsigned*) img.scanLine(r);
|
unsigned *row = (unsigned *) img.scanLine(r);
|
||||||
std::fill(row, row + header.width, 0);
|
std::fill(row, row + header.width, 0);
|
||||||
if (!readRow(dev, row, header.width, channels)) {
|
if (!readRow(dev, row, header.width, channels)) {
|
||||||
FAIL();
|
FAIL();
|
||||||
|
|||||||
@ -90,7 +90,6 @@ typedef struct {
|
|||||||
#define HEADER_SIZE sizeof(PICHeader)
|
#define HEADER_SIZE sizeof(PICHeader)
|
||||||
#define CHANNEL_SIZE sizeof(PICChannel)
|
#define CHANNEL_SIZE sizeof(PICChannel)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the PIC header and checks that it is OK
|
* Reads the PIC header and checks that it is OK
|
||||||
* @param dev The QT device to read from
|
* @param dev The QT device to read from
|
||||||
@ -106,5 +105,4 @@ void pic_read(QIODevice *dev, QImage *img);
|
|||||||
/// Pic write handler for Qt / KDE
|
/// Pic write handler for Qt / KDE
|
||||||
void pic_write(QIODevice *dev, const QImage *img);
|
void pic_write(QIODevice *dev, const QImage *img);
|
||||||
|
|
||||||
|
|
||||||
#endif//__PIC_RW_H__
|
#endif//__PIC_RW_H__
|
||||||
|
|||||||
@ -54,7 +54,7 @@ static bool writeHeader(QIODevice *dev, std::string msg, unsigned width, unsigne
|
|||||||
h.height = htons(height);
|
h.height = htons(height);
|
||||||
h.ratio = 1.0f;
|
h.ratio = 1.0f;
|
||||||
h.fields = htons(BOTH);
|
h.fields = htons(BOTH);
|
||||||
count = dev->write((const char*) & h, sizeof(PICHeader));
|
count = dev->write((const char *) & h, sizeof(PICHeader));
|
||||||
if (count != sizeof(PICHeader)) {
|
if (count != sizeof(PICHeader)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ static bool writeHeader(QIODevice *dev, std::string msg, unsigned width, unsigne
|
|||||||
if (alpha) {
|
if (alpha) {
|
||||||
c.chained = 1;
|
c.chained = 1;
|
||||||
}
|
}
|
||||||
count = dev->write((const char*) & c, sizeof(PICChannel));
|
count = dev->write((const char *) & c, sizeof(PICChannel));
|
||||||
if (count != sizeof(PICChannel)) {
|
if (count != sizeof(PICChannel)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ static bool writeHeader(QIODevice *dev, std::string msg, unsigned width, unsigne
|
|||||||
if (alpha) {
|
if (alpha) {
|
||||||
c.channel = ALPHA;
|
c.channel = ALPHA;
|
||||||
c.chained = 0;
|
c.chained = 0;
|
||||||
count = dev->write((const char*) & c, sizeof(PICChannel));
|
count = dev->write((const char *) & c, sizeof(PICChannel));
|
||||||
if (count != sizeof(PICChannel)) {
|
if (count != sizeof(PICChannel)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -123,7 +123,7 @@ static bool encodeRLE(const unsigned *image, unsigned char *output, bool rgb, un
|
|||||||
*out++ = count >> 8;
|
*out++ = count >> 8;
|
||||||
*out++ = count & 0xFF;
|
*out++ = count & 0xFF;
|
||||||
unsigned pixel = convertABGRtoRGBA(*image);
|
unsigned pixel = convertABGRtoRGBA(*image);
|
||||||
memcpy(out, ((char*) & pixel) + offset, channels);
|
memcpy(out, ((char *) & pixel) + offset, channels);
|
||||||
out += channels;
|
out += channels;
|
||||||
oConsumed = count;
|
oConsumed = count;
|
||||||
oProduced = out - output;
|
oProduced = out - output;
|
||||||
@ -131,7 +131,7 @@ static bool encodeRLE(const unsigned *image, unsigned char *output, bool rgb, un
|
|||||||
/* Sequece of < 128 identical pixels */
|
/* Sequece of < 128 identical pixels */
|
||||||
*out++ = (count + 127);
|
*out++ = (count + 127);
|
||||||
unsigned pixel = convertABGRtoRGBA(*image);
|
unsigned pixel = convertABGRtoRGBA(*image);
|
||||||
memcpy(out, ((char*) & pixel) + offset, channels);
|
memcpy(out, ((char *) & pixel) + offset, channels);
|
||||||
out += channels;
|
out += channels;
|
||||||
oConsumed = count;
|
oConsumed = count;
|
||||||
oProduced = out - output;
|
oProduced = out - output;
|
||||||
@ -152,7 +152,7 @@ static bool encodeRLE(const unsigned *image, unsigned char *output, bool rgb, un
|
|||||||
in = image;
|
in = image;
|
||||||
for (unsigned c = 0; c < count; ++c) {
|
for (unsigned c = 0; c < count; ++c) {
|
||||||
unsigned pixel = convertABGRtoRGBA(*in);
|
unsigned pixel = convertABGRtoRGBA(*in);
|
||||||
memcpy(out, ((char*) & pixel) + offset, channels);
|
memcpy(out, ((char *) & pixel) + offset, channels);
|
||||||
out += channels;
|
out += channels;
|
||||||
in++;
|
in++;
|
||||||
}
|
}
|
||||||
@ -200,7 +200,7 @@ static bool writeRow(QIODevice *dev, unsigned *row, unsigned width, bool alpha)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->write((const char*) buf, posOut);
|
dev->write((const char *) buf, posOut);
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -220,7 +220,7 @@ void pic_write(QIODevice *dev, const QImage *img)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int r = 0; r < img->height(); r++) {
|
for (int r = 0; r < img->height(); r++) {
|
||||||
unsigned *row = (unsigned*) img->scanLine(r);
|
unsigned *row = (unsigned *) img->scanLine(r);
|
||||||
if (!writeRow(dev, row, img->width(), alpha)) {
|
if (!writeRow(dev, row, img->width(), alpha)) {
|
||||||
FAIL();
|
FAIL();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,7 +52,7 @@ struct PSDHeader {
|
|||||||
ushort color_mode;
|
ushort color_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
static QDataStream & operator>> (QDataStream & s, PSDHeader & header)
|
static QDataStream &operator>> (QDataStream &s, PSDHeader &header)
|
||||||
{
|
{
|
||||||
s >> header.signature;
|
s >> header.signature;
|
||||||
s >> header.version;
|
s >> header.version;
|
||||||
@ -66,22 +66,23 @@ static QDataStream & operator>> (QDataStream & s, PSDHeader & header)
|
|||||||
s >> header.color_mode;
|
s >> header.color_mode;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
static bool seekBy(QDataStream& s, unsigned int bytes)
|
static bool seekBy(QDataStream &s, unsigned int bytes)
|
||||||
{
|
{
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
while (bytes) {
|
while (bytes) {
|
||||||
unsigned int num = qMin(bytes, (unsigned int)sizeof(buf));
|
unsigned int num = qMin(bytes, (unsigned int)sizeof(buf));
|
||||||
unsigned int l = num;
|
unsigned int l = num;
|
||||||
s.readRawData(buf, l);
|
s.readRawData(buf, l);
|
||||||
if (l != num)
|
if (l != num) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
bytes -= num;
|
bytes -= num;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the header is a valid PSD.
|
// Check that the header is a valid PSD.
|
||||||
static bool IsValid(const PSDHeader & header)
|
static bool IsValid(const PSDHeader &header)
|
||||||
{
|
{
|
||||||
if (header.signature != 0x38425053) { // '8BPS'
|
if (header.signature != 0x38425053) { // '8BPS'
|
||||||
return false;
|
return false;
|
||||||
@ -90,7 +91,7 @@ static bool IsValid(const PSDHeader & header)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check that the header is supported.
|
// Check that the header is supported.
|
||||||
static bool IsSupported(const PSDHeader & header)
|
static bool IsSupported(const PSDHeader &header)
|
||||||
{
|
{
|
||||||
if (header.version != 1) {
|
if (header.version != 1) {
|
||||||
return false;
|
return false;
|
||||||
@ -108,7 +109,7 @@ static bool IsSupported(const PSDHeader & header)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load the PSD image.
|
// Load the PSD image.
|
||||||
static bool LoadPSD(QDataStream & s, const PSDHeader & header, QImage & img)
|
static bool LoadPSD(QDataStream &s, const PSDHeader &header, QImage &img)
|
||||||
{
|
{
|
||||||
// Create dst image.
|
// Create dst image.
|
||||||
img = QImage(header.width, header.height, QImage::Format_RGB32);
|
img = QImage(header.width, header.height, QImage::Format_RGB32);
|
||||||
@ -159,19 +160,21 @@ static bool LoadPSD(QDataStream & s, const PSDHeader & header, QImage & img)
|
|||||||
if (compression) {
|
if (compression) {
|
||||||
|
|
||||||
// Skip row lengths.
|
// Skip row lengths.
|
||||||
if (!seekBy(s, header.height * header.channel_count * sizeof(ushort)))
|
if (!seekBy(s, header.height * header.channel_count * sizeof(ushort))) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Read RLE data.
|
// Read RLE data.
|
||||||
for (uint channel = 0; channel < channel_num; channel++) {
|
for (uint channel = 0; channel < channel_num; channel++) {
|
||||||
|
|
||||||
uchar * ptr = img.bits() + components[channel];
|
uchar *ptr = img.bits() + components[channel];
|
||||||
|
|
||||||
uint count = 0;
|
uint count = 0;
|
||||||
while (count < pixel_count) {
|
while (count < pixel_count) {
|
||||||
uchar c;
|
uchar c;
|
||||||
if (s.atEnd())
|
if (s.atEnd()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
s >> c;
|
s >> c;
|
||||||
uint len = c;
|
uint len = c;
|
||||||
|
|
||||||
@ -179,8 +182,9 @@ static bool LoadPSD(QDataStream & s, const PSDHeader & header, QImage & img)
|
|||||||
// Copy next len+1 bytes literally.
|
// Copy next len+1 bytes literally.
|
||||||
len++;
|
len++;
|
||||||
count += len;
|
count += len;
|
||||||
if (count > pixel_count)
|
if (count > pixel_count) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
while (len != 0) {
|
while (len != 0) {
|
||||||
s >> *ptr;
|
s >> *ptr;
|
||||||
@ -193,8 +197,9 @@ static bool LoadPSD(QDataStream & s, const PSDHeader & header, QImage & img)
|
|||||||
len ^= 0xFF;
|
len ^= 0xFF;
|
||||||
len += 2;
|
len += 2;
|
||||||
count += len;
|
count += len;
|
||||||
if (s.atEnd() || count > pixel_count)
|
if (s.atEnd() || count > pixel_count) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
uchar val;
|
uchar val;
|
||||||
s >> val;
|
s >> val;
|
||||||
while (len != 0) {
|
while (len != 0) {
|
||||||
@ -214,7 +219,7 @@ static bool LoadPSD(QDataStream & s, const PSDHeader & header, QImage & img)
|
|||||||
// Read the data by channel.
|
// Read the data by channel.
|
||||||
for (uint channel = 0; channel < channel_num; channel++) {
|
for (uint channel = 0; channel < channel_num; channel++) {
|
||||||
|
|
||||||
uchar * ptr = img.bits() + components[channel];
|
uchar *ptr = img.bits() + components[channel];
|
||||||
|
|
||||||
// Read the data.
|
// Read the data.
|
||||||
uint count = pixel_count;
|
uint count = pixel_count;
|
||||||
@ -231,7 +236,6 @@ static bool LoadPSD(QDataStream & s, const PSDHeader & header, QImage & img)
|
|||||||
|
|
||||||
} // Private
|
} // Private
|
||||||
|
|
||||||
|
|
||||||
PSDHandler::PSDHandler()
|
PSDHandler::PSDHandler()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -288,8 +292,9 @@ bool PSDHandler::canRead(QIODevice *device)
|
|||||||
qint64 readBytes = device->read(head, sizeof(head));
|
qint64 readBytes = device->read(head, sizeof(head));
|
||||||
if (readBytes != sizeof(head)) {
|
if (readBytes != sizeof(head)) {
|
||||||
if (device->isSequential()) {
|
if (device->isSequential()) {
|
||||||
while (readBytes > 0)
|
while (readBytes > 0) {
|
||||||
device->ungetChar(head[readBytes-- - 1]);
|
device->ungetChar(head[readBytes-- - 1]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
device->seek(oldPos);
|
device->seek(oldPos);
|
||||||
}
|
}
|
||||||
@ -297,8 +302,9 @@ bool PSDHandler::canRead(QIODevice *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (device->isSequential()) {
|
if (device->isSequential()) {
|
||||||
while (readBytes > 0)
|
while (readBytes > 0) {
|
||||||
device->ungetChar(head[readBytes-- - 1]);
|
device->ungetChar(head[readBytes-- - 1]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
device->seek(oldPos);
|
device->seek(oldPos);
|
||||||
}
|
}
|
||||||
@ -308,16 +314,20 @@ bool PSDHandler::canRead(QIODevice *device)
|
|||||||
|
|
||||||
QImageIOPlugin::Capabilities PSDPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
QImageIOPlugin::Capabilities PSDPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
||||||
{
|
{
|
||||||
if (format == "psd")
|
if (format == "psd") {
|
||||||
return Capabilities(CanRead);
|
return Capabilities(CanRead);
|
||||||
if (!format.isEmpty())
|
}
|
||||||
|
if (!format.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
if (!device->isOpen())
|
}
|
||||||
|
if (!device->isOpen()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Capabilities cap;
|
Capabilities cap;
|
||||||
if (device->isReadable() && PSDHandler::canRead(device))
|
if (device->isReadable() && PSDHandler::canRead(device)) {
|
||||||
cap |= CanRead;
|
cap |= CanRead;
|
||||||
|
}
|
||||||
return cap;
|
return cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -51,7 +51,7 @@ struct RasHeader {
|
|||||||
enum { SIZE = 32 }; // 8 fields of four bytes each
|
enum { SIZE = 32 }; // 8 fields of four bytes each
|
||||||
};
|
};
|
||||||
|
|
||||||
static QDataStream & operator>> (QDataStream & s, RasHeader & head)
|
static QDataStream &operator>> (QDataStream &s, RasHeader &head)
|
||||||
{
|
{
|
||||||
s >> head.MagicNumber;
|
s >> head.MagicNumber;
|
||||||
s >> head.Width;
|
s >> head.Width;
|
||||||
@ -72,7 +72,7 @@ static QDataStream & operator>> (QDataStream & s, RasHeader & head)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsSupported(const RasHeader & head)
|
static bool IsSupported(const RasHeader &head)
|
||||||
{
|
{
|
||||||
// check magic number
|
// check magic number
|
||||||
if (head.MagicNumber != rasMagicBigEndian) {
|
if (head.MagicNumber != rasMagicBigEndian) {
|
||||||
@ -99,7 +99,7 @@ static bool IsSupported(const RasHeader & head)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LoadRAS(QDataStream & s, const RasHeader & ras, QImage &img)
|
static bool LoadRAS(QDataStream &s, const RasHeader &ras, QImage &img)
|
||||||
{
|
{
|
||||||
s.device()->seek(RasHeader::SIZE);
|
s.device()->seek(RasHeader::SIZE);
|
||||||
// Read palette if needed.
|
// Read palette if needed.
|
||||||
@ -278,16 +278,20 @@ bool RASHandler::read(QImage *outImage)
|
|||||||
QImageIOPlugin::Capabilities RASPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
QImageIOPlugin::Capabilities RASPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
||||||
{
|
{
|
||||||
|
|
||||||
if (format == "ras")
|
if (format == "ras") {
|
||||||
return Capabilities(CanRead);
|
return Capabilities(CanRead);
|
||||||
if (!format.isEmpty())
|
}
|
||||||
|
if (!format.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
if (!device->isOpen())
|
}
|
||||||
|
if (!device->isOpen()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Capabilities cap;
|
Capabilities cap;
|
||||||
if (device->isReadable() && RASHandler::canRead(device))
|
if (device->isReadable() && RASHandler::canRead(device)) {
|
||||||
cap |= CanRead;
|
cap |= CanRead;
|
||||||
|
}
|
||||||
return cap;
|
return cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,6 @@
|
|||||||
// published by the Free Software Foundation; either version 2 of the
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
// License, or (at your option) any later version.
|
// License, or (at your option) any later version.
|
||||||
|
|
||||||
|
|
||||||
/* this code supports:
|
/* this code supports:
|
||||||
* reading:
|
* reading:
|
||||||
* everything, except images with 1 dimension or images with
|
* everything, except images with 1 dimension or images with
|
||||||
@ -34,13 +33,16 @@ class RLEData : public QVector<uchar>
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RLEData() {}
|
RLEData() {}
|
||||||
RLEData(const uchar *d, uint l, uint o) : _offset(o) {
|
RLEData(const uchar *d, uint l, uint o) : _offset(o)
|
||||||
for (uint i = 0; i < l; i++)
|
{
|
||||||
|
for (uint i = 0; i < l; i++) {
|
||||||
append(d[i]);
|
append(d[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bool operator<(const RLEData&) const;
|
bool operator<(const RLEData &) const;
|
||||||
void write(QDataStream& s);
|
void write(QDataStream &s);
|
||||||
uint offset() const {
|
uint offset() const
|
||||||
|
{
|
||||||
return _offset;
|
return _offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,14 +50,14 @@ private:
|
|||||||
uint _offset;
|
uint _offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class RLEMap : public QMap<RLEData, uint>
|
class RLEMap : public QMap<RLEData, uint>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RLEMap() : _counter(0), _offset(0) {}
|
RLEMap() : _counter(0), _offset(0) {}
|
||||||
uint insert(const uchar *d, uint l);
|
uint insert(const uchar *d, uint l);
|
||||||
QVector<const RLEData*> vector();
|
QVector<const RLEData *> vector();
|
||||||
void setBaseOffset(uint o) {
|
void setBaseOffset(uint o)
|
||||||
|
{
|
||||||
_offset = o;
|
_offset = o;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,15 +66,14 @@ private:
|
|||||||
uint _offset;
|
uint _offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class SGIImage
|
class SGIImage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SGIImage(QIODevice *device);
|
SGIImage(QIODevice *device);
|
||||||
~SGIImage();
|
~SGIImage();
|
||||||
|
|
||||||
bool readImage(QImage&);
|
bool readImage(QImage &);
|
||||||
bool writeImage(const QImage&);
|
bool writeImage(const QImage &);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum { NORMAL, DITHERED, SCREEN, COLORMAP }; // colormap
|
enum { NORMAL, DITHERED, SCREEN, COLORMAP }; // colormap
|
||||||
@ -95,16 +96,16 @@ private:
|
|||||||
QByteArray _data;
|
QByteArray _data;
|
||||||
QByteArray::Iterator _pos;
|
QByteArray::Iterator _pos;
|
||||||
RLEMap _rlemap;
|
RLEMap _rlemap;
|
||||||
QVector<const RLEData*> _rlevector;
|
QVector<const RLEData *> _rlevector;
|
||||||
uint _numrows;
|
uint _numrows;
|
||||||
|
|
||||||
bool readData(QImage&);
|
bool readData(QImage &);
|
||||||
bool getRow(uchar *dest);
|
bool getRow(uchar *dest);
|
||||||
|
|
||||||
void writeHeader();
|
void writeHeader();
|
||||||
void writeRle();
|
void writeRle();
|
||||||
void writeVerbatim(const QImage&);
|
void writeVerbatim(const QImage &);
|
||||||
bool scanData(const QImage&);
|
bool scanData(const QImage &);
|
||||||
uint compact(uchar *, uchar *);
|
uint compact(uchar *, uchar *);
|
||||||
uchar intensity(uchar);
|
uchar intensity(uchar);
|
||||||
};
|
};
|
||||||
@ -117,24 +118,22 @@ SGIImage::SGIImage(QIODevice *io) :
|
|||||||
_stream.setDevice(_dev);
|
_stream.setDevice(_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SGIImage::~SGIImage()
|
SGIImage::~SGIImage()
|
||||||
{
|
{
|
||||||
delete[] _starttab;
|
delete[] _starttab;
|
||||||
delete[] _lengthtab;
|
delete[] _lengthtab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
bool SGIImage::getRow(uchar *dest)
|
bool SGIImage::getRow(uchar *dest)
|
||||||
{
|
{
|
||||||
int n, i;
|
int n, i;
|
||||||
if (!_rle) {
|
if (!_rle) {
|
||||||
for (i = 0; i < _xsize; i++) {
|
for (i = 0; i < _xsize; i++) {
|
||||||
if (_pos >= _data.end())
|
if (_pos >= _data.end()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
dest[i] = uchar(*_pos);
|
dest[i] = uchar(*_pos);
|
||||||
_pos += _bpc;
|
_pos += _bpc;
|
||||||
}
|
}
|
||||||
@ -142,11 +141,13 @@ bool SGIImage::getRow(uchar *dest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < _xsize;) {
|
for (i = 0; i < _xsize;) {
|
||||||
if (_bpc == 2)
|
if (_bpc == 2) {
|
||||||
_pos++;
|
_pos++;
|
||||||
|
}
|
||||||
n = *_pos & 0x7f;
|
n = *_pos & 0x7f;
|
||||||
if (!n)
|
if (!n) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (*_pos++ & 0x80) {
|
if (*_pos++ & 0x80) {
|
||||||
for (; i < _xsize && n--; i++) {
|
for (; i < _xsize && n--; i++) {
|
||||||
@ -154,8 +155,9 @@ bool SGIImage::getRow(uchar *dest)
|
|||||||
_pos += _bpc;
|
_pos += _bpc;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (; i < _xsize && n--; i++)
|
for (; i < _xsize && n--; i++) {
|
||||||
*dest++ = *_pos;
|
*dest++ = *_pos;
|
||||||
|
}
|
||||||
|
|
||||||
_pos += _bpc;
|
_pos += _bpc;
|
||||||
}
|
}
|
||||||
@ -163,8 +165,7 @@ bool SGIImage::getRow(uchar *dest)
|
|||||||
return i == _xsize;
|
return i == _xsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SGIImage::readData(QImage &img)
|
||||||
bool SGIImage::readData(QImage& img)
|
|
||||||
{
|
{
|
||||||
QRgb *c;
|
QRgb *c;
|
||||||
quint32 *start = _starttab;
|
quint32 *start = _starttab;
|
||||||
@ -172,62 +173,76 @@ bool SGIImage::readData(QImage& img)
|
|||||||
uchar *line = (uchar *)lguard.data();
|
uchar *line = (uchar *)lguard.data();
|
||||||
unsigned x, y;
|
unsigned x, y;
|
||||||
|
|
||||||
if (!_rle)
|
if (!_rle) {
|
||||||
_pos = _data.begin();
|
_pos = _data.begin();
|
||||||
|
|
||||||
for (y = 0; y < _ysize; y++) {
|
|
||||||
if (_rle)
|
|
||||||
_pos = _data.begin() + *start++;
|
|
||||||
if (!getRow(line))
|
|
||||||
return false;
|
|
||||||
c = (QRgb *)img.scanLine(_ysize - y - 1);
|
|
||||||
for (x = 0; x < _xsize; x++, c++)
|
|
||||||
*c = qRgb(line[x], line[x], line[x]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_zsize == 1)
|
for (y = 0; y < _ysize; y++) {
|
||||||
|
if (_rle) {
|
||||||
|
_pos = _data.begin() + *start++;
|
||||||
|
}
|
||||||
|
if (!getRow(line)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
c = (QRgb *)img.scanLine(_ysize - y - 1);
|
||||||
|
for (x = 0; x < _xsize; x++, c++) {
|
||||||
|
*c = qRgb(line[x], line[x], line[x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_zsize == 1) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (_zsize != 2) {
|
if (_zsize != 2) {
|
||||||
for (y = 0; y < _ysize; y++) {
|
for (y = 0; y < _ysize; y++) {
|
||||||
if (_rle)
|
if (_rle) {
|
||||||
_pos = _data.begin() + *start++;
|
_pos = _data.begin() + *start++;
|
||||||
if (!getRow(line))
|
}
|
||||||
|
if (!getRow(line)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
c = (QRgb *)img.scanLine(_ysize - y - 1);
|
c = (QRgb *)img.scanLine(_ysize - y - 1);
|
||||||
for (x = 0; x < _xsize; x++, c++)
|
for (x = 0; x < _xsize; x++, c++) {
|
||||||
*c = qRgb(qRed(*c), line[x], line[x]);
|
*c = qRgb(qRed(*c), line[x], line[x]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (y = 0; y < _ysize; y++) {
|
for (y = 0; y < _ysize; y++) {
|
||||||
if (_rle)
|
if (_rle) {
|
||||||
_pos = _data.begin() + *start++;
|
_pos = _data.begin() + *start++;
|
||||||
if (!getRow(line))
|
}
|
||||||
|
if (!getRow(line)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
c = (QRgb *)img.scanLine(_ysize - y - 1);
|
c = (QRgb *)img.scanLine(_ysize - y - 1);
|
||||||
for (x = 0; x < _xsize; x++, c++)
|
for (x = 0; x < _xsize; x++, c++) {
|
||||||
*c = qRgb(qRed(*c), qGreen(*c), line[x]);
|
*c = qRgb(qRed(*c), qGreen(*c), line[x]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_zsize == 3)
|
if (_zsize == 3) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (y = 0; y < _ysize; y++) {
|
for (y = 0; y < _ysize; y++) {
|
||||||
if (_rle)
|
if (_rle) {
|
||||||
_pos = _data.begin() + *start++;
|
_pos = _data.begin() + *start++;
|
||||||
if (!getRow(line))
|
}
|
||||||
|
if (!getRow(line)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
c = (QRgb *)img.scanLine(_ysize - y - 1);
|
c = (QRgb *)img.scanLine(_ysize - y - 1);
|
||||||
for (x = 0; x < _xsize; x++, c++)
|
for (x = 0; x < _xsize; x++, c++) {
|
||||||
*c = qRgba(qRed(*c), qGreen(*c), qBlue(*c), line[x]);
|
*c = qRgba(qRed(*c), qGreen(*c), qBlue(*c), line[x]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SGIImage::readImage(QImage &img)
|
||||||
bool SGIImage::readImage(QImage& img)
|
|
||||||
{
|
{
|
||||||
qint8 u8;
|
qint8 u8;
|
||||||
qint16 u16;
|
qint16 u16;
|
||||||
@ -237,14 +252,16 @@ bool SGIImage::readImage(QImage& img)
|
|||||||
|
|
||||||
// magic
|
// magic
|
||||||
_stream >> u16;
|
_stream >> u16;
|
||||||
if (u16 != 0x01da)
|
if (u16 != 0x01da) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// verbatim/rle
|
// verbatim/rle
|
||||||
_stream >> _rle;
|
_stream >> _rle;
|
||||||
// qDebug() << (_rle ? "RLE" : "verbatim");
|
// qDebug() << (_rle ? "RLE" : "verbatim");
|
||||||
if (_rle > 1)
|
if (_rle > 1) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// bytes per channel
|
// bytes per channel
|
||||||
_stream >> _bpc;
|
_stream >> _bpc;
|
||||||
@ -253,14 +270,16 @@ bool SGIImage::readImage(QImage& img)
|
|||||||
;
|
;
|
||||||
else if (_bpc == 2) {
|
else if (_bpc == 2) {
|
||||||
// qDebug() << "dropping least significant byte";
|
// qDebug() << "dropping least significant byte";
|
||||||
} else
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// number of dimensions
|
// number of dimensions
|
||||||
_stream >> _dim;
|
_stream >> _dim;
|
||||||
// qDebug() << "dimensions: " << _dim;
|
// qDebug() << "dimensions: " << _dim;
|
||||||
if (_dim < 1 || _dim > 3)
|
if (_dim < 1 || _dim > 3) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
_stream >> _xsize >> _ysize >> _zsize >> _pixmin >> _pixmax >> u32;
|
_stream >> _xsize >> _ysize >> _zsize >> _pixmin >> _pixmax >> u32;
|
||||||
// qDebug() << "x: " << _xsize;
|
// qDebug() << "x: " << _xsize;
|
||||||
@ -273,27 +292,30 @@ bool SGIImage::readImage(QImage& img)
|
|||||||
|
|
||||||
_stream >> _colormap;
|
_stream >> _colormap;
|
||||||
// qDebug() << "colormap: " << _colormap;
|
// qDebug() << "colormap: " << _colormap;
|
||||||
if (_colormap != NORMAL)
|
if (_colormap != NORMAL) {
|
||||||
return false; // only NORMAL supported
|
return false; // only NORMAL supported
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 404; i++)
|
for (int i = 0; i < 404; i++) {
|
||||||
_stream >> u8;
|
_stream >> u8;
|
||||||
|
}
|
||||||
|
|
||||||
if (_dim == 1) {
|
if (_dim == 1) {
|
||||||
// qDebug() << "1-dimensional images aren't supported yet";
|
// qDebug() << "1-dimensional images aren't supported yet";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_stream.atEnd())
|
if (_stream.atEnd()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
_numrows = _ysize * _zsize;
|
_numrows = _ysize * _zsize;
|
||||||
|
|
||||||
img = QImage(_xsize, _ysize, QImage::Format_RGB32);
|
img = QImage(_xsize, _ysize, QImage::Format_RGB32);
|
||||||
|
|
||||||
if (_zsize == 2 || _zsize == 4)
|
if (_zsize == 2 || _zsize == 4) {
|
||||||
img = img.convertToFormat(QImage::Format_ARGB32);
|
img = img.convertToFormat(QImage::Format_ARGB32);
|
||||||
else if (_zsize > 4) {
|
} else if (_zsize > 4) {
|
||||||
// qDebug() << "using first 4 of " << _zsize << " channels";
|
// qDebug() << "using first 4 of " << _zsize << " channels";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,8 +328,9 @@ bool SGIImage::readImage(QImage& img)
|
|||||||
}
|
}
|
||||||
|
|
||||||
_lengthtab = new quint32[_numrows];
|
_lengthtab = new quint32[_numrows];
|
||||||
for (l = 0; l < _numrows; l++)
|
for (l = 0; l < _numrows; l++) {
|
||||||
_stream >> _lengthtab[l];
|
_stream >> _lengthtab[l];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_data = _dev->readAll();
|
_data = _dev->readAll();
|
||||||
@ -329,84 +352,87 @@ bool SGIImage::readImage(QImage& img)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void RLEData::write(QDataStream &s)
|
||||||
void RLEData::write(QDataStream& s)
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < size(); i++)
|
for (int i = 0; i < size(); i++) {
|
||||||
s << at(i);
|
s << at(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RLEData::operator<(const RLEData &b) const
|
||||||
bool RLEData::operator<(const RLEData& b) const
|
|
||||||
{
|
{
|
||||||
uchar ac, bc;
|
uchar ac, bc;
|
||||||
for (int i = 0; i < qMin(size(), b.size()); i++) {
|
for (int i = 0; i < qMin(size(), b.size()); i++) {
|
||||||
ac = at(i);
|
ac = at(i);
|
||||||
bc = b[i];
|
bc = b[i];
|
||||||
if (ac != bc)
|
if (ac != bc) {
|
||||||
return ac < bc;
|
return ac < bc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return size() < b.size();
|
return size() < b.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint RLEMap::insert(const uchar *d, uint l)
|
uint RLEMap::insert(const uchar *d, uint l)
|
||||||
{
|
{
|
||||||
RLEData data = RLEData(d, l, _offset);
|
RLEData data = RLEData(d, l, _offset);
|
||||||
Iterator it = find(data);
|
Iterator it = find(data);
|
||||||
if (it != end())
|
if (it != end()) {
|
||||||
return it.value();
|
return it.value();
|
||||||
|
}
|
||||||
|
|
||||||
_offset += l;
|
_offset += l;
|
||||||
return QMap<RLEData, uint>::insert(data, _counter++).value();
|
return QMap<RLEData, uint>::insert(data, _counter++).value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<const RLEData *> RLEMap::vector()
|
||||||
QVector<const RLEData*> RLEMap::vector()
|
|
||||||
{
|
{
|
||||||
QVector<const RLEData*> v(size());
|
QVector<const RLEData *> v(size());
|
||||||
for (Iterator it = begin(); it != end(); ++it)
|
for (Iterator it = begin(); it != end(); ++it) {
|
||||||
v.replace(it.value(), &it.key());
|
v.replace(it.value(), &it.key());
|
||||||
|
}
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uchar SGIImage::intensity(uchar c)
|
uchar SGIImage::intensity(uchar c)
|
||||||
{
|
{
|
||||||
if (c < _pixmin)
|
if (c < _pixmin) {
|
||||||
_pixmin = c;
|
_pixmin = c;
|
||||||
if (c > _pixmax)
|
}
|
||||||
|
if (c > _pixmax) {
|
||||||
_pixmax = c;
|
_pixmax = c;
|
||||||
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint SGIImage::compact(uchar *d, uchar *s)
|
uint SGIImage::compact(uchar *d, uchar *s)
|
||||||
{
|
{
|
||||||
uchar *dest = d, *src = s, patt, *t, *end = s + _xsize;
|
uchar *dest = d, *src = s, patt, *t, *end = s + _xsize;
|
||||||
int i, n;
|
int i, n;
|
||||||
while (src < end) {
|
while (src < end) {
|
||||||
for (n = 0, t = src; t + 2 < end && !(*t == t[1] && *t == t[2]); t++)
|
for (n = 0, t = src; t + 2 < end && !(*t == t[1] && *t == t[2]); t++) {
|
||||||
n++;
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
while (n) {
|
while (n) {
|
||||||
i = n > 126 ? 126 : n;
|
i = n > 126 ? 126 : n;
|
||||||
n -= i;
|
n -= i;
|
||||||
*dest++ = 0x80 | i;
|
*dest++ = 0x80 | i;
|
||||||
while (i--)
|
while (i--) {
|
||||||
*dest++ = *src++;
|
*dest++ = *src++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src == end)
|
if (src == end) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
patt = *src++;
|
patt = *src++;
|
||||||
for (n = 1; src < end && *src == patt; src++)
|
for (n = 1; src < end && *src == patt; src++) {
|
||||||
n++;
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
while (n) {
|
while (n) {
|
||||||
i = n > 126 ? 126 : n;
|
i = n > 126 ? 126 : n;
|
||||||
@ -419,8 +445,7 @@ uint SGIImage::compact(uchar *d, uchar *s)
|
|||||||
return dest - d;
|
return dest - d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SGIImage::scanData(const QImage &img)
|
||||||
bool SGIImage::scanData(const QImage& img)
|
|
||||||
{
|
{
|
||||||
quint32 *start = _starttab;
|
quint32 *start = _starttab;
|
||||||
QByteArray lineguard(_xsize * 2, 0);
|
QByteArray lineguard(_xsize * 2, 0);
|
||||||
@ -433,40 +458,46 @@ bool SGIImage::scanData(const QImage& img)
|
|||||||
|
|
||||||
for (y = 0; y < _ysize; y++) {
|
for (y = 0; y < _ysize; y++) {
|
||||||
c = reinterpret_cast<const QRgb *>(img.scanLine(_ysize - y - 1));
|
c = reinterpret_cast<const QRgb *>(img.scanLine(_ysize - y - 1));
|
||||||
for (x = 0; x < _xsize; x++)
|
for (x = 0; x < _xsize; x++) {
|
||||||
buf[x] = intensity(qRed(*c++));
|
buf[x] = intensity(qRed(*c++));
|
||||||
|
}
|
||||||
len = compact(line, buf);
|
len = compact(line, buf);
|
||||||
*start++ = _rlemap.insert(line, len);
|
*start++ = _rlemap.insert(line, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_zsize == 1)
|
if (_zsize == 1) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (_zsize != 2) {
|
if (_zsize != 2) {
|
||||||
for (y = 0; y < _ysize; y++) {
|
for (y = 0; y < _ysize; y++) {
|
||||||
c = reinterpret_cast<const QRgb *>(img.scanLine(_ysize - y - 1));
|
c = reinterpret_cast<const QRgb *>(img.scanLine(_ysize - y - 1));
|
||||||
for (x = 0; x < _xsize; x++)
|
for (x = 0; x < _xsize; x++) {
|
||||||
buf[x] = intensity(qGreen(*c++));
|
buf[x] = intensity(qGreen(*c++));
|
||||||
|
}
|
||||||
len = compact(line, buf);
|
len = compact(line, buf);
|
||||||
*start++ = _rlemap.insert(line, len);
|
*start++ = _rlemap.insert(line, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (y = 0; y < _ysize; y++) {
|
for (y = 0; y < _ysize; y++) {
|
||||||
c = reinterpret_cast<const QRgb *>(img.scanLine(_ysize - y - 1));
|
c = reinterpret_cast<const QRgb *>(img.scanLine(_ysize - y - 1));
|
||||||
for (x = 0; x < _xsize; x++)
|
for (x = 0; x < _xsize; x++) {
|
||||||
buf[x] = intensity(qBlue(*c++));
|
buf[x] = intensity(qBlue(*c++));
|
||||||
|
}
|
||||||
len = compact(line, buf);
|
len = compact(line, buf);
|
||||||
*start++ = _rlemap.insert(line, len);
|
*start++ = _rlemap.insert(line, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_zsize == 3)
|
if (_zsize == 3) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (y = 0; y < _ysize; y++) {
|
for (y = 0; y < _ysize; y++) {
|
||||||
c = reinterpret_cast<const QRgb *>(img.scanLine(_ysize - y - 1));
|
c = reinterpret_cast<const QRgb *>(img.scanLine(_ysize - y - 1));
|
||||||
for (x = 0; x < _xsize; x++)
|
for (x = 0; x < _xsize; x++) {
|
||||||
buf[x] = intensity(qAlpha(*c++));
|
buf[x] = intensity(qAlpha(*c++));
|
||||||
|
}
|
||||||
len = compact(line, buf);
|
len = compact(line, buf);
|
||||||
*start++ = _rlemap.insert(line, len);
|
*start++ = _rlemap.insert(line, len);
|
||||||
}
|
}
|
||||||
@ -474,7 +505,6 @@ bool SGIImage::scanData(const QImage& img)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SGIImage::writeHeader()
|
void SGIImage::writeHeader()
|
||||||
{
|
{
|
||||||
_stream << quint16(0x01da);
|
_stream << quint16(0x01da);
|
||||||
@ -483,16 +513,17 @@ void SGIImage::writeHeader()
|
|||||||
_stream << _pixmin << _pixmax;
|
_stream << _pixmin << _pixmax;
|
||||||
_stream << quint32(0);
|
_stream << quint32(0);
|
||||||
|
|
||||||
for (int i = 0; i < 80; i++)
|
for (int i = 0; i < 80; i++) {
|
||||||
_imagename[i] = '\0';
|
_imagename[i] = '\0';
|
||||||
|
}
|
||||||
_stream.writeRawData(_imagename, 80);
|
_stream.writeRawData(_imagename, 80);
|
||||||
|
|
||||||
_stream << _colormap;
|
_stream << _colormap;
|
||||||
for (int i = 0; i < 404; i++)
|
for (int i = 0; i < 404; i++) {
|
||||||
_stream << quint8(0);
|
_stream << quint8(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SGIImage::writeRle()
|
void SGIImage::writeRle()
|
||||||
{
|
{
|
||||||
_rle = 1;
|
_rle = 1;
|
||||||
@ -501,20 +532,22 @@ void SGIImage::writeRle()
|
|||||||
uint i;
|
uint i;
|
||||||
|
|
||||||
// write start table
|
// write start table
|
||||||
for (i = 0; i < _numrows; i++)
|
for (i = 0; i < _numrows; i++) {
|
||||||
_stream << quint32(_rlevector[_starttab[i]]->offset());
|
_stream << quint32(_rlevector[_starttab[i]]->offset());
|
||||||
|
}
|
||||||
|
|
||||||
// write length table
|
// write length table
|
||||||
for (i = 0; i < _numrows; i++)
|
for (i = 0; i < _numrows; i++) {
|
||||||
_stream << quint32(_rlevector[_starttab[i]]->size());
|
_stream << quint32(_rlevector[_starttab[i]]->size());
|
||||||
|
}
|
||||||
|
|
||||||
// write data
|
// write data
|
||||||
for (i = 0; (int)i < _rlevector.size(); i++)
|
for (i = 0; (int)i < _rlevector.size(); i++) {
|
||||||
const_cast<RLEData*>(_rlevector[i])->write(_stream);
|
const_cast<RLEData *>(_rlevector[i])->write(_stream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SGIImage::writeVerbatim(const QImage &img)
|
||||||
void SGIImage::writeVerbatim(const QImage& img)
|
|
||||||
{
|
{
|
||||||
_rle = 0;
|
_rle = 0;
|
||||||
// qDebug() << "writing verbatim data";
|
// qDebug() << "writing verbatim data";
|
||||||
@ -525,49 +558,56 @@ void SGIImage::writeVerbatim(const QImage& img)
|
|||||||
|
|
||||||
for (y = 0; y < _ysize; y++) {
|
for (y = 0; y < _ysize; y++) {
|
||||||
c = reinterpret_cast<const QRgb *>(img.scanLine(_ysize - y - 1));
|
c = reinterpret_cast<const QRgb *>(img.scanLine(_ysize - y - 1));
|
||||||
for (x = 0; x < _xsize; x++)
|
for (x = 0; x < _xsize; x++) {
|
||||||
_stream << quint8(qRed(*c++));
|
_stream << quint8(qRed(*c++));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_zsize == 1)
|
if (_zsize == 1) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_zsize != 2) {
|
if (_zsize != 2) {
|
||||||
for (y = 0; y < _ysize; y++) {
|
for (y = 0; y < _ysize; y++) {
|
||||||
c = reinterpret_cast<const QRgb *>(img.scanLine(_ysize - y - 1));
|
c = reinterpret_cast<const QRgb *>(img.scanLine(_ysize - y - 1));
|
||||||
for (x = 0; x < _xsize; x++)
|
for (x = 0; x < _xsize; x++) {
|
||||||
_stream << quint8(qGreen(*c++));
|
_stream << quint8(qGreen(*c++));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (y = 0; y < _ysize; y++) {
|
for (y = 0; y < _ysize; y++) {
|
||||||
c = reinterpret_cast<const QRgb *>(img.scanLine(_ysize - y - 1));
|
c = reinterpret_cast<const QRgb *>(img.scanLine(_ysize - y - 1));
|
||||||
for (x = 0; x < _xsize; x++)
|
for (x = 0; x < _xsize; x++) {
|
||||||
_stream << quint8(qBlue(*c++));
|
_stream << quint8(qBlue(*c++));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_zsize == 3)
|
if (_zsize == 3) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (y = 0; y < _ysize; y++) {
|
for (y = 0; y < _ysize; y++) {
|
||||||
c = reinterpret_cast<const QRgb *>(img.scanLine(_ysize - y - 1));
|
c = reinterpret_cast<const QRgb *>(img.scanLine(_ysize - y - 1));
|
||||||
for (x = 0; x < _xsize; x++)
|
for (x = 0; x < _xsize; x++) {
|
||||||
_stream << quint8(qAlpha(*c++));
|
_stream << quint8(qAlpha(*c++));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SGIImage::writeImage(const QImage &image)
|
||||||
bool SGIImage::writeImage(const QImage& image)
|
|
||||||
{
|
{
|
||||||
// qDebug() << "writing "; // TODO add filename
|
// qDebug() << "writing "; // TODO add filename
|
||||||
QImage img = image;
|
QImage img = image;
|
||||||
if (img.allGray())
|
if (img.allGray()) {
|
||||||
_dim = 2, _zsize = 1;
|
_dim = 2, _zsize = 1;
|
||||||
else
|
} else {
|
||||||
_dim = 3, _zsize = 3;
|
_dim = 3, _zsize = 3;
|
||||||
|
}
|
||||||
|
|
||||||
if (img.format() == QImage::Format_ARGB32)
|
if (img.format() == QImage::Format_ARGB32) {
|
||||||
_dim = 3, _zsize++;
|
_dim = 3, _zsize++;
|
||||||
|
}
|
||||||
|
|
||||||
img = img.convertToFormat(QImage::Format_RGB32);
|
img = img.convertToFormat(QImage::Format_RGB32);
|
||||||
if (img.isNull()) {
|
if (img.isNull()) {
|
||||||
@ -594,8 +634,9 @@ bool SGIImage::writeImage(const QImage& image)
|
|||||||
|
|
||||||
long verbatim_size = _numrows * _xsize;
|
long verbatim_size = _numrows * _xsize;
|
||||||
long rle_size = _numrows * 2 * sizeof(quint32);
|
long rle_size = _numrows * 2 * sizeof(quint32);
|
||||||
for (int i = 0; i < _rlevector.size(); i++)
|
for (int i = 0; i < _rlevector.size(); i++) {
|
||||||
rle_size += _rlevector[i]->size();
|
rle_size += _rlevector[i]->size();
|
||||||
|
}
|
||||||
|
|
||||||
// qDebug() << "minimum intensity: " << _pixmin;
|
// qDebug() << "minimum intensity: " << _pixmin;
|
||||||
// qDebug() << "maximum intensity: " << _pixmax;
|
// qDebug() << "maximum intensity: " << _pixmax;
|
||||||
@ -603,22 +644,20 @@ bool SGIImage::writeImage(const QImage& image)
|
|||||||
// qDebug() << "total savings: " << (verbatim_size - rle_size) << " bytes";
|
// qDebug() << "total savings: " << (verbatim_size - rle_size) << " bytes";
|
||||||
// qDebug() << "compression: " << (rle_size * 100.0 / verbatim_size) << '%';
|
// qDebug() << "compression: " << (rle_size * 100.0 / verbatim_size) << '%';
|
||||||
|
|
||||||
if (verbatim_size <= rle_size)
|
if (verbatim_size <= rle_size) {
|
||||||
writeVerbatim(img);
|
writeVerbatim(img);
|
||||||
else
|
} else {
|
||||||
writeRle();
|
writeRle();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
RGBHandler::RGBHandler()
|
RGBHandler::RGBHandler()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool RGBHandler::canRead() const
|
bool RGBHandler::canRead() const
|
||||||
{
|
{
|
||||||
if (canRead(device())) {
|
if (canRead(device())) {
|
||||||
@ -628,21 +667,18 @@ bool RGBHandler::canRead() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool RGBHandler::read(QImage *outImage)
|
bool RGBHandler::read(QImage *outImage)
|
||||||
{
|
{
|
||||||
SGIImage sgi(device());
|
SGIImage sgi(device());
|
||||||
return sgi.readImage(*outImage);
|
return sgi.readImage(*outImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool RGBHandler::write(const QImage &image)
|
bool RGBHandler::write(const QImage &image)
|
||||||
{
|
{
|
||||||
SGIImage sgi(device());
|
SGIImage sgi(device());
|
||||||
return sgi.writeImage(image);
|
return sgi.writeImage(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool RGBHandler::canRead(QIODevice *device)
|
bool RGBHandler::canRead(QIODevice *device)
|
||||||
{
|
{
|
||||||
if (!device) {
|
if (!device) {
|
||||||
@ -655,8 +691,9 @@ bool RGBHandler::canRead(QIODevice *device)
|
|||||||
int readBytes = head.size();
|
int readBytes = head.size();
|
||||||
|
|
||||||
if (device->isSequential()) {
|
if (device->isSequential()) {
|
||||||
while (readBytes > 0)
|
while (readBytes > 0) {
|
||||||
device->ungetChar(head[readBytes-- - 1]);
|
device->ungetChar(head[readBytes-- - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
device->seek(oldPos);
|
device->seek(oldPos);
|
||||||
@ -668,29 +705,31 @@ bool RGBHandler::canRead(QIODevice *device)
|
|||||||
return data.contains(regexp);
|
return data.contains(regexp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
QImageIOPlugin::Capabilities RGBPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
QImageIOPlugin::Capabilities RGBPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
||||||
{
|
{
|
||||||
if (format == "rgb" || format == "rgba" ||
|
if (format == "rgb" || format == "rgba" ||
|
||||||
format == "bw" || format == "sgi")
|
format == "bw" || format == "sgi") {
|
||||||
return Capabilities(CanRead | CanWrite);
|
return Capabilities(CanRead | CanWrite);
|
||||||
if (!format.isEmpty())
|
}
|
||||||
|
if (!format.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
if (!device->isOpen())
|
}
|
||||||
|
if (!device->isOpen()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Capabilities cap;
|
Capabilities cap;
|
||||||
if (device->isReadable() && RGBHandler::canRead(device))
|
if (device->isReadable() && RGBHandler::canRead(device)) {
|
||||||
cap |= CanRead;
|
cap |= CanRead;
|
||||||
if (device->isWritable())
|
}
|
||||||
|
if (device->isWritable()) {
|
||||||
cap |= CanWrite;
|
cap |= CanWrite;
|
||||||
|
}
|
||||||
return cap;
|
return cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QImageIOHandler *RGBPlugin::create(QIODevice *device, const QByteArray &format) const
|
QImageIOHandler *RGBPlugin::create(QIODevice *device, const QByteArray &format) const
|
||||||
{
|
{
|
||||||
QImageIOHandler *handler = new RGBHandler;
|
QImageIOHandler *handler = new RGBHandler;
|
||||||
|
|||||||
@ -74,7 +74,7 @@ struct TgaHeader {
|
|||||||
enum { SIZE = 18 }; // const static int SIZE = 18;
|
enum { SIZE = 18 }; // const static int SIZE = 18;
|
||||||
};
|
};
|
||||||
|
|
||||||
static QDataStream & operator>> (QDataStream & s, TgaHeader & head)
|
static QDataStream &operator>> (QDataStream &s, TgaHeader &head)
|
||||||
{
|
{
|
||||||
s >> head.id_length;
|
s >> head.id_length;
|
||||||
s >> head.colormap_type;
|
s >> head.colormap_type;
|
||||||
@ -94,7 +94,7 @@ static QDataStream & operator>> (QDataStream & s, TgaHeader & head)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsSupported(const TgaHeader & head)
|
static bool IsSupported(const TgaHeader &head)
|
||||||
{
|
{
|
||||||
if (head.image_type != TGA_TYPE_INDEXED &&
|
if (head.image_type != TGA_TYPE_INDEXED &&
|
||||||
head.image_type != TGA_TYPE_RGB &&
|
head.image_type != TGA_TYPE_RGB &&
|
||||||
@ -140,25 +140,26 @@ struct TgaHeaderInfo {
|
|||||||
bool rgb;
|
bool rgb;
|
||||||
bool grey;
|
bool grey;
|
||||||
|
|
||||||
TgaHeaderInfo(const TgaHeader & tga) : rle(false), pal(false), rgb(false), grey(false) {
|
TgaHeaderInfo(const TgaHeader &tga) : rle(false), pal(false), rgb(false), grey(false)
|
||||||
|
{
|
||||||
switch (tga.image_type) {
|
switch (tga.image_type) {
|
||||||
case TGA_TYPE_RLE_INDEXED:
|
case TGA_TYPE_RLE_INDEXED:
|
||||||
rle = true;
|
rle = true;
|
||||||
// no break is intended!
|
// no break is intended!
|
||||||
case TGA_TYPE_INDEXED:
|
case TGA_TYPE_INDEXED:
|
||||||
pal = true;
|
pal = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TGA_TYPE_RLE_RGB:
|
case TGA_TYPE_RLE_RGB:
|
||||||
rle = true;
|
rle = true;
|
||||||
// no break is intended!
|
// no break is intended!
|
||||||
case TGA_TYPE_RGB:
|
case TGA_TYPE_RGB:
|
||||||
rgb = true;
|
rgb = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TGA_TYPE_RLE_GREY:
|
case TGA_TYPE_RLE_GREY:
|
||||||
rle = true;
|
rle = true;
|
||||||
// no break is intended!
|
// no break is intended!
|
||||||
case TGA_TYPE_GREY:
|
case TGA_TYPE_GREY:
|
||||||
grey = true;
|
grey = true;
|
||||||
break;
|
break;
|
||||||
@ -170,9 +171,7 @@ struct TgaHeaderInfo {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool LoadTGA(QDataStream &s, const TgaHeader &tga, QImage &img)
|
||||||
|
|
||||||
static bool LoadTGA(QDataStream & s, const TgaHeader & tga, QImage &img)
|
|
||||||
{
|
{
|
||||||
// Create image.
|
// Create image.
|
||||||
img = QImage(tga.width, tga.height, QImage::Format_RGB32);
|
img = QImage(tga.width, tga.height, QImage::Format_RGB32);
|
||||||
@ -202,11 +201,11 @@ static bool LoadTGA(QDataStream & s, const TgaHeader & tga, QImage &img)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Allocate image.
|
// Allocate image.
|
||||||
uchar * const image = new uchar[size];
|
uchar *const image = new uchar[size];
|
||||||
|
|
||||||
if (info.rle) {
|
if (info.rle) {
|
||||||
// Decode image.
|
// Decode image.
|
||||||
char * dst = (char *)image;
|
char *dst = (char *)image;
|
||||||
int num = size;
|
int num = size;
|
||||||
|
|
||||||
while (num > 0) {
|
while (num > 0) {
|
||||||
@ -250,10 +249,10 @@ static bool LoadTGA(QDataStream & s, const TgaHeader & tga, QImage &img)
|
|||||||
y_end = -1;
|
y_end = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uchar * src = image;
|
uchar *src = image;
|
||||||
|
|
||||||
for (int y = y_start; y != y_end; y += y_step) {
|
for (int y = y_start; y != y_end; y += y_step) {
|
||||||
QRgb * scanline = (QRgb *) img.scanLine(y);
|
QRgb *scanline = (QRgb *) img.scanLine(y);
|
||||||
|
|
||||||
if (info.pal) {
|
if (info.pal) {
|
||||||
// Paletted.
|
// Paletted.
|
||||||
@ -299,7 +298,6 @@ static bool LoadTGA(QDataStream & s, const TgaHeader & tga, QImage &img)
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
TGAHandler::TGAHandler()
|
TGAHandler::TGAHandler()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -320,7 +318,6 @@ bool TGAHandler::read(QImage *outImage)
|
|||||||
QDataStream s(device());
|
QDataStream s(device());
|
||||||
s.setByteOrder(QDataStream::LittleEndian);
|
s.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
|
||||||
|
|
||||||
// Read image header.
|
// Read image header.
|
||||||
TgaHeader tga;
|
TgaHeader tga;
|
||||||
s >> tga;
|
s >> tga;
|
||||||
@ -338,7 +335,6 @@ bool TGAHandler::read(QImage *outImage)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QImage img;
|
QImage img;
|
||||||
bool result = LoadTGA(s, tga, img);
|
bool result = LoadTGA(s, tga, img);
|
||||||
|
|
||||||
@ -347,7 +343,6 @@ bool TGAHandler::read(QImage *outImage)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
*outImage = img;
|
*outImage = img;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -357,10 +352,11 @@ bool TGAHandler::write(const QImage &image)
|
|||||||
QDataStream s(device());
|
QDataStream s(device());
|
||||||
s.setByteOrder(QDataStream::LittleEndian);
|
s.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
|
||||||
const QImage& img = image;
|
const QImage &img = image;
|
||||||
const bool hasAlpha = (img.format() == QImage::Format_ARGB32);
|
const bool hasAlpha = (img.format() == QImage::Format_ARGB32);
|
||||||
for (int i = 0; i < 12; i++)
|
for (int i = 0; i < 12; i++) {
|
||||||
s << targaMagic[i];
|
s << targaMagic[i];
|
||||||
|
}
|
||||||
|
|
||||||
// write header
|
// write header
|
||||||
s << quint16(img.width()); // width
|
s << quint16(img.width()); // width
|
||||||
@ -374,8 +370,9 @@ bool TGAHandler::write(const QImage &image)
|
|||||||
s << quint8(qBlue(color));
|
s << quint8(qBlue(color));
|
||||||
s << quint8(qGreen(color));
|
s << quint8(qGreen(color));
|
||||||
s << quint8(qRed(color));
|
s << quint8(qRed(color));
|
||||||
if (hasAlpha)
|
if (hasAlpha) {
|
||||||
s << quint8(qAlpha(color));
|
s << quint8(qAlpha(color));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -413,18 +410,23 @@ bool TGAHandler::canRead(QIODevice *device)
|
|||||||
|
|
||||||
QImageIOPlugin::Capabilities TGAPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
QImageIOPlugin::Capabilities TGAPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
||||||
{
|
{
|
||||||
if (format == "tga")
|
if (format == "tga") {
|
||||||
return Capabilities(CanRead | CanWrite);
|
return Capabilities(CanRead | CanWrite);
|
||||||
if (!format.isEmpty())
|
}
|
||||||
|
if (!format.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
if (!device->isOpen())
|
}
|
||||||
|
if (!device->isOpen()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Capabilities cap;
|
Capabilities cap;
|
||||||
if (device->isReadable() && TGAHandler::canRead(device))
|
if (device->isReadable() && TGAHandler::canRead(device)) {
|
||||||
cap |= CanRead;
|
cap |= CanRead;
|
||||||
if (device->isWritable())
|
}
|
||||||
|
if (device->isWritable()) {
|
||||||
cap |= CanWrite;
|
cap |= CanWrite;
|
||||||
|
}
|
||||||
return cap;
|
return cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -18,7 +18,6 @@
|
|||||||
static const int b_255_3[] = {0, 85, 170, 255}, // index*255/3
|
static const int b_255_3[] = {0, 85, 170, 255}, // index*255/3
|
||||||
rg_255_7[] = {0, 36, 72, 109, 145, 182, 218, 255}; // index *255/7
|
rg_255_7[] = {0, 36, 72, 109, 145, 182, 218, 255}; // index *255/7
|
||||||
|
|
||||||
|
|
||||||
XVHandler::XVHandler()
|
XVHandler::XVHandler()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -43,40 +42,47 @@ bool XVHandler::read(QImage *retImage)
|
|||||||
|
|
||||||
// magic number must be "P7 332"
|
// magic number must be "P7 332"
|
||||||
iodev->readLine(str, BUFSIZE);
|
iodev->readLine(str, BUFSIZE);
|
||||||
if (strncmp(str, "P7 332", 6))
|
if (strncmp(str, "P7 332", 6)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// next line #XVVERSION
|
// next line #XVVERSION
|
||||||
iodev->readLine(str, BUFSIZE);
|
iodev->readLine(str, BUFSIZE);
|
||||||
if (strncmp(str, "#XVVERSION", 10))
|
if (strncmp(str, "#XVVERSION", 10)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// now it gets interesting, #BUILTIN means we are out.
|
// now it gets interesting, #BUILTIN means we are out.
|
||||||
// if IMGINFO comes, we are happy!
|
// if IMGINFO comes, we are happy!
|
||||||
iodev->readLine(str, BUFSIZE);
|
iodev->readLine(str, BUFSIZE);
|
||||||
if (strncmp(str, "#IMGINFO:", 9))
|
if (strncmp(str, "#IMGINFO:", 9)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// after this an #END_OF_COMMENTS signals everything to be ok!
|
// after this an #END_OF_COMMENTS signals everything to be ok!
|
||||||
iodev->readLine(str, BUFSIZE);
|
iodev->readLine(str, BUFSIZE);
|
||||||
if (strncmp(str, "#END_OF", 7))
|
if (strncmp(str, "#END_OF", 7)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// now a last line with width, height, maxval which is
|
// now a last line with width, height, maxval which is
|
||||||
// supposed to be 255
|
// supposed to be 255
|
||||||
iodev->readLine(str, BUFSIZE);
|
iodev->readLine(str, BUFSIZE);
|
||||||
sscanf(str, "%d %d %d", &x, &y, &maxval);
|
sscanf(str, "%d %d %d", &x, &y, &maxval);
|
||||||
|
|
||||||
if (maxval != 255)
|
if (maxval != 255) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
int blocksize = x * y;
|
int blocksize = x * y;
|
||||||
if (x < 0 || y < 0 || blocksize < x || blocksize < y)
|
if (x < 0 || y < 0 || blocksize < x || blocksize < y) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// now follows a binary block of x*y bytes.
|
// now follows a binary block of x*y bytes.
|
||||||
char *block = (char*) malloc(blocksize);
|
char *block = (char *) malloc(blocksize);
|
||||||
if (!block)
|
if (!block) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (iodev->read(block, blocksize) != blocksize) {
|
if (iodev->read(block, blocksize) != blocksize) {
|
||||||
free(block);
|
free(block);
|
||||||
@ -114,7 +120,7 @@ bool XVHandler::read(QImage *retImage)
|
|||||||
|
|
||||||
bool XVHandler::write(const QImage &image)
|
bool XVHandler::write(const QImage &image)
|
||||||
{
|
{
|
||||||
QIODevice& f = *(device());
|
QIODevice &f = *(device());
|
||||||
|
|
||||||
// Removed "f.open(...)" and "f.close()" (tanghus)
|
// Removed "f.open(...)" and "f.close()" (tanghus)
|
||||||
|
|
||||||
@ -139,19 +145,19 @@ bool XVHandler::write(const QImage &image)
|
|||||||
sprintf(str, "%i %i 255\n", w, h);
|
sprintf(str, "%i %i 255\n", w, h);
|
||||||
f.write(str, strlen(str));
|
f.write(str, strlen(str));
|
||||||
|
|
||||||
|
|
||||||
QImage tmpImage(image);
|
QImage tmpImage(image);
|
||||||
if (image.depth() == 1)
|
if (image.depth() == 1) {
|
||||||
tmpImage = image.convertToFormat(QImage::Format_Indexed8, Qt::AutoColor);
|
tmpImage = image.convertToFormat(QImage::Format_Indexed8, Qt::AutoColor);
|
||||||
|
}
|
||||||
|
|
||||||
uchar* buffer = new uchar[ w ];
|
uchar *buffer = new uchar[ w ];
|
||||||
|
|
||||||
for (int py = 0; py < h; py++) {
|
for (int py = 0; py < h; py++) {
|
||||||
const uchar *data = tmpImage.scanLine(py);
|
const uchar *data = tmpImage.scanLine(py);
|
||||||
for (int px = 0; px < w; px++) {
|
for (int px = 0; px < w; px++) {
|
||||||
int r, g, b;
|
int r, g, b;
|
||||||
if (tmpImage.depth() == 32) {
|
if (tmpImage.depth() == 32) {
|
||||||
const QRgb *data32 = (QRgb*) data;
|
const QRgb *data32 = (QRgb *) data;
|
||||||
r = qRed(*data32) >> 5;
|
r = qRed(*data32) >> 5;
|
||||||
g = qGreen(*data32) >> 5;
|
g = qGreen(*data32) >> 5;
|
||||||
b = qBlue(*data32) >> 6;
|
b = qBlue(*data32) >> 6;
|
||||||
@ -165,7 +171,7 @@ bool XVHandler::write(const QImage &image)
|
|||||||
}
|
}
|
||||||
buffer[ px ] = (r << 5) | (g << 2) | b;
|
buffer[ px ] = (r << 5) | (g << 2) | b;
|
||||||
}
|
}
|
||||||
f.write((const char*)buffer, w);
|
f.write((const char *)buffer, w);
|
||||||
}
|
}
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
|
|
||||||
@ -185,8 +191,9 @@ bool XVHandler::canRead(QIODevice *device)
|
|||||||
qint64 readBytes = device->read(head, sizeof(head));
|
qint64 readBytes = device->read(head, sizeof(head));
|
||||||
if (readBytes != sizeof(head)) {
|
if (readBytes != sizeof(head)) {
|
||||||
if (device->isSequential()) {
|
if (device->isSequential()) {
|
||||||
while (readBytes > 0)
|
while (readBytes > 0) {
|
||||||
device->ungetChar(head[readBytes-- - 1]);
|
device->ungetChar(head[readBytes-- - 1]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
device->seek(oldPos);
|
device->seek(oldPos);
|
||||||
}
|
}
|
||||||
@ -194,8 +201,9 @@ bool XVHandler::canRead(QIODevice *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (device->isSequential()) {
|
if (device->isSequential()) {
|
||||||
while (readBytes > 0)
|
while (readBytes > 0) {
|
||||||
device->ungetChar(head[readBytes-- - 1]);
|
device->ungetChar(head[readBytes-- - 1]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
device->seek(oldPos);
|
device->seek(oldPos);
|
||||||
}
|
}
|
||||||
@ -205,18 +213,23 @@ bool XVHandler::canRead(QIODevice *device)
|
|||||||
|
|
||||||
QImageIOPlugin::Capabilities XVPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
QImageIOPlugin::Capabilities XVPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
||||||
{
|
{
|
||||||
if (format == "xv")
|
if (format == "xv") {
|
||||||
return Capabilities(CanRead | CanWrite);
|
return Capabilities(CanRead | CanWrite);
|
||||||
if (!format.isEmpty())
|
}
|
||||||
|
if (!format.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
if (!device->isOpen())
|
}
|
||||||
|
if (!device->isOpen()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Capabilities cap;
|
Capabilities cap;
|
||||||
if (device->isReadable() && XVHandler::canRead(device))
|
if (device->isReadable() && XVHandler::canRead(device)) {
|
||||||
cap |= CanRead;
|
cap |= CanRead;
|
||||||
if (device->isWritable())
|
}
|
||||||
|
if (device->isWritable()) {
|
||||||
cap |= CanWrite;
|
cap |= CanWrite;
|
||||||
|
}
|
||||||
return cap;
|
return cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
#include <QImageWriter>
|
#include <QImageWriter>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
QCoreApplication::addLibraryPath(QLatin1String(PLUGIN_DIR));
|
QCoreApplication::addLibraryPath(QLatin1String(PLUGIN_DIR));
|
||||||
@ -42,18 +42,18 @@ int main(int argc, char** argv)
|
|||||||
parser.addPositionalArgument(QLatin1String("in"), QLatin1String("input image file"));
|
parser.addPositionalArgument(QLatin1String("in"), QLatin1String("input image file"));
|
||||||
parser.addPositionalArgument(QLatin1String("out"), QLatin1String("output image file"));
|
parser.addPositionalArgument(QLatin1String("out"), QLatin1String("output image file"));
|
||||||
QCommandLineOption informat(
|
QCommandLineOption informat(
|
||||||
QStringList() << QLatin1String("i") << QLatin1String("informat"),
|
QStringList() << QLatin1String("i") << QLatin1String("informat"),
|
||||||
QLatin1String("Image format for input file"),
|
QLatin1String("Image format for input file"),
|
||||||
QLatin1String("format"));
|
QLatin1String("format"));
|
||||||
parser.addOption(informat);
|
parser.addOption(informat);
|
||||||
QCommandLineOption outformat(
|
QCommandLineOption outformat(
|
||||||
QStringList() << QLatin1String("o") << QLatin1String("outformat"),
|
QStringList() << QLatin1String("o") << QLatin1String("outformat"),
|
||||||
QLatin1String("Image format for output file"),
|
QLatin1String("Image format for output file"),
|
||||||
QLatin1String("format"));
|
QLatin1String("format"));
|
||||||
parser.addOption(outformat);
|
parser.addOption(outformat);
|
||||||
QCommandLineOption listformats(
|
QCommandLineOption listformats(
|
||||||
QStringList() << QLatin1String("l") << QLatin1String("list"),
|
QStringList() << QLatin1String("l") << QLatin1String("list"),
|
||||||
QLatin1String("List supported image formats"));
|
QLatin1String("List supported image formats"));
|
||||||
parser.addOption(listformats);
|
parser.addOption(listformats);
|
||||||
|
|
||||||
parser.process(app);
|
parser.process(app);
|
||||||
|
|||||||
Reference in New Issue
Block a user