Files
Misaki.HighPerformance/Misaki.HighPerformance.Image/AnimatedGifEnumerator.cs
Misaki eeff3313b5 Add image processing and memory management features
Added new namespace `Misaki.HighPerformance.Image` for image processing, including classes for animated GIF handling and memory management.
Added `AnimatedFrameResult` class for individual frames in animated images.
Added `AnimatedGifEnumerator` class for enumerating frames in animated GIFs.
Added `ColorComponents` enum for different color formats.
Added `ImageInfo` struct for image dimensions and color components.
Added `CRuntime` class for low-level memory management functions.
Added `MemoryStats` class to track memory allocation statistics.
Added utility functions for creating multi-dimensional arrays.
Added new structures for fixed-size UTF-8 encoded strings.
Added benchmarking classes to test new memory management features.

Changed `StbImage.cs` to include new namespaces and functionality for image data manipulation.
Changed project files to target .NET 9.0 and enable new features.
Changed `Arena.cs` and `DynamicArena.cs` to use `nuint` for size parameters.
Changed `BitSet.cs` to enhance bit manipulation methods.
Changed `Program.cs` to run `FunctionPtrBenchmark` for performance testing.

Removed memory tracking code from `AllocationManager.cs`, including the `_allocated` dictionary and related logic.
Removed `Free` method from `IAllocator.cs` interface.
Removed `UNSAFE_COLLECTION_CHECK` preprocessor directive from the codebase.

Refactored various files to improve organization, moving from `Unsafe` to `LowLevel` namespace.
Refactored `MemoryUtilities` class to include new memory operation methods.
Refactored `UnsafeUtilities.cs` to support new collection structures.
2025-07-12 19:48:42 +09:00

149 lines
3.8 KiB
C#

using Misaki.HighPerformance.Image.Runtime;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
namespace Misaki.HighPerformance.Image
{
internal class AnimatedGifEnumerator : IEnumerator<AnimatedFrameResult>
{
private readonly StbImage.stbi__context _context;
private StbImage.stbi__gif _gif;
private readonly ColorComponents _colorComponents;
public AnimatedGifEnumerator(Stream input, ColorComponents colorComponents)
{
if (input == null)
throw new ArgumentNullException("input");
_context = new StbImage.stbi__context(input);
if (StbImage.stbi__gif_test(_context) == 0)
throw new Exception("Input stream is not GIF file.");
_gif = new StbImage.stbi__gif();
_colorComponents = colorComponents;
}
public ColorComponents ColorComponents
{
get
{
return _colorComponents;
}
}
public AnimatedFrameResult Current
{
get; private set;
}
object IEnumerator.Current
{
get
{
return Current;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public unsafe bool MoveNext()
{
// Read next frame
int ccomp;
byte two_back;
var result = StbImage.stbi__gif_load_next(_context, _gif, &ccomp, (int)ColorComponents, &two_back);
if (result == null)
return false;
if (Current == null)
{
Current = new AnimatedFrameResult
{
Width = (uint)_gif.w,
Height = (uint)_gif.h,
SourceComponent = (ColorComponents)ccomp,
Component = ColorComponents == ColorComponents.Default ? (ColorComponents)ccomp : ColorComponents
};
Current.SetData(result);
}
Current.DelayInMs = _gif.delay;
return true;
}
public void Reset()
{
throw new NotImplementedException();
}
~AnimatedGifEnumerator()
{
Dispose(false);
}
protected unsafe virtual void Dispose(bool disposing)
{
if (_gif != null)
{
if (_gif._out_ != null)
{
CRuntime.free(_gif._out_);
_gif._out_ = null;
}
if (_gif.history != null)
{
CRuntime.free(_gif.history);
_gif.history = null;
}
if (_gif.background != null)
{
CRuntime.free(_gif.background);
_gif.background = null;
}
_gif = null;
}
}
}
internal class AnimatedGifEnumerable : IEnumerable<AnimatedFrameResult>
{
private readonly Stream _input;
private readonly ColorComponents _colorComponents;
public AnimatedGifEnumerable(Stream input, ColorComponents colorComponents)
{
_input = input;
_colorComponents = colorComponents;
}
public ColorComponents ColorComponents
{
get
{
return _colorComponents;
}
}
public IEnumerator<AnimatedFrameResult> GetEnumerator()
{
return new AnimatedGifEnumerator(_input, ColorComponents);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}