1
1
using System ;
2
2
using System . Collections ;
3
- using System . Collections . Generic ;
4
3
using System . IO ;
5
4
using RSG ;
6
- using Unity . UIWidgets . async ;
7
5
using Unity . UIWidgets . foundation ;
8
6
using UnityEngine ;
9
7
@@ -18,80 +16,75 @@ public class FrameData {
18
16
public GifDecoder . GifFrame gifFrame ;
19
17
}
20
18
21
- readonly List < Promise < FrameData > > _frames ;
19
+ volatile byte [ ] _bytes ;
22
20
volatile int _width ;
23
21
volatile int _height ;
24
22
volatile int _frameCount ;
25
23
volatile int _repetitionCount ;
26
24
volatile bool _isDone ;
27
25
volatile int _frameIndex ;
28
26
volatile Texture2D _texture ;
29
- readonly UIWidgetsCoroutine _coroutine ;
27
+ volatile FrameData _frameData ;
28
+ volatile Image _image ;
29
+ volatile GifDecoder _decoder ;
30
+ volatile MemoryStream _stream ;
31
+ IEnumerator _coroutine ;
30
32
31
33
public GifCodec ( byte [ ] bytes ) {
32
34
D . assert ( bytes != null ) ;
33
35
D . assert ( isGif ( bytes ) ) ;
34
36
35
- this . _frames = new List < Promise < FrameData > > ( ) ;
36
- this . _width = 0 ;
37
- this . _height = 0 ;
38
37
this . _frameCount = 0 ;
39
38
this . _repetitionCount = 0 ;
40
39
this . _isDone = false ;
41
40
this . _frameIndex = 0 ;
42
-
43
- this . _coroutine = Window . instance . startBackgroundCoroutine (
44
- this . _startDecoding ( bytes , Window . instance ) ) ;
41
+ this . _bytes = bytes ;
42
+ this . _coroutine = this . _startDecoding ( ) ;
43
+ this . _decoder = new GifDecoder ( ) ;
44
+ this . _stream = new MemoryStream ( this . _bytes ) ;
45
+ this . _frameData = new FrameData ( ) {
46
+ frameInfo = new FrameInfo ( )
47
+ } ;
45
48
}
46
49
47
- IEnumerator _startDecoding ( byte [ ] bytes , Window window ) {
48
- var bytesStream = new MemoryStream ( bytes ) ;
50
+ IEnumerator _startDecoding ( ) {
51
+ this . _stream . Seek ( 0 , SeekOrigin . Begin ) ;
49
52
50
- var gifDecoder = new GifDecoder ( ) ;
51
- if ( gifDecoder . read ( bytesStream ) != GifDecoder . STATUS_OK ) {
53
+ if ( this . _decoder . read ( this . _stream ) != GifDecoder . STATUS_OK ) {
52
54
throw new Exception ( "Failed to decode gif." ) ;
53
55
}
54
56
55
- this . _width = gifDecoder . frameWidth ;
56
- this . _height = gifDecoder . frameHeight ;
57
+ this . _width = this . _decoder . frameWidth ;
58
+ this . _height = this . _decoder . frameHeight ;
59
+
60
+ if ( this . _texture == null ) {
61
+ this . _texture = new Texture2D ( this . _width , this . _height , TextureFormat . BGRA32 , false ) ;
62
+ this . _texture . hideFlags = HideFlags . HideAndDontSave ;
63
+ this . _image = new Image ( this . _texture ) ;
64
+ this . _frameData . frameInfo . image = this . _image ;
65
+ }
66
+ this . _frameData . gifFrame = this . _decoder . currentFrame ;
67
+ D . assert ( this . _frameData . gifFrame != null ) ;
57
68
58
69
int i = 0 ;
59
70
while ( true ) {
60
- yield return null ;
61
-
62
- if ( gifDecoder . nextFrame ( ) != GifDecoder . STATUS_OK ) {
71
+ if ( this . _decoder . nextFrame ( ) != GifDecoder . STATUS_OK ) {
63
72
throw new Exception ( "Failed to decode gif." ) ;
64
73
}
65
74
66
- if ( gifDecoder . done ) {
75
+ if ( this . _decoder . done ) {
67
76
break ;
68
77
}
69
78
70
- var frameData = new FrameData {
71
- gifFrame = gifDecoder . currentFrame ,
72
- } ;
73
-
74
- Promise < FrameData > frame ;
75
-
76
- lock ( this . _frames ) {
77
- if ( i < this . _frames . Count ) {
78
- }
79
- else {
80
- D . assert ( this . _frames . Count == i ) ;
81
- this . _frames . Add ( new Promise < FrameData > ( ) ) ;
82
- }
83
-
84
- frame = this . _frames [ i ] ;
85
- }
86
-
87
- window . runInMain ( ( ) => { frame . Resolve ( frameData ) ; } ) ;
88
79
89
80
i ++ ;
81
+
82
+ yield return null ;
90
83
}
91
84
92
- D . assert ( gifDecoder . frameCount == i ) ;
93
- this . _frameCount = gifDecoder . frameCount ;
94
- this . _repetitionCount = gifDecoder . loopCount ;
85
+ D . assert ( this . _decoder . frameCount == i ) ;
86
+ this . _frameCount = this . _decoder . frameCount ;
87
+ this . _repetitionCount = this . _decoder . loopCount ;
95
88
this . _isDone = true ;
96
89
}
97
90
@@ -107,54 +100,26 @@ public int repetitionCount {
107
100
void _nextFrame ( ) {
108
101
this . _frameIndex ++ ;
109
102
103
+ this . _coroutine . MoveNext ( ) ;
104
+
110
105
if ( this . _isDone && this . _frameIndex >= this . _frameCount ) {
111
106
this . _frameIndex = 0 ;
107
+ this . _isDone = false ;
108
+ this . _coroutine = this . _startDecoding ( ) ;
109
+ this . _coroutine . MoveNext ( ) ;
112
110
}
113
111
}
114
112
115
- public IPromise < FrameInfo > getNextFrame ( ) {
116
- Promise < FrameData > frame ;
117
-
118
- lock ( this . _frames ) {
119
- if ( this . _frameIndex == this . _frames . Count ) {
120
- this . _frames . Add ( new Promise < FrameData > ( ) ) ;
121
- }
122
- else {
123
- D . assert ( this . _frameIndex < this . _frames . Count ) ;
124
- }
125
-
126
- frame = this . _frames [ this . _frameIndex ] ;
127
- }
128
-
129
-
130
- return frame . Then ( frameData => {
131
- this . _nextFrame ( ) ;
132
-
133
- if ( this . _texture == null ) {
134
- this . _texture = new Texture2D ( this . _width , this . _height , TextureFormat . BGRA32 , false ) ;
135
- this . _texture . hideFlags = HideFlags . HideAndDontSave ;
136
- }
137
-
138
- var tex = this . _texture ;
139
- tex . LoadRawTextureData ( frameData . gifFrame . bytes ) ;
140
- tex . Apply ( ) ;
141
-
142
- if ( frameData . frameInfo != null ) {
143
- return frameData . frameInfo ;
144
- }
145
-
146
- frameData . frameInfo = new FrameInfo {
147
- image = new Image ( tex ) ,
148
- duration = TimeSpan . FromMilliseconds ( frameData . gifFrame . delay )
149
- } ;
150
- // frameData.gifFrame = null; // dispose gifFrame
151
-
152
- return frameData . frameInfo ;
153
- } ) ;
113
+ public FrameInfo getNextFrame ( ) {
114
+ this . _nextFrame ( ) ;
115
+ this . _texture . LoadRawTextureData ( this . _frameData . gifFrame . bytes ) ;
116
+ this . _texture . Apply ( ) ;
117
+ this . _frameData . frameInfo . duration = TimeSpan . FromMilliseconds ( this . _frameData . gifFrame . delay ) ;
118
+ return this . _frameData . frameInfo ;
154
119
}
155
120
156
121
public void Dispose ( ) {
157
- this . _coroutine . stop ( ) ;
122
+ this . _decoder . Dispose ( ) ;
158
123
}
159
124
}
160
125
}
0 commit comments