1 7 8 package com.sun.imageio.plugins.gif; 9 10 import java.io.UnsupportedEncodingException ; 11 import java.nio.charset.Charset ; 12 import java.util.ArrayList ; 13 import java.util.Iterator ; 14 import java.util.List ; 15 import javax.imageio.ImageTypeSpecifier ; 16 import javax.imageio.metadata.IIOInvalidTreeException ; 17 import javax.imageio.metadata.IIOMetadata ; 18 import javax.imageio.metadata.IIOMetadataNode ; 19 import javax.imageio.metadata.IIOMetadataFormat ; 20 import javax.imageio.metadata.IIOMetadataFormatImpl ; 21 import org.w3c.dom.Node ; 22 23 class GIFWritableImageMetadata extends GIFImageMetadata { 24 25 static final String 27 NATIVE_FORMAT_NAME = "javax_imageio_gif_image_1.0"; 28 29 GIFWritableImageMetadata() { 30 super(true, 31 NATIVE_FORMAT_NAME, 32 "com.sun.imageio.plugins.gif.GIFImageMetadataFormat", 33 null, null); 34 } 35 36 public boolean isReadOnly() { 37 return false; 38 } 39 40 public void reset() { 41 imageLeftPosition = 0; 43 imageTopPosition = 0; 44 imageWidth = 0; 45 imageHeight = 0; 46 interlaceFlag = false; 47 sortFlag = false; 48 localColorTable = null; 49 50 disposalMethod = 0; 52 userInputFlag = false; 53 transparentColorFlag = false; 54 delayTime = 0; 55 transparentColorIndex = 0; 56 57 hasPlainTextExtension = false; 59 textGridLeft = 0; 60 textGridTop = 0; 61 textGridWidth = 0; 62 textGridHeight = 0; 63 characterCellWidth = 0; 64 characterCellHeight = 0; 65 textForegroundColor = 0; 66 textBackgroundColor = 0; 67 text = null; 68 69 applicationIDs = null; 71 authenticationCodes = null; 72 applicationData = null; 73 74 comments = null; 77 } 78 79 private byte[] fromISO8859(String data) { 80 try { 81 return data.getBytes("ISO-8859-1"); 82 } catch (UnsupportedEncodingException e) { 83 return (new String ("")).getBytes(); 84 } 85 } 86 87 protected void mergeNativeTree(Node root) throws IIOInvalidTreeException { 88 Node node = root; 89 if (!node.getNodeName().equals(nativeMetadataFormatName)) { 90 fatal(node, "Root must be " + nativeMetadataFormatName); 91 } 92 93 node = node.getFirstChild(); 94 while (node != null) { 95 String name = node.getNodeName(); 96 97 if (name.equals("ImageDescriptor")) { 98 imageLeftPosition = getIntAttribute(node, 99 "imageLeftPosition", 100 -1, true, 101 true, 0, 65535); 102 103 imageTopPosition = getIntAttribute(node, 104 "imageTopPosition", 105 -1, true, 106 true, 0, 65535); 107 108 imageWidth = getIntAttribute(node, 109 "imageWidth", 110 -1, true, 111 true, 1, 65535); 112 113 imageHeight = getIntAttribute(node, 114 "imageHeight", 115 -1, true, 116 true, 1, 65535); 117 118 interlaceFlag = getBooleanAttribute(node, "interlaceFlag", 119 false, true); 120 } else if (name.equals("LocalColorTable")) { 121 int sizeOfLocalColorTable = 122 getIntAttribute(node, "sizeOfLocalColorTable", 123 true, 2, 256); 124 if (sizeOfLocalColorTable != 2 && 125 sizeOfLocalColorTable != 4 && 126 sizeOfLocalColorTable != 8 && 127 sizeOfLocalColorTable != 16 && 128 sizeOfLocalColorTable != 32 && 129 sizeOfLocalColorTable != 64 && 130 sizeOfLocalColorTable != 128 && 131 sizeOfLocalColorTable != 256) { 132 fatal(node, 133 "Bad value for LocalColorTable attribute sizeOfLocalColorTable!"); 134 } 135 136 sortFlag = getBooleanAttribute(node, "sortFlag", false, true); 137 138 localColorTable = getColorTable(node, "ColorTableEntry", 139 true, sizeOfLocalColorTable); 140 } else if (name.equals("GraphicControlExtension")) { 141 String disposalMethodName = 142 getStringAttribute(node, "disposalMethod", null, 143 true, disposalMethodNames); 144 disposalMethod = 0; 145 while(!disposalMethodName.equals(disposalMethodNames[disposalMethod])) { 146 disposalMethod++; 147 } 148 149 userInputFlag = getBooleanAttribute(node, "userInputFlag", 150 false, true); 151 152 transparentColorFlag = 153 getBooleanAttribute(node, "transparentColorFlag", 154 false, true); 155 156 delayTime = getIntAttribute(node, 157 "delayTime", 158 -1, true, 159 true, 0, 65535); 160 161 transparentColorIndex = 162 getIntAttribute(node, "transparentColorIndex", 163 -1, true, 164 true, 0, 65535); 165 } else if (name.equals("PlainTextExtension")) { 166 hasPlainTextExtension = true; 167 168 textGridLeft = getIntAttribute(node, 169 "textGridLeft", 170 -1, true, 171 true, 0, 65535); 172 173 textGridTop = getIntAttribute(node, 174 "textGridTop", 175 -1, true, 176 true, 0, 65535); 177 178 textGridWidth = getIntAttribute(node, 179 "textGridWidth", 180 -1, true, 181 true, 1, 65535); 182 183 textGridHeight = getIntAttribute(node, 184 "textGridHeight", 185 -1, true, 186 true, 1, 65535); 187 188 characterCellWidth = getIntAttribute(node, 189 "characterCellWidth", 190 -1, true, 191 true, 1, 65535); 192 193 characterCellHeight = getIntAttribute(node, 194 "characterCellHeight", 195 -1, true, 196 true, 1, 65535); 197 198 textForegroundColor = getIntAttribute(node, 199 "textForegroundColor", 200 -1, true, 201 true, 0, 255); 202 203 textBackgroundColor = getIntAttribute(node, 204 "textBackgroundColor", 205 -1, true, 206 true, 0, 255); 207 208 214 String textString = 215 getStringAttribute(node, "text", "", false, null); 216 text = fromISO8859(textString); 217 } else if (name.equals("ApplicationExtensions")) { 218 IIOMetadataNode applicationExtension = 219 (IIOMetadataNode )node.getFirstChild(); 220 221 if (!applicationExtension.getNodeName().equals("ApplicationExtension")) { 222 fatal(node, 223 "Only a ApplicationExtension may be a child of a ApplicationExtensions!"); 224 } 225 226 String applicationIDString = 227 getStringAttribute(applicationExtension, "applicationID", 228 null, true, null); 229 230 String authenticationCodeString = 231 getStringAttribute(applicationExtension, "authenticationCode", 232 null, true, null); 233 234 Object applicationExtensionData = 235 applicationExtension.getUserObject(); 236 if (applicationExtensionData == null || 237 !(applicationExtensionData instanceof byte[])) { 238 fatal(applicationExtension, 239 "Bad user object in ApplicationExtension!"); 240 } 241 242 if (applicationIDs == null) { 243 applicationIDs = new ArrayList (); 244 authenticationCodes = new ArrayList (); 245 applicationData = new ArrayList (); 246 } 247 248 applicationIDs.add(fromISO8859(applicationIDString)); 249 authenticationCodes.add(fromISO8859(authenticationCodeString)); 250 applicationData.add(applicationExtensionData); 251 } else if (name.equals("CommentExtensions")) { 252 Node commentExtension = node.getFirstChild(); 253 if (commentExtension != null) { 254 while(commentExtension != null) { 255 if (!commentExtension.getNodeName().equals("CommentExtension")) { 256 fatal(node, 257 "Only a CommentExtension may be a child of a CommentExtensions!"); 258 } 259 260 if (comments == null) { 261 comments = new ArrayList (); 262 } 263 264 String comment = 265 getStringAttribute(commentExtension, "value", null, 266 true, null); 267 268 comments.add(fromISO8859(comment)); 269 270 commentExtension = commentExtension.getNextSibling(); 271 } 272 } 273 } else { 274 fatal(node, "Unknown child of root node!"); 275 } 276 277 node = node.getNextSibling(); 278 } 279 } 280 281 protected void mergeStandardTree(Node root) 282 throws IIOInvalidTreeException { 283 Node node = root; 284 if (!node.getNodeName() 285 .equals(IIOMetadataFormatImpl.standardMetadataFormatName)) { 286 fatal(node, "Root must be " + 287 IIOMetadataFormatImpl.standardMetadataFormatName); 288 } 289 290 node = node.getFirstChild(); 291 while (node != null) { 292 String name = node.getNodeName(); 293 294 if (name.equals("Chroma")) { 295 Node childNode = node.getFirstChild(); 296 while(childNode != null) { 297 String childName = childNode.getNodeName(); 298 if (childName.equals("Palette")) { 299 localColorTable = getColorTable(childNode, 300 "PaletteEntry", 301 false, -1); 302 break; 303 } 304 childNode = childNode.getNextSibling(); 305 } 306 } else if (name.equals("Compression")) { 307 Node childNode = node.getFirstChild(); 308 while(childNode != null) { 309 String childName = childNode.getNodeName(); 310 if (childName.equals("NumProgressiveScans")) { 311 int numProgressiveScans = 312 getIntAttribute(childNode, "value", 4, false, 313 true, 1, Integer.MAX_VALUE); 314 if (numProgressiveScans > 1) { 315 interlaceFlag = true; 316 } 317 break; 318 } 319 childNode = childNode.getNextSibling(); 320 } 321 } else if (name.equals("Dimension")) { 322 Node childNode = node.getFirstChild(); 323 while(childNode != null) { 324 String childName = childNode.getNodeName(); 325 if (childName.equals("HorizontalPixelOffset")) { 326 imageLeftPosition = getIntAttribute(childNode, 327 "value", 328 -1, true, 329 true, 0, 65535); 330 } else if (childName.equals("VerticalPixelOffset")) { 331 imageTopPosition = getIntAttribute(childNode, 332 "value", 333 -1, true, 334 true, 0, 65535); 335 } 336 childNode = childNode.getNextSibling(); 337 } 338 } else if (name.equals("Text")) { 339 Node childNode = node.getFirstChild(); 340 while(childNode != null) { 341 String childName = childNode.getNodeName(); 342 if (childName.equals("TextEntry") && 343 getAttribute(childNode, "compression", 344 "none", false).equals("none") && 345 Charset.isSupported(getAttribute(childNode, 346 "encoding", 347 "ISO-8859-1", 348 false))) { 349 String value = getAttribute(childNode, "value"); 350 byte[] comment = fromISO8859(value); 351 if (comments == null) { 352 comments = new ArrayList (); 353 } 354 comments.add(comment); 355 } 356 childNode = childNode.getNextSibling(); 357 } 358 } else if (name.equals("Transparency")) { 359 Node childNode = node.getFirstChild(); 360 while(childNode != null) { 361 String childName = childNode.getNodeName(); 362 if (childName.equals("TransparentIndex")) { 363 transparentColorIndex = getIntAttribute(childNode, 364 "value", 365 -1, true, 366 true, 0, 255); 367 transparentColorFlag = true; 368 break; 369 } 370 childNode = childNode.getNextSibling(); 371 } 372 } 373 374 node = node.getNextSibling(); 375 } 376 } 377 378 public void setFromTree(String formatName, Node root) 379 throws IIOInvalidTreeException 380 { 381 reset(); 382 mergeTree(formatName, root); 383 } 384 } 385 | Popular Tags |