public static Bitmap ReadLZ77Image(BinaryReader reader, int bytesPerPixel) { byte[] bufferPalette = reader.ReadBytes(256 * sizeof(UInt32)); Int32 sizeUncompressed = reader.ReadInt32(); // TODO(adm244): check compressed size; or read buffer first and then decode Int32 sizeCompressed = reader.ReadInt32(); byte[] bufferPixels = AGSCompression.ReadLZ77(reader, sizeUncompressed, bytesPerPixel, out int width, out int height); PixelFormat format = PixelFormatExtension.FromBytesPerPixel(bytesPerPixel); // CHECK(adm244): palette format in room files //PixelFormat paletteFormat = PixelFormat.Argb32; //if (format == PixelFormat.Indexed) PixelFormat paletteFormat = PixelFormat.Argb6666; Palette palette = Palette.FromBuffer(bufferPalette, paletteFormat); if (format == PixelFormat.Indexed) { return(new Bitmap(width, height, bufferPixels, format, palette)); } Bitmap bitmap = new Bitmap(width, height, bufferPixels, format); // NOTE(adm244): removes null-alpha; see AGSGraphics.ReadSprite if (bitmap.Format == PixelFormat.Argb32) { bitmap = bitmap.Convert(PixelFormat.Rgb24); } return(bitmap); }
public static void WriteLZ77Image(BinaryWriter writer, Bitmap image, int bytesPerPixel) { // CHECK(adm244): palette format in room files //PixelFormat paletteFormat = PixelFormat.Argb32; // CHECK(adm244): 2.54 crashes if palette is not 6-bits in some cases (if some >0x3F values are present) // maybe we don't care for 8-bits palette then? double check that //if (image.Format == PixelFormat.Indexed) PixelFormat paletteFormat = PixelFormat.Argb6666; Palette palette = image.Palette.HasValue ? image.Palette.Value : AGSSpriteSet.DefaultPalette; byte[] paletteBuffer = palette.ToBuffer(paletteFormat); writer.Write((byte[])paletteBuffer); //NOTE(adm244): convert bitmap to match requested bytesPerPixel PixelFormat targetFormat = PixelFormatExtension.FromBytesPerPixel(bytesPerPixel); if (image.Format != targetFormat) { image = image.Convert(targetFormat, discardAlpha: true); } byte[] pixels = image.GetPixels(); Debug.Assert(pixels.Length == (image.Width * image.Height * bytesPerPixel)); byte[] buffer = PreAppendImageSize(image.Width, image.Height, bytesPerPixel, pixels); byte[] bufferCompressed = AGSCompression.LZ77Compress(buffer); writer.Write((UInt32)buffer.Length); writer.Write((UInt32)bufferCompressed.Length); writer.Write((byte[])bufferCompressed); }
private static Bitmap ReadSprite(BinaryReader reader, SpriteSetHeader header) { // TODO(adm244): maybe return PixelFormat instead of bytesPerPixel? byte[] buffer = ReadSprite(reader, header, out int width, out int height, out int bytesPerPixel); if (buffer == null) { return(null); } PixelFormat format = PixelFormatExtension.FromBytesPerPixel(bytesPerPixel); if (format == PixelFormat.Indexed) { return(new Bitmap(width, height, buffer, format, header.Palette)); } Bitmap bitmap = new Bitmap(width, height, buffer, format); // NOTE(adm244): since AGS doesn't support 24bpp RLE images it converts them to 32bpp // (even if it won't be compressed, you know, 'just in case' case...) // in the process alpha channel gets set to 0 (transparent) instead of 255 (opaque) // which leads to a problem of fully transparent images (and "features" in GDI decoders) // // to resolve this issue, we check if alpha channel is used and if not discard it if (format == PixelFormat.Argb32 && !IsAlphaChannelUsed(buffer)) { bitmap = bitmap.Convert(PixelFormat.Rgb24); } return(bitmap); }
public static Bitmap ReadAllegroImage(BinaryReader reader) { Int16 bytesPerPixel = 1; Int16 width = reader.ReadInt16(); Int16 height = reader.ReadInt16(); byte[] buffer = AGSCompression.ReadAllegro(reader, width, height); Debug.Assert(buffer.Length == (width * height * bytesPerPixel)); PixelFormat format = PixelFormatExtension.FromBytesPerPixel(bytesPerPixel); // NOTE(adm244): in this case palette is always(?) rgb666 Palette palette = ReadPalette(reader, PixelFormat.Rgb666); return(new Bitmap(width, height, buffer, format, palette)); }