(DCF): improved overlays handling.

This commit is contained in:
morkt 2018-09-07 15:49:12 +04:00
parent e1771edc81
commit f1a201d571
2 changed files with 35 additions and 36 deletions

View File

@ -2,7 +2,7 @@
//! \date Fri Jul 29 14:07:15 2016 //! \date Fri Jul 29 14:07:15 2016
//! \brief AliceSoft incremental image format. //! \brief AliceSoft incremental image format.
// //
// Copyright (C) 2016 by morkt // Copyright (C) 2016-2018 by morkt
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to // of this software and associated documentation files (the "Software"), to
@ -137,29 +137,29 @@ namespace GameRes.Formats.AliceSoft
long qnt_pos = m_input.Position; long qnt_pos = m_input.Position;
if (m_input.ReadUInt32() != Qnt.Signature) if (m_input.ReadUInt32() != Qnt.Signature)
throw new InvalidFormatException(); throw new InvalidFormatException();
QntMetaData qnt_info;
using (var reg = new StreamRegion (m_input.AsStream, qnt_pos, true)) using (var reg = new StreamRegion (m_input.AsStream, qnt_pos, true))
using (var qnt = new BinaryStream (reg, m_input.Name)) using (var qnt = new BinaryStream (reg, m_input.Name))
qnt_info = Qnt.ReadMetaData (qnt) as QntMetaData;
if (null == qnt_info)
throw new InvalidFormatException();
m_input.Position = qnt_pos + 0x44;
var overlay = new QntFormat.Reader (m_input.AsStream, qnt_info);
overlay.Unpack();
m_overlay_bpp = overlay.BPP;
if (m_mask != null)
ReadBaseImage();
if (m_base != null)
{ {
m_output = ApplyOverlay (overlay.Data); var qnt_info = Qnt.ReadMetaData (qnt) as QntMetaData;
SetFormat ((int)m_info.Width, m_base_bpp); if (null == qnt_info)
} throw new InvalidFormatException();
else
{ var overlay = new QntFormat.Reader (reg, qnt_info);
m_output = overlay.Data; overlay.Unpack();
SetFormat ((int)qnt_info.Width, m_overlay_bpp); m_overlay_bpp = overlay.BPP;
if (m_mask != null)
ReadBaseImage();
if (m_base != null)
{
m_output = ApplyOverlay (overlay.Data);
SetFormat ((int)m_info.Width, m_overlay_bpp);
}
else
{
m_output = overlay.Data;
SetFormat ((int)qnt_info.Width, m_overlay_bpp);
}
} }
} }
@ -181,31 +181,31 @@ namespace GameRes.Formats.AliceSoft
for (int y = 0; y < blocks_y; ++y) for (int y = 0; y < blocks_y; ++y)
{ {
int base_pos = y * 0x10 * base_stride; int base_pos = y * 0x10 * base_stride;
int src_pos = y * 0x10 * overlay_stride; int dst_pos = y * 0x10 * overlay_stride;
for (int x = 0; x < blocks_x; ++x) for (int x = 0; x < blocks_x; ++x)
{ {
if (0 != m_mask[mask_pos++]) if (0 == m_mask[mask_pos++])
continue; continue;
for (int by = 0; by < 0x10; ++by) for (int by = 0; by < 0x10; ++by)
{ {
int dst = base_pos + by * base_stride + x * 0x10 * base_step; int src = base_pos + by * base_stride + x * 0x10 * base_step;
int src = src_pos + by * overlay_stride + x * 0x10 * overlay_step; int dst = dst_pos + by * overlay_stride + x * 0x10 * overlay_step;
for (int bx = 0; bx < 0x10; ++bx) for (int bx = 0; bx < 0x10; ++bx)
{ {
m_base[dst ] = overlay[src ]; overlay[dst ] = m_base[src ];
m_base[dst+1] = overlay[src+1]; overlay[dst+1] = m_base[src+1];
m_base[dst+2] = overlay[src+2]; overlay[dst+2] = m_base[src+2];
if (4 == base_step) if (4 == overlay_step)
{ {
m_base[dst+3] = 4 == overlay_step ? overlay[src+3] : (byte)0xFF; overlay[dst+3] = 4 == base_step ? m_base[src+3] : (byte)0xFF;
} }
dst += base_step; src += base_step;
src += overlay_step; dst += overlay_step;
} }
} }
} }
} }
return m_base; return overlay;
} }
void ReadBaseImage () void ReadBaseImage ()

View File

@ -90,8 +90,6 @@ namespace GameRes.Formats.AliceSoft
public override ImageData Read (IBinaryStream stream, ImageMetaData info) public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{ {
var meta = (QntMetaData)info;
stream.Position = meta.HeaderSize;
var reader = new Reader (stream.AsStream, (QntMetaData)info); var reader = new Reader (stream.AsStream, (QntMetaData)info);
reader.Unpack(); reader.Unpack();
int stride = (int)info.Width * (reader.BPP / 8); int stride = (int)info.Width * (reader.BPP / 8);
@ -120,7 +118,8 @@ namespace GameRes.Formats.AliceSoft
int rgb_size = h * w * 3; int rgb_size = h * w * 3;
m_bpp = info.AlphaSize != 0 ? 4 : 3; m_bpp = info.AlphaSize != 0 ? 4 : 3;
m_input = new byte[rgb_size]; m_input = new byte[rgb_size];
var alpha_pos = stream.Position + info.RGBSize; stream.Position = info.HeaderSize;
var alpha_pos = info.HeaderSize + info.RGBSize;
using (var zstream = new ZLibStream (stream, CompressionMode.Decompress, true)) using (var zstream = new ZLibStream (stream, CompressionMode.Decompress, true))
if (rgb_size != zstream.Read (m_input, 0, rgb_size)) if (rgb_size != zstream.Read (m_input, 0, rgb_size))
throw new InvalidFormatException ("Unexpected end of file"); throw new InvalidFormatException ("Unexpected end of file");