mirror of
https://github.com/crskycode/GARbro.git
synced 2024-12-23 19:34:15 +08:00
(ALP): support 8bpp bitmaps.
This commit is contained in:
parent
6a404b6ea3
commit
dfbdf31203
@ -27,6 +27,7 @@ using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace GameRes.Formats.NekoSDK
|
||||
{
|
||||
@ -35,19 +36,32 @@ namespace GameRes.Formats.NekoSDK
|
||||
{
|
||||
public ImageData Read (IBinaryStream file, BmpMetaData info)
|
||||
{
|
||||
if (info.BPP != 24 && info.BPP != 32 || !file.CanSeek)
|
||||
if (!file.CanSeek)
|
||||
return null;
|
||||
var alp_name = Path.ChangeExtension (info.FileName, "alp");
|
||||
if (alp_name.Equals (info.FileName, StringComparison.InvariantCultureIgnoreCase)
|
||||
|| !VFS.FileExists (alp_name))
|
||||
return null;
|
||||
var alpha_size = info.Width * info.Height;
|
||||
int alp_stride = ((int)info.Width + 3) & -4;
|
||||
int alpha_size = alp_stride * (int)info.Height;
|
||||
var alpha = new byte[alpha_size];
|
||||
using (var alp = VFS.OpenStream (alp_name))
|
||||
{
|
||||
if (alpha.Length != alp.Read (alpha, 0, alpha.Length) || alp.ReadByte() != -1)
|
||||
alpha_size = alp.Read (alpha, 0, alpha.Length);
|
||||
if (alp.ReadByte() != -1)
|
||||
return null;
|
||||
if (alpha_size != alpha.Length)
|
||||
{
|
||||
if (alp_stride == (int)info.Width)
|
||||
return null;
|
||||
alp_stride = (int)info.Width;
|
||||
if (alpha_size != alp_stride * (int)info.Height)
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (info.BPP != 24 && info.BPP != 32)
|
||||
return ReadBmp (file, info, alpha, alp_stride);
|
||||
|
||||
file.Position = info.ImageOffset;
|
||||
int dst_stride = (int)info.Width * 4;
|
||||
int gap = -((int)info.Width * info.BPP / 8) & 3;
|
||||
@ -56,7 +70,7 @@ namespace GameRes.Formats.NekoSDK
|
||||
int dst = (int)(info.Height-1) * dst_stride;
|
||||
for (int y = (int)info.Height-1; y >= 0; --y)
|
||||
{
|
||||
int a_src = (int)info.Width * y;
|
||||
int a_src = alp_stride * y;
|
||||
for (int x = 0; x < dst_stride; x += 4)
|
||||
{
|
||||
file.Read (pixels, dst+x, src_pixel_size);
|
||||
@ -68,5 +82,29 @@ namespace GameRes.Formats.NekoSDK
|
||||
}
|
||||
return ImageData.Create (info, PixelFormats.Bgra32, null, pixels, dst_stride);
|
||||
}
|
||||
|
||||
public ImageData ReadBmp (IBinaryStream file, BmpMetaData info, byte[] alpha, int alp_stride)
|
||||
{
|
||||
var decoder = new BmpBitmapDecoder (file.AsStream,
|
||||
BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
|
||||
BitmapSource bitmap = decoder.Frames[0];
|
||||
bitmap = new FormatConvertedBitmap (bitmap, PixelFormats.Bgr32, null, 0);
|
||||
int dst_stride = (int)info.Width * 4;
|
||||
var pixels = new byte[(int)info.Height * dst_stride];
|
||||
bitmap.CopyPixels (pixels, dst_stride, 0);
|
||||
int dst = 0;
|
||||
int src = 0;
|
||||
for (int y = (int)info.Height; y > 0; --y)
|
||||
{
|
||||
int a_src = src;
|
||||
for (int x = 3; x < dst_stride; x += 4)
|
||||
{
|
||||
pixels[dst+x] = alpha[a_src++];
|
||||
}
|
||||
dst += dst_stride;
|
||||
src += alp_stride;
|
||||
}
|
||||
return ImageData.Create (info, PixelFormats.Bgra32, null, pixels, dst_stride);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user