|
|
|
|
|
|
volatile Texture2D _texture; |
|
|
|
volatile FrameData _frameData; |
|
|
|
volatile Image _image; |
|
|
|
volatile GifDecoder _decoder; |
|
|
|
volatile MemoryStream _stream; |
|
|
|
IEnumerator _coroutine; |
|
|
|
|
|
|
|
public GifCodec(byte[] bytes) { |
|
|
|
|
|
|
this._frameIndex = 0; |
|
|
|
this._bytes = bytes; |
|
|
|
this._coroutine = this._startDecoding(); |
|
|
|
this._init(); |
|
|
|
this._texture = new Texture2D(this._width, this._height, TextureFormat.BGRA32, false); |
|
|
|
this._texture.hideFlags = HideFlags.HideAndDontSave; |
|
|
|
this._image = new Image(this._texture); |
|
|
|
this._decoder = new GifDecoder(); |
|
|
|
this._stream = new MemoryStream(this._bytes); |
|
|
|
this._frameData = new FrameData() { |
|
|
|
frameInfo = new FrameInfo() |
|
|
|
}; |
|
|
|
void _init() { |
|
|
|
var bytesStream = new MemoryStream(this._bytes); |
|
|
|
IEnumerator _startDecoding() { |
|
|
|
this._stream.Seek(0, SeekOrigin.Begin); |
|
|
|
var gifDecoder = new GifDecoder(); |
|
|
|
if (gifDecoder.read(bytesStream) != GifDecoder.STATUS_OK) { |
|
|
|
if (this._decoder.read(this._stream) != GifDecoder.STATUS_OK) { |
|
|
|
this._width = gifDecoder.frameWidth; |
|
|
|
this._height = gifDecoder.frameHeight; |
|
|
|
} |
|
|
|
this._width = this._decoder.frameWidth; |
|
|
|
this._height = this._decoder.frameHeight; |
|
|
|
IEnumerator _startDecoding() { |
|
|
|
var bytesStream = new MemoryStream(this._bytes); |
|
|
|
|
|
|
|
var gifDecoder = new GifDecoder(); |
|
|
|
if (gifDecoder.read(bytesStream) != GifDecoder.STATUS_OK) { |
|
|
|
throw new Exception("Failed to decode gif."); |
|
|
|
if (this._texture == null) { |
|
|
|
this._texture = new Texture2D(this._width, this._height, TextureFormat.BGRA32, false); |
|
|
|
this._texture.hideFlags = HideFlags.HideAndDontSave; |
|
|
|
this._image = new Image(this._texture); |
|
|
|
this._frameData.frameInfo.image = this._image; |
|
|
|
|
|
|
|
this._width = gifDecoder.frameWidth; |
|
|
|
this._height = gifDecoder.frameHeight; |
|
|
|
this._frameData.gifFrame = this._decoder.currentFrame; |
|
|
|
D.assert(this._frameData.gifFrame != null); |
|
|
|
if (gifDecoder.nextFrame() != GifDecoder.STATUS_OK) { |
|
|
|
if (this._decoder.nextFrame() != GifDecoder.STATUS_OK) { |
|
|
|
if (gifDecoder.done) { |
|
|
|
if (this._decoder.done) { |
|
|
|
var frameData = new FrameData { |
|
|
|
gifFrame = gifDecoder.currentFrame |
|
|
|
}; |
|
|
|
|
|
|
|
this._frameData = frameData; |
|
|
|
|
|
|
|
i++; |
|
|
|
|
|
|
|
|
|
|
D.assert(gifDecoder.frameCount == i); |
|
|
|
this._frameCount = gifDecoder.frameCount; |
|
|
|
this._repetitionCount = gifDecoder.loopCount; |
|
|
|
D.assert(this._decoder.frameCount == i); |
|
|
|
this._frameCount = this._decoder.frameCount; |
|
|
|
this._repetitionCount = this._decoder.loopCount; |
|
|
|
this._isDone = true; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
this._nextFrame(); |
|
|
|
this._texture.LoadRawTextureData(this._frameData.gifFrame.bytes); |
|
|
|
this._texture.Apply(); |
|
|
|
this._frameData.frameInfo = new FrameInfo() { |
|
|
|
image = this._image, |
|
|
|
duration = TimeSpan.FromMilliseconds(this._frameData.gifFrame.delay) |
|
|
|
}; |
|
|
|
this._frameData.frameInfo.duration = TimeSpan.FromMilliseconds(this._frameData.gifFrame.delay); |
|
|
|
return this._frameData.frameInfo; |
|
|
|
} |
|
|
|
|
|
|
|