1 7 8 package com.sun.imageio.plugins.gif; 9 10 import java.io.UnsupportedEncodingException ; 11 import java.util.ArrayList ; 12 import java.util.Iterator ; 13 import java.util.List ; 14 import javax.imageio.ImageTypeSpecifier ; 15 import javax.imageio.metadata.IIOMetadata ; 16 import javax.imageio.metadata.IIOMetadataNode ; 17 import javax.imageio.metadata.IIOMetadataFormat ; 18 import javax.imageio.metadata.IIOMetadataFormatImpl ; 19 import org.w3c.dom.Node ; 20 21 24 public class GIFImageMetadata extends IIOMetadata { 25 26 static final String 28 nativeMetadataFormatName = "javax_imageio_gif_image_1.0"; 29 30 static final String [] disposalMethodNames = { 31 "none", 32 "doNotDispose", 33 "restoreToBackgroundColor", 34 "restoreToPrevious", 35 "undefinedDisposalMethod4", 36 "undefinedDisposalMethod5", 37 "undefinedDisposalMethod6", 38 "undefinedDisposalMethod7" 39 }; 40 41 public int imageLeftPosition; 43 public int imageTopPosition; 44 public int imageWidth; 45 public int imageHeight; 46 public boolean interlaceFlag = false; 47 public boolean sortFlag = false; 48 public byte[] localColorTable = null; 49 50 public int disposalMethod = 0; 52 public boolean userInputFlag = false; 53 public boolean transparentColorFlag = false; 54 public int delayTime = 0; 55 public int transparentColorIndex = 0; 56 57 public boolean hasPlainTextExtension = false; 59 public int textGridLeft; 60 public int textGridTop; 61 public int textGridWidth; 62 public int textGridHeight; 63 public int characterCellWidth; 64 public int characterCellHeight; 65 public int textForegroundColor; 66 public int textBackgroundColor; 67 public byte[] text; 68 69 public List applicationIDs = null; 73 public List authenticationCodes = null; 76 public List applicationData = null; 79 public List comments = null; 83 public GIFImageMetadata() { 84 super(true, 85 nativeMetadataFormatName, 86 "com.sun.imageio.plugins.gif.GIFImageMetadataFormat", 87 null, null); 88 } 89 90 public boolean isReadOnly() { 91 return true; 92 } 93 94 public Node getAsTree(String formatName) { 95 if (formatName.equals(nativeMetadataFormatName)) { 96 return getNativeTree(); 97 } else if (formatName.equals 98 (IIOMetadataFormatImpl.standardMetadataFormatName)) { 99 return getStandardTree(); 100 } else { 101 throw new IllegalArgumentException ("Not a recognized format!"); 102 } 103 } 104 105 private String toISO8859(byte[] data) { 106 try { 107 return new String (data, "ISO-8859-1"); 108 } catch (UnsupportedEncodingException e) { 109 return ""; 110 } 111 } 112 113 private Node getNativeTree() { 114 IIOMetadataNode node; IIOMetadataNode root = 116 new IIOMetadataNode (nativeMetadataFormatName); 117 118 node = new IIOMetadataNode ("ImageDescriptor"); 120 node.setAttribute("imageLeftPosition", 121 Integer.toString(imageLeftPosition)); 122 node.setAttribute("imageTopPosition", 123 Integer.toString(imageTopPosition)); 124 node.setAttribute("imageWidth", Integer.toString(imageWidth)); 125 node.setAttribute("imageHeight", Integer.toString(imageHeight)); 126 node.setAttribute("interlaceFlag", 127 interlaceFlag ? "true" : "false"); 128 root.appendChild(node); 129 130 if (localColorTable != null) { 132 node = new IIOMetadataNode ("LocalColorTable"); 133 int numEntries = localColorTable.length/3; 134 node.setAttribute("sizeOfLocalColorTable", 135 Integer.toString(numEntries)); 136 node.setAttribute("sortFlag", 137 sortFlag ? "TRUE" : "FALSE"); 138 139 for (int i = 0; i < numEntries; i++) { 140 IIOMetadataNode entry = 141 new IIOMetadataNode ("ColorTableEntry"); 142 entry.setAttribute("index", Integer.toString(i)); 143 int r = localColorTable[3*i] & 0xff; 144 int g = localColorTable[3*i + 1] & 0xff; 145 int b = localColorTable[3*i + 2] & 0xff; 146 entry.setAttribute("red", Integer.toString(r)); 147 entry.setAttribute("green", Integer.toString(g)); 148 entry.setAttribute("blue", Integer.toString(b)); 149 node.appendChild(entry); 150 } 151 root.appendChild(node); 152 } 153 154 node = new IIOMetadataNode ("GraphicControlExtension"); 156 node.setAttribute("disposalMethod", 157 disposalMethodNames[disposalMethod]); 158 node.setAttribute("userInputFlag", 159 userInputFlag ? "true" : "false"); 160 node.setAttribute("transparentColorFlag", 161 transparentColorFlag ? "true" : "false"); 162 node.setAttribute("delayTime", 163 Integer.toString(delayTime)); 164 node.setAttribute("transparentColorIndex", 165 Integer.toString(transparentColorIndex)); 166 root.appendChild(node); 167 168 if (hasPlainTextExtension) { 169 node = new IIOMetadataNode ("PlainTextExtension"); 170 node.setAttribute("textGridLeft", 171 Integer.toString(textGridLeft)); 172 node.setAttribute("textGridTop", 173 Integer.toString(textGridTop)); 174 node.setAttribute("textGridWidth", 175 Integer.toString(textGridWidth)); 176 node.setAttribute("textGridHeight", 177 Integer.toString(textGridHeight)); 178 node.setAttribute("characterCellWidth", 179 Integer.toString(characterCellWidth)); 180 node.setAttribute("characterCellHeight", 181 Integer.toString(characterCellHeight)); 182 node.setAttribute("textForegroundColor", 183 Integer.toString(textForegroundColor)); 184 node.setAttribute("textBackgroundColor", 185 Integer.toString(textBackgroundColor)); 186 node.setAttribute("text", toISO8859(text)); 187 188 root.appendChild(node); 189 } 190 191 int numAppExtensions = applicationIDs == null ? 193 0 : applicationIDs.size(); 194 if (numAppExtensions > 0) { 195 node = new IIOMetadataNode ("ApplicationExtensions"); 196 for (int i = 0; i < numAppExtensions; i++) { 197 IIOMetadataNode appExtNode = 198 new IIOMetadataNode ("ApplicationExtension"); 199 byte[] applicationID = (byte[])applicationIDs.get(i); 200 appExtNode.setAttribute("applicationID", 201 toISO8859(applicationID)); 202 byte[] authenticationCode = (byte[])authenticationCodes.get(i); 203 appExtNode.setAttribute("authenticationCode", 204 toISO8859(authenticationCode)); 205 byte[] appData = (byte[])applicationData.get(i); 206 appExtNode.setUserObject((byte[])appData.clone()); 207 node.appendChild(appExtNode); 208 } 209 210 root.appendChild(node); 211 } 212 213 int numComments = comments == null ? 0 : comments.size(); 215 if (numComments > 0) { 216 node = new IIOMetadataNode ("CommentExtensions"); 217 for (int i = 0; i < numComments; i++) { 218 IIOMetadataNode commentNode = 219 new IIOMetadataNode ("CommentExtension"); 220 byte[] comment = (byte[])comments.get(i); 221 commentNode.setAttribute("value", toISO8859(comment)); 222 node.appendChild(commentNode); 223 } 224 225 root.appendChild(node); 226 } 227 228 return root; 229 } 230 231 public IIOMetadataNode getStandardChromaNode() { 232 IIOMetadataNode chroma_node = new IIOMetadataNode ("Chroma"); 233 IIOMetadataNode node = null; 235 node = new IIOMetadataNode ("ColorSpaceType"); 236 node.setAttribute("name", "RGB"); 237 chroma_node.appendChild(node); 238 239 node = new IIOMetadataNode ("NumChannels"); 240 node.setAttribute("value", transparentColorFlag ? "4" : "3"); 241 chroma_node.appendChild(node); 242 243 245 node = new IIOMetadataNode ("BlackIsZero"); 246 node.setAttribute("value", "TRUE"); 247 chroma_node.appendChild(node); 248 249 if (localColorTable != null) { 250 node = new IIOMetadataNode ("Palette"); 251 int numEntries = localColorTable.length/3; 252 for (int i = 0; i < numEntries; i++) { 253 IIOMetadataNode entry = 254 new IIOMetadataNode ("PaletteEntry"); 255 entry.setAttribute("index", Integer.toString(i)); 256 entry.setAttribute("red", 257 Integer.toString(localColorTable[3*i] & 0xff)); 258 entry.setAttribute("green", 259 Integer.toString(localColorTable[3*i + 1] & 0xff)); 260 entry.setAttribute("blue", 261 Integer.toString(localColorTable[3*i + 2] & 0xff)); 262 node.appendChild(entry); 263 } 264 chroma_node.appendChild(node); 265 } 266 267 270 return chroma_node; 271 } 272 273 public IIOMetadataNode getStandardCompressionNode() { 274 IIOMetadataNode compression_node = new IIOMetadataNode ("Compression"); 275 IIOMetadataNode node = null; 277 node = new IIOMetadataNode ("CompressionTypeName"); 278 node.setAttribute("value", "lzw"); 279 compression_node.appendChild(node); 280 281 node = new IIOMetadataNode ("Lossless"); 282 node.setAttribute("value", "TRUE"); 283 compression_node.appendChild(node); 284 285 node = new IIOMetadataNode ("NumProgressiveScans"); 286 node.setAttribute("value", interlaceFlag ? "4" : "1"); 287 compression_node.appendChild(node); 288 289 291 return compression_node; 292 } 293 294 public IIOMetadataNode getStandardDataNode() { 295 IIOMetadataNode data_node = new IIOMetadataNode ("Data"); 296 IIOMetadataNode node = null; 298 300 node = new IIOMetadataNode ("SampleFormat"); 301 node.setAttribute("value", "Index"); 302 data_node.appendChild(node); 303 304 308 return data_node; 309 } 310 311 public IIOMetadataNode getStandardDimensionNode() { 312 IIOMetadataNode dimension_node = new IIOMetadataNode ("Dimension"); 313 IIOMetadataNode node = null; 315 317 node = new IIOMetadataNode ("ImageOrientation"); 318 node.setAttribute("value", "Normal"); 319 dimension_node.appendChild(node); 320 321 328 node = new IIOMetadataNode ("HorizontalPixelOffset"); 329 node.setAttribute("value", Integer.toString(imageLeftPosition)); 330 dimension_node.appendChild(node); 331 332 node = new IIOMetadataNode ("VerticalPixelOffset"); 333 node.setAttribute("value", Integer.toString(imageTopPosition)); 334 dimension_node.appendChild(node); 335 336 339 return dimension_node; 340 } 341 342 344 public IIOMetadataNode getStandardTextNode() { 345 if (comments == null) { 346 return null; 347 } 348 Iterator commentIter = comments.iterator(); 349 if (!commentIter.hasNext()) { 350 return null; 351 } 352 353 IIOMetadataNode text_node = new IIOMetadataNode ("Text"); 354 IIOMetadataNode node = null; 356 while (commentIter.hasNext()) { 357 byte[] comment = (byte[])commentIter.next(); 358 String s = null; 359 try { 360 s = new String (comment, "ISO-8859-1"); 361 } catch (UnsupportedEncodingException e) { 362 throw new RuntimeException ("Encoding ISO-8859-1 unknown!"); 363 } 364 365 node = new IIOMetadataNode ("TextEntry"); 366 node.setAttribute("value", s); 367 node.setAttribute("encoding", "ISO-8859-1"); 368 node.setAttribute("compression", "none"); 369 text_node.appendChild(node); 370 } 371 372 return text_node; 373 } 374 375 public IIOMetadataNode getStandardTransparencyNode() { 376 if (!transparentColorFlag) { 377 return null; 378 } 379 380 IIOMetadataNode transparency_node = 381 new IIOMetadataNode ("Transparency"); 382 IIOMetadataNode node = null; 384 386 node = new IIOMetadataNode ("TransparentIndex"); 387 node.setAttribute("value", 388 Integer.toString(transparentColorIndex)); 389 transparency_node.appendChild(node); 390 391 395 return transparency_node; 396 } 397 398 public void setFromTree(String formatName, Node root) { 399 throw new IllegalStateException ("Metadata is read-only!"); 400 } 401 402 public void mergeTree(String formatName, Node root) { 403 throw new IllegalStateException ("Metadata is read-only!"); 404 } 405 406 public void reset() { 407 throw new IllegalStateException ("Metadata is read-only!"); 408 } 409 } 410 | Popular Tags |