public object Serdes(object existing, AssetInfo config, AssetMapping mapping, ISerializer s) { if (s == null) { throw new ArgumentNullException(nameof(s)); } if (config == null) { throw new ArgumentNullException(nameof(config)); } ApiUtil.Assert(config.Transposed != true); int width = s.UInt16(null, 0); int height = s.UInt16(null, 0); int something = s.UInt8(null, 0); ApiUtil.Assert(something == 0); int spriteCount = s.UInt8(null, 0); bool uniform = config.File.Format != "NonUniform"; var frames = new AlbionSpriteFrame[spriteCount]; var frameBytes = new List <byte[]>(); int currentY = 0; int spriteWidth = 0; for (int i = 0; i < spriteCount; i++) { if (!uniform && i > 0) { width = s.UInt16(null, 0); height = s.UInt16(null, 0); something = s.UInt8(null, 0); ApiUtil.Assert(something == 0); int spriteCount2 = s.UInt8(null, 0); ApiUtil.Assert(spriteCount2 == spriteCount); } var bytes = s.ByteArray(null, null, width * height); frames[i] = new AlbionSpriteFrame(0, currentY, width, height); frameBytes.Add(bytes); currentY += height; if (width > spriteWidth) { spriteWidth = width; } } byte[] pixelData = new byte[spriteCount * spriteWidth * currentY]; for (int n = 0; n < spriteCount; n++) { var frame = frames[n]; for (int j = 0; j < frame.Height; j++) { for (int i = 0; i < frame.Width; i++) { pixelData[(frame.Y + j) * spriteWidth + frame.X + i] = frameBytes[n][j * frame.Width + i]; } } } s.Check(); return(new AlbionSprite(config.AssetId.ToString(), spriteWidth, currentY, uniform, pixelData, frames)); }
public object Serdes(object existing, AssetInfo config, AssetMapping mapping, ISerializer s) { if (s == null) { throw new ArgumentNullException(nameof(s)); } if (config == null) { throw new ArgumentNullException(nameof(config)); } if (s.Mode != SerializerMode.Reading) { throw new NotImplementedException("Fixed size sprite saving not currently supported"); } var streamLength = s.BytesRemaining; if (streamLength == 0) { return(null); } int width = config.EffectiveWidth; int height = config.EffectiveHeight; if (width == 0) { width = (int)Math.Sqrt(streamLength); } if (height == 0) { height = (int)streamLength / width; } // ApiUtil.Assert(streamLength % width == 0); // ApiUtil.Assert(streamLength % (width * height) == 0); // long initialPosition = s.BaseStream.Position; int spriteCount = Math.Max(1, unchecked ((int)(streamLength / (width * height)))); height = (int)streamLength / (width * spriteCount); int currentY = 0; var pixelData = new byte[spriteCount * width * height]; var frames = new AlbionSpriteFrame[spriteCount]; for (int n = 0; n < spriteCount; n++) { frames[n] = new AlbionSpriteFrame(0, currentY, width, height); var bytes = s.ByteArray(null, null, width * height); for (int i = 0; i < width * height; i++) { pixelData[n * width * height + i] = bytes[i]; } currentY += height; } var sprite = new AlbionSprite(config.AssetId.ToString(), width, height * spriteCount, true, pixelData, frames); if (!config.Transposed) { return(sprite); } int rotatedFrameHeight = width; pixelData = new byte[spriteCount * width * height]; frames = new AlbionSpriteFrame[spriteCount]; for (int n = 0; n < spriteCount; n++) { frames[n] = new AlbionSpriteFrame(0, rotatedFrameHeight * n, height, rotatedFrameHeight); ApiUtil.RotateImage(width, height, new ReadOnlySpan <byte>(sprite.PixelData, n * width * height, width * height), new Span <byte>(pixelData, n * width * height, width * height)); } return(new AlbionSprite(config.AssetId.ToString(), height, width * spriteCount, true, pixelData, frames)); }