Skip to content

Commit 83b37bf

Browse files
authored
Merge pull request #241 from Nadahar/GIF_Graphics_Control_Extension
Full parsing of GIF Graphics Control Extension
2 parents 67ec8aa + e5731c8 commit 83b37bf

File tree

2 files changed

+78
-6
lines changed

2 files changed

+78
-6
lines changed

Source/com/drew/metadata/gif/GifControlDirectory.java

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,21 @@
3333
public class GifControlDirectory extends Directory
3434
{
3535
public static final int TAG_DELAY = 1;
36+
public static final int TAG_DISPOSAL_METHOD = 2;
37+
public static final int TAG_USER_INPUT_FLAG = 3;
38+
public static final int TAG_TRANSPARENT_COLOR_FLAG = 4;
39+
public static final int TAG_TRANSPARENT_COLOR_INDEX = 5;
3640

3741
@NotNull
3842
protected static final HashMap<Integer, String> _tagNameMap = new HashMap<Integer, String>();
3943

4044
static
4145
{
4246
_tagNameMap.put(TAG_DELAY, "Delay");
47+
_tagNameMap.put(TAG_DISPOSAL_METHOD, "Disposal Method");
48+
_tagNameMap.put(TAG_USER_INPUT_FLAG, "User Input Flag");
49+
_tagNameMap.put(TAG_TRANSPARENT_COLOR_FLAG, "Transparent Color Flag");
50+
_tagNameMap.put(TAG_TRANSPARENT_COLOR_INDEX, "Transparent Color Index");
4351
}
4452

4553
public GifControlDirectory()
@@ -54,10 +62,73 @@ public String getName()
5462
return "GIF Control";
5563
}
5664

65+
/**
66+
* @return The {@link DisposalMethod}.
67+
*/
68+
@NotNull
69+
public DisposalMethod getDisposalMethod() {
70+
return (DisposalMethod) getObject(TAG_DISPOSAL_METHOD);
71+
}
72+
73+
/**
74+
* @return Whether the GIF has transparency.
75+
*/
76+
public boolean isTransparent() {
77+
Boolean transparent = getBooleanObject(TAG_TRANSPARENT_COLOR_FLAG);
78+
return transparent != null ? transparent.booleanValue() : false;
79+
}
80+
5781
@Override
5882
@NotNull
5983
protected HashMap<Integer, String> getTagNameMap()
6084
{
6185
return _tagNameMap;
6286
}
87+
88+
/**
89+
* Disposal method indicates the way in which the graphic is to be treated
90+
* after being displayed.
91+
*/
92+
public enum DisposalMethod {
93+
NOT_SPECIFIED,
94+
DO_NOT_DISPOSE,
95+
RESTORE_TO_BACKGROUND_COLOR,
96+
RESTORE_TO_PREVIOUS,
97+
TO_BE_DEFINED,
98+
INVALID;
99+
100+
public static DisposalMethod typeOf(int value) {
101+
switch (value) {
102+
case 0: return NOT_SPECIFIED;
103+
case 1: return DO_NOT_DISPOSE;
104+
case 2: return RESTORE_TO_BACKGROUND_COLOR;
105+
case 3: return RESTORE_TO_PREVIOUS;
106+
case 4:
107+
case 5:
108+
case 6:
109+
case 7: return TO_BE_DEFINED;
110+
default: return INVALID;
111+
}
112+
}
113+
114+
@Override
115+
public String toString() {
116+
switch (this) {
117+
case DO_NOT_DISPOSE:
118+
return "Don't Dispose";
119+
case INVALID:
120+
return "Invalid value";
121+
case NOT_SPECIFIED:
122+
return "Not Specified";
123+
case RESTORE_TO_BACKGROUND_COLOR:
124+
return "Restore to Background Color";
125+
case RESTORE_TO_PREVIOUS:
126+
return "Restore to Previous";
127+
case TO_BE_DEFINED:
128+
return "To Be Defined";
129+
default:
130+
return super.toString();
131+
}
132+
}
133+
}
63134
}

Source/com/drew/metadata/gif/GifReader.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import com.drew.metadata.ErrorDirectory;
3131
import com.drew.metadata.Metadata;
3232
import com.drew.metadata.StringValue;
33+
import com.drew.metadata.gif.GifControlDirectory.DisposalMethod;
3334
import com.drew.metadata.icc.IccReader;
3435
import com.drew.metadata.xmp.XmpReader;
3536

@@ -298,15 +299,15 @@ private static GifControlDirectory readControlBlock(SequentialReader reader, int
298299

299300
GifControlDirectory directory = new GifControlDirectory();
300301

301-
reader.skip(1);
302-
302+
short packedFields = reader.getUInt8();
303+
directory.setObject(GifControlDirectory.TAG_DISPOSAL_METHOD, DisposalMethod.typeOf((packedFields >> 2) & 7));
304+
directory.setBoolean(GifControlDirectory.TAG_USER_INPUT_FLAG, (packedFields & 2) >> 1 == 1 ? true : false);
305+
directory.setBoolean(GifControlDirectory.TAG_TRANSPARENT_COLOR_FLAG, (packedFields & 1) == 1 ? true : false);
303306
directory.setInt(GifControlDirectory.TAG_DELAY, reader.getUInt16());
304-
305-
if (blockSizeBytes > 3)
306-
reader.skip(blockSizeBytes - 3);
307+
directory.setInt(GifControlDirectory.TAG_TRANSPARENT_COLOR_INDEX, reader.getUInt8());
307308

308309
// skip 0x0 block terminator
309-
reader.getByte();
310+
reader.skip(1);
310311

311312
return directory;
312313
}

0 commit comments

Comments
 (0)