Frames | No Frames |
1: /* ImageWriter.java -- Encodes raster images. 2: Copyright (C) 2004, 2005 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.imageio; 40: 41: import java.awt.Dimension; 42: import java.awt.Rectangle; 43: import java.awt.image.BufferedImage; 44: import java.awt.image.Raster; 45: import java.awt.image.RenderedImage; 46: import java.io.IOException; 47: import java.util.ArrayList; 48: import java.util.Iterator; 49: import java.util.List; 50: import java.util.Locale; 51: import java.util.ResourceBundle; 52: import java.util.MissingResourceException; 53: 54: import javax.imageio.event.IIOWriteProgressListener; 55: import javax.imageio.event.IIOWriteWarningListener; 56: import javax.imageio.metadata.IIOMetadata; 57: 58: import javax.imageio.spi.ImageWriterSpi; 59: 60: /** 61: * A class for encoding images within the ImageIO framework. 62: * 63: * An ImageWriter for a given format is instantiated by an 64: * ImageWriterSpi for that format. ImageWriterSpis are registered 65: * with the IIORegistry. 66: * 67: * The ImageWriter API supports writing animated images that may have 68: * multiple frames; to support such images many methods take an index 69: * parameter. 70: * 71: * Images may also be written in multiple passes, where each 72: * successive pass increases the level of detail in the destination 73: * image. 74: */ 75: public abstract class ImageWriter 76: implements ImageTranscoder 77: { 78: private boolean aborted; 79: 80: /** 81: * All locales available for localization of warning messages, or 82: * null if localization is not supported. 83: */ 84: protected Locale[] availableLocales = null; 85: 86: /** 87: * The current locale used to localize warning messages, or null if 88: * no locale has been set. 89: */ 90: protected Locale locale = null; 91: 92: /** 93: * The image writer SPI that instantiated this writer. 94: */ 95: protected ImageWriterSpi originatingProvider = null; 96: 97: /** 98: * An ImageInputStream to which image data is written. 99: */ 100: protected Object output = null; 101: 102: /** 103: * A list of installed progress listeners. Initially null, meaning 104: * no installed listeners. 105: */ 106: protected List<IIOWriteProgressListener> progressListeners = null; 107: 108: /** 109: * A list of installed warning listeners. Initially null, meaning 110: * no installed listeners. 111: */ 112: protected List<IIOWriteWarningListener> warningListeners = null; 113: 114: /** 115: * A list of warning locales corresponding with the list of 116: * installed warning listeners. Initially null, meaning no locales. 117: */ 118: protected List<Locale> warningLocales = null; 119: 120: /** 121: * Construct an image writer. 122: * 123: * @param originatingProvider the provider that is constructing this 124: * image writer, or null 125: */ 126: protected ImageWriter(ImageWriterSpi originatingProvider) 127: { 128: this.originatingProvider = originatingProvider; 129: } 130: 131: /** 132: * Throw an IllegalStateException if output is null. 133: * 134: * @exception IllegalStateException if output is null 135: */ 136: private void checkOutputSet() 137: { 138: if (output == null) 139: throw new IllegalStateException("no output set"); 140: } 141: 142: /** 143: * Request that writing be aborted. The unwritten portions of the 144: * destination image will be undefined. 145: * 146: * Writers should clear the abort flag before starting a write 147: * operation, then poll it periodically during the write operation. 148: */ 149: public void abort() 150: { 151: aborted = true; 152: } 153: 154: /** 155: * Check if the abort flag is set. 156: * 157: * @return true if the current write operation should be aborted, 158: * false otherwise 159: */ 160: protected boolean abortRequested() 161: { 162: return aborted; 163: } 164: 165: /** 166: * Install a write progress listener. This method will return 167: * immediately if listener is null. 168: * 169: * @param listener a write progress listener or null 170: */ 171: public void addIIOWriteProgressListener(IIOWriteProgressListener listener) 172: { 173: if (listener == null) 174: return; 175: if (progressListeners == null) 176: progressListeners = new ArrayList (); 177: progressListeners.add(listener); 178: } 179: 180: /** 181: * Install a write warning listener. This method will return 182: * immediately if listener is null. Warning messages sent to this 183: * listener will be localized using the current locale. If the 184: * current locale is null then this writer will select a sensible 185: * default. 186: * 187: * @param listener a write warning listener 188: */ 189: public void addIIOWriteWarningListener (IIOWriteWarningListener listener) 190: { 191: if (listener == null) 192: return; 193: if (warningListeners == null) 194: warningListeners = new ArrayList (); 195: warningListeners.add(listener); 196: } 197: 198: /** 199: * Check whether a new empty image can be inserted at the given 200: * frame index. Pixel values may be filled in later using the 201: * replacePixels methods. Indices greater than the insertion index 202: * will be incremented. If imageIndex is -1, the image will be 203: * appended at the end of the current image list. 204: * 205: * @param imageIndex the frame index 206: * 207: * @return true if an empty image can be inserted at imageIndex, 208: * false otherwise 209: * 210: * @exception IllegalStateException if output is null 211: * @exception IndexOutOfBoundsException if imageIndex is less than 212: * -1 or greater than the last index in the current image list 213: * @exception IOException if a write error occurs 214: */ 215: public boolean canInsertEmpty(int imageIndex) 216: throws IOException 217: { 218: checkOutputSet(); 219: return false; 220: } 221: 222: /** 223: * Check whether an image can be inserted at the given frame index. 224: * Indices greater than the insertion index will be incremented. If 225: * imageIndex is -1, the image will be appended at the end of the 226: * current image list. 227: * 228: * @param imageIndex the frame index 229: * 230: * @return true if an image can be inserted at imageIndex, false 231: * otherwise 232: * 233: * @exception IllegalStateException if output is null 234: * @exception IndexOutOfBoundsException if imageIndex is less than 235: * -1 or greater than the last index in the current image list 236: * @exception IOException if a write error occurs 237: */ 238: public boolean canInsertImage(int imageIndex) 239: throws IOException 240: { 241: checkOutputSet(); 242: return false; 243: } 244: 245: /** 246: * Check whether an image can be removed from the given frame index. 247: * Indices greater than the removal index will be decremented. 248: * 249: * @param imageIndex the frame index 250: * 251: * @return true if an image can be removed from imageIndex, false 252: * otherwise 253: * 254: * @exception IllegalStateException if output is null 255: * @exception IndexOutOfBoundsException if imageIndex is less than 0 256: * or greater than the last index in the current image list 257: * @exception IOException if a write error occurs 258: */ 259: public boolean canRemoveImage(int imageIndex) 260: throws IOException 261: { 262: checkOutputSet(); 263: return false; 264: } 265: 266: /** 267: * Check whether the metadata associated the image at the given 268: * frame index can be replaced. 269: * 270: * @param imageIndex the frame index 271: * 272: * @return true if the metadata associated with the image at 273: * imageIndex can be replaced, false otherwise 274: * 275: * @exception IllegalStateException if output is null 276: * @exception IndexOutOfBoundsException if imageIndex is less than 0 277: * or greater than the last index in the current image list 278: * @exception IOException if a write error occurs 279: */ 280: public boolean canReplaceImageMetadata(int imageIndex) 281: throws IOException 282: { 283: checkOutputSet(); 284: return false; 285: } 286: 287: /** 288: * Check whether the pixels within the image at the given index can 289: * be replaced. 290: * 291: * @param imageIndex the frame index 292: * 293: * @return true if the pixels in the image at imageIndex can be 294: * replaced, false otherwise 295: * 296: * @exception IllegalStateException if output is null 297: * @exception IndexOutOfBoundsException if imageIndex is less than 0 298: * or greater than the last index in the current image list 299: * @exception IOException if a write error occurs 300: */ 301: public boolean canReplacePixels(int imageIndex) 302: throws IOException 303: { 304: checkOutputSet(); 305: return false; 306: } 307: 308: /** 309: * Check whether the metadata associated the entire image stream can 310: * be replaced. 311: * 312: * @return true if the stream metadata can be replaced, false 313: * otherwise 314: * 315: * @exception IllegalStateException if output is null 316: * @exception IOException if a write error occurs 317: */ 318: public boolean canReplaceStreamMetadata() 319: throws IOException 320: { 321: checkOutputSet(); 322: return false; 323: } 324: 325: /** 326: * Check whether an entire empty image, including empty metadata and 327: * empty thumbnails, can be written to the output stream, leaving 328: * pixel values to be filled in later using the replacePixels 329: * methods. 330: * 331: * @return true if an entire empty image can be written before its 332: * contents are filled in, false otherwise 333: * 334: * @exception IllegalStateException if output is null 335: * @exception IOException if a write error occurs 336: */ 337: public boolean canWriteEmpty() 338: throws IOException 339: { 340: checkOutputSet(); 341: return false; 342: } 343: 344: /** 345: * Check if IIOImages containing raster data are supported. 346: * 347: * @return true if raster IIOImages are supported, false otherwise 348: */ 349: public boolean canWriteRasters() 350: { 351: return false; 352: } 353: 354: /** 355: * Check if an image can be appended at the end of the current list 356: * of images even if prior images have already been written. 357: * 358: * @return true if sequences of images can be written, false 359: * otherwise 360: */ 361: public boolean canWriteSequence() 362: { 363: return false; 364: } 365: 366: /** 367: * Clear the abort flag. 368: */ 369: protected void clearAbortRequest() 370: { 371: aborted = false; 372: } 373: 374: /** 375: * Convert IIOMetadata from an input reader format, returning an 376: * IIOMetadata suitable for use by an image writer. 377: * 378: * The ImageTypeSpecifier specifies the destination image type. 379: * 380: * An optional ImageWriteParam argument is available in case the 381: * image writing parameters affect the metadata conversion. 382: * 383: * @param inData the metadata coming from an image reader 384: * @param imageType the output image type of the writer 385: * @param param the image writing parameters or null 386: * 387: * @return the converted metadata that should be used by the image 388: * writer, or null if this ImageTranscoder has no knowledge of the 389: * input metadata 390: * 391: * @exception IllegalArgumentException if either inData or imageType 392: * is null 393: */ 394: public abstract IIOMetadata convertImageMetadata (IIOMetadata inData, 395: ImageTypeSpecifier imageType, 396: ImageWriteParam param); 397: 398: /** 399: * Convert IIOMetadata from an input stream format, returning an 400: * IIOMetadata suitable for use by an image writer. 401: * 402: * An optional ImageWriteParam argument is available in case the 403: * image writing parameters affect the metadata conversion. 404: * 405: * @param inData the metadata coming from an input image stream 406: * @param param the image writing parameters or null 407: * 408: * @return the converted metadata that should be used by the image 409: * writer, or null if this ImageTranscoder has no knowledge of the 410: * input metadata 411: * 412: * @exception IllegalArgumentException if inData is null 413: */ 414: public abstract IIOMetadata convertStreamMetadata (IIOMetadata inData, 415: ImageWriteParam param); 416: 417: /** 418: * Releases any resources allocated to this object. Subsequent 419: * calls to methods on this object will produce undefined results. 420: * 421: * The default implementation does nothing; subclasses should use 422: * this method ensure that native resources are released. 423: */ 424: public void dispose() 425: { 426: // The default implementation is empty. Subclasses have to overwrite it. 427: } 428: 429: /** 430: * Retrieve the available locales. Return null if no locales are 431: * available or a clone of availableLocales. 432: * 433: * @return an array of locales or null 434: */ 435: public Locale[] getAvailableLocales() 436: { 437: return availableLocales; 438: } 439: 440: /** 441: * Get a metadata object appropriate for encoding an image specified 442: * by the given image type specifier and optional image write 443: * parameters. 444: * 445: * @param imageType an image type specifier 446: * @param param image writing parameters, or null 447: * 448: * @return a metadata object appropriate for encoding an image of 449: * the given type with the given parameters 450: */ 451: public abstract IIOMetadata getDefaultImageMetadata (ImageTypeSpecifier imageType, ImageWriteParam param); 452: 453: /** 454: * Get a metadata object appropriate for encoding the default image 455: * type handled by this writer, optionally considering image write 456: * parameters. 457: * 458: * @param param image writing parameters, or null 459: * 460: * @return a metadata object appropriate for encoding an image of 461: * the default type with the given parameters 462: */ 463: public abstract IIOMetadata getDefaultStreamMetadata (ImageWriteParam param); 464: 465: /** 466: * Retrieve the default write parameters for this writer's image 467: * format. 468: * 469: * The default implementation returns new ImageWriteParam(). 470: * 471: * @return image writing parameters 472: */ 473: public ImageWriteParam getDefaultWriteParam() 474: { 475: return new ImageWriteParam(getLocale()); 476: } 477: 478: /** 479: * Get this writer's locale. null is returned if the locale has not 480: * been set. 481: * 482: * @return this writer's locale, or null 483: */ 484: public Locale getLocale() 485: { 486: return locale; 487: } 488: 489: /** 490: * Get the number of thumbnails supported by this image writer, 491: * based on the given image type, image writing parameters, and 492: * stream and image metadata. The image writing parameters are 493: * optional, in case they affect the number of thumbnails supported. 494: * 495: * @param imageType an image type specifier, or null 496: * @param param image writing parameters, or null 497: * @param streamMetadata the metadata associated with this stream, 498: * or null 499: * @param imageMetadata the metadata associated with this image, or 500: * null 501: * 502: * @return the number of thumbnails that this writer supports 503: * writing or -1 if the given information is insufficient 504: */ 505: public int getNumThumbnailsSupported (ImageTypeSpecifier imageType, 506: ImageWriteParam param, 507: IIOMetadata streamMetadata, 508: IIOMetadata imageMetadata) 509: { 510: return 0; 511: } 512: 513: /** 514: * Get the ImageWriterSpi that created this writer or null. 515: * 516: * @return an ImageWriterSpi, or null 517: */ 518: public ImageWriterSpi getOriginatingProvider() 519: { 520: return originatingProvider; 521: } 522: 523: /** 524: * Get this reader's image output destination. null is returned if 525: * the image destination has not been set. 526: * 527: * @return an image output destination object, or null 528: */ 529: public Object getOutput() 530: { 531: return output; 532: } 533: 534: /** 535: * Get the preferred sizes for thumbnails based on the given image 536: * type, image writing parameters, and stream and image metadata. 537: * The preferred sizes are returned in pairs of dimension values; 538: * the first value in the array is a dimension object representing 539: * the minimum thumbnail size, the second value is a dimension 540: * object representing a maximum thumbnail size. The writer can 541: * select a size within the range given by each pair, or it can 542: * ignore these size hints. 543: * 544: * @param imageType an image type specifier, or null 545: * @param param image writing parameters, or null 546: * @param streamMetadata the metadata associated with this stream, 547: * or null 548: * @param imageMetadata the metadata associated with this image, or 549: * null 550: * 551: * @return an array of dimension pairs whose length is a multiple of 552: * 2, or null if there is no preferred size (any size is allowed) or 553: * if the size is unknown (insufficient information was provided) 554: */ 555: public Dimension[] getPreferredThumbnailSizes (ImageTypeSpecifier imageType, 556: ImageWriteParam param, 557: IIOMetadata streamMetadata, 558: IIOMetadata imageMetadata) 559: { 560: return null; 561: } 562: 563: /** 564: * Notifies all installed write progress listeners that image 565: * loading has completed by calling their imageComplete methods. 566: */ 567: protected void processImageComplete() 568: { 569: if (progressListeners != null) 570: { 571: Iterator it = progressListeners.iterator(); 572: 573: while (it.hasNext()) 574: { 575: IIOWriteProgressListener listener = 576: (IIOWriteProgressListener) it.next(); 577: listener.imageComplete(this); 578: } 579: } 580: } 581: 582: /** 583: * Notifies all installed write progress listeners that a certain 584: * percentage of the image has been loaded, by calling their 585: * imageProgress methods. 586: * 587: * @param percentageDone the percentage of image data that has been 588: * loaded 589: */ 590: protected void processImageProgress(float percentageDone) 591: { 592: if (progressListeners != null) 593: { 594: Iterator it = progressListeners.iterator(); 595: 596: while (it.hasNext()) 597: { 598: IIOWriteProgressListener listener = 599: (IIOWriteProgressListener) it.next(); 600: listener.imageProgress(this, percentageDone); 601: } 602: } 603: } 604: 605: /** 606: * Notifies all installed write progress listeners, by calling their 607: * imageStarted methods, that image loading has started on the given 608: * image. 609: * 610: * @param imageIndex the frame index of the image that has started 611: * loading 612: */ 613: protected void processImageStarted(int imageIndex) 614: { 615: if (progressListeners != null) 616: { 617: Iterator it = progressListeners.iterator(); 618: 619: while (it.hasNext()) 620: { 621: IIOWriteProgressListener listener = 622: (IIOWriteProgressListener) it.next(); 623: listener.imageStarted(this, imageIndex); 624: } 625: } 626: } 627: 628: /** 629: * Notifies all installed write progress listeners, by calling their 630: * thumbnailComplete methods, that a thumbnail has completed 631: * loading. 632: */ 633: protected void processThumbnailComplete() 634: { 635: if (progressListeners != null) 636: { 637: Iterator it = progressListeners.iterator(); 638: 639: while (it.hasNext()) 640: { 641: IIOWriteProgressListener listener = 642: (IIOWriteProgressListener) it.next(); 643: listener.thumbnailComplete(this); 644: } 645: } 646: } 647: 648: /** 649: * Notifies all installed write progress listeners that a certain 650: * percentage of a thumbnail has been loaded, by calling their 651: * thumbnailProgress methods. 652: * 653: * @param percentageDone the percentage of thumbnail data that has 654: * been loaded 655: */ 656: protected void processThumbnailProgress(float percentageDone) 657: { 658: if (progressListeners != null) 659: { 660: Iterator it = progressListeners.iterator(); 661: 662: while (it.hasNext()) 663: { 664: IIOWriteProgressListener listener = 665: (IIOWriteProgressListener) it.next(); 666: listener.thumbnailProgress(this, percentageDone); 667: } 668: } 669: } 670: 671: /** 672: * Notifies all installed write progress listeners, by calling their 673: * imageStarted methods, that thumbnail loading has started on the 674: * given thumbnail of the given image. 675: * 676: * @param imageIndex the frame index of the image one of who's 677: * thumbnails has started loading 678: * @param thumbnailIndex the index of the thumbnail that has started 679: * loading 680: */ 681: protected void processThumbnailStarted(int imageIndex, int thumbnailIndex) 682: { 683: if (progressListeners != null) 684: { 685: Iterator it = progressListeners.iterator(); 686: 687: while (it.hasNext()) 688: { 689: IIOWriteProgressListener listener = 690: (IIOWriteProgressListener) it.next(); 691: listener.thumbnailStarted(this, imageIndex, thumbnailIndex); 692: } 693: } 694: } 695: 696: /** 697: * Notifies all installed warning listeners, by calling their 698: * warningOccurred methods, that a warning message has been raised. 699: * 700: * @param imageIndex the index of the image that was being written 701: * when the warning was raised 702: * @param warning the warning message 703: * 704: * @exception IllegalArgumentException if warning is null 705: */ 706: protected void processWarningOccurred(int imageIndex, String warning) 707: { 708: if (warningListeners != null) 709: { 710: Iterator it = warningListeners.iterator(); 711: 712: while (it.hasNext()) 713: { 714: IIOWriteWarningListener listener = 715: (IIOWriteWarningListener) it.next(); 716: listener.warningOccurred(this, imageIndex, warning); 717: } 718: } 719: } 720: 721: /** 722: * Notify all installed warning listeners, by calling their 723: * warningOccurred methods, that a warning message has been raised. 724: * The warning message is retrieved from a resource bundle, using 725: * the given basename and keyword. 726: * 727: * @param imageIndex the index of the image that was being written 728: * when the warning was raised 729: * @param baseName the basename of the resource from which to 730: * retrieve the warning message 731: * @param keyword the keyword used to retrieve the warning from the 732: * resource bundle 733: * 734: * @exception IllegalArgumentException if either baseName or keyword 735: * is null 736: * @exception IllegalArgumentException if no resource bundle is 737: * found using baseName 738: * @exception IllegalArgumentException if the given keyword produces 739: * no results from the resource bundle 740: * @exception IllegalArgumentException if the retrieved object is 741: * not a String 742: */ 743: protected void processWarningOccurred(int imageIndex, 744: String baseName, 745: String keyword) 746: { 747: if (baseName == null || keyword == null) 748: throw new IllegalArgumentException ("null argument"); 749: 750: ResourceBundle b = null; 751: 752: try 753: { 754: b = ResourceBundle.getBundle(baseName, getLocale()); 755: } 756: catch (MissingResourceException e) 757: { 758: throw new IllegalArgumentException ("no resource bundle found"); 759: } 760: 761: Object str = null; 762: 763: try 764: { 765: str = b.getObject(keyword); 766: } 767: catch (MissingResourceException e) 768: { 769: throw new IllegalArgumentException ("no results found for keyword"); 770: } 771: 772: if (! (str instanceof String)) 773: throw new IllegalArgumentException ("retrieved object not a String"); 774: 775: String warning = (String) str; 776: 777: if (warningListeners != null) 778: { 779: Iterator it = warningListeners.iterator(); 780: 781: while (it.hasNext()) 782: { 783: IIOWriteWarningListener listener = 784: (IIOWriteWarningListener) it.next(); 785: listener.warningOccurred(this, imageIndex, warning); 786: } 787: } 788: } 789: 790: /** 791: * Notifies all installed write progress listeners that image 792: * loading has been aborted by calling their writeAborted methods. 793: */ 794: protected void processWriteAborted() 795: { 796: if (progressListeners != null) 797: { 798: Iterator it = progressListeners.iterator(); 799: 800: while (it.hasNext()) 801: { 802: IIOWriteProgressListener listener = 803: (IIOWriteProgressListener) it.next(); 804: listener.writeAborted(this); 805: } 806: } 807: } 808: 809: /** 810: * Uninstall all write progress listeners. 811: */ 812: public void removeAllIIOWriteProgressListeners() 813: { 814: if (progressListeners != null) 815: { 816: progressListeners.clear(); 817: } 818: } 819: 820: /** 821: * Uninstall all write warning listeners. 822: */ 823: public void removeAllIIOWriteWarningListeners() 824: { 825: if (progressListeners != null) 826: { 827: progressListeners.clear(); 828: } 829: } 830: 831: /** 832: * Uninstall the given write progress listener. 833: * 834: * @param listener the listener to remove 835: */ 836: public void removeIIOWriteProgressListener (IIOWriteProgressListener listener) 837: { 838: if (listener == null) 839: return; 840: if (progressListeners != null) 841: { 842: progressListeners.remove(listener); 843: } 844: } 845: /** 846: * Uninstall the given write warning listener. 847: * 848: * @param listener the listener to remove 849: */ 850: public void removeIIOWriteWarningListener (IIOWriteWarningListener listener) 851: { 852: if (listener == null) 853: return; 854: if (warningListeners != null) 855: { 856: warningListeners.remove(listener); 857: } 858: } 859: /** 860: * Reset this writer's internal state. 861: */ 862: public void reset() 863: { 864: setOutput(null); 865: setLocale(null); 866: removeAllIIOWriteWarningListeners(); 867: removeAllIIOWriteProgressListeners(); 868: clearAbortRequest(); 869: } 870: 871: /** 872: * Set the current locale or use the default locale. 873: * 874: * @param locale the locale to set, or null 875: */ 876: public void setLocale(Locale locale) 877: { 878: if (locale != null) 879: { 880: // Check if its a valid locale. 881: boolean found = false; 882: 883: if (availableLocales != null) 884: for (int i = availableLocales.length - 1; i >= 0; --i) 885: if (availableLocales[i].equals(locale)) 886: found = true; 887: 888: if (! found) 889: throw new IllegalArgumentException("looale not available"); 890: } 891: 892: this.locale = locale; 893: } 894: 895: /** 896: * Set the output destination of the given object. The output 897: * destination must be set before many methods can be called on this 898: * writer. (see all ImageWriter methods that throw 899: * IllegalStateException). If input is null then the current input 900: * source will be removed. 901: * 902: * @param output the output destination object 903: * 904: * @exception IllegalArgumentException if input is not a valid input 905: * source for this writer and is not an ImageInputStream 906: */ 907: public void setOutput(Object output) 908: { 909: if (output != null) 910: { 911: // Check if its a valid output object. 912: boolean found = false; 913: Class[] types = null; 914: 915: if (originatingProvider != null) 916: types = originatingProvider.getOutputTypes(); 917: 918: if (types != null) 919: for (int i = types.length - 1; i >= 0; --i) 920: if (types[i].isInstance(output)) 921: found = true; 922: 923: if (! found) 924: throw new IllegalArgumentException("output type not available"); 925: } 926: 927: this.output = output; 928: } 929: 930: /** 931: * Write an image stream, including thumbnails and metadata to the 932: * output stream. The output must have been set prior to this 933: * method being called. Metadata associated with the stream may be 934: * supplied, or it can be left null. IIOImage may contain raster 935: * data if this writer supports rasters, or it will contain a 936: * rendered image. Thumbnails are resized if need be. Image 937: * writing parameters may be specified to affect writing, or may be 938: * left null. 939: * 940: * @param streamMetadata metadata associated with this stream, or 941: * null 942: * @param image an IIOImage containing image data, metadata and 943: * thumbnails to be written 944: * @param param image writing parameters, or null 945: * 946: * @exception IllegalStateException if output is null 947: * @exception UnsupportedOperationException if image contains raster 948: * data but this writer does not support rasters 949: * @exception IllegalArgumentException if image is null 950: * @exception IOException if a write error occurs 951: */ 952: public abstract void write (IIOMetadata streamMetadata, IIOImage image, ImageWriteParam param) 953: throws IOException; 954: 955: /** 956: * Complete inserting an empty image in the output stream. 957: * 958: * @exception IllegalStateException if output is null 959: * @exception UnsupportedOperationException if inserting empty 960: * images is not supported 961: * @exception IllegalArgumentException if a call to 962: * prepareInsertEmpty was not called previous to this method being 963: * called (a sequence of prepareInsertEmpty calls must be terminated 964: * by a call to endInsertEmpty) 965: * @exception IllegalArgumentException if prepareWriteEmpty was 966: * called before this method being called (without a terminating 967: * call to endWriteEmpty) 968: * @exception IllegalArgumentException if prepareReplacePixels was 969: * called before this method being called (without a terminating 970: * call to endReplacePixels) 971: * @exception IOException if a write error occurs 972: */ 973: public void endInsertEmpty () 974: throws IOException 975: { 976: if (!canInsertEmpty(0)) 977: throw new UnsupportedOperationException(); 978: } 979: 980: /** 981: * Complete replacing pixels in an image in the output stream. 982: * 983: * @exception IllegalStateException if output is null 984: * @exception UnsupportedOperationException if replacing pixels is 985: * not supported by this writer 986: * @exception IllegalArgumentException if prepareReplacePixels was 987: * not called before this method being called 988: * @exception IOException if a write error occurs 989: */ 990: public void endReplacePixels () 991: throws IOException 992: { 993: if (!canReplacePixels(0)) 994: throw new UnsupportedOperationException(); 995: } 996: 997: /** 998: * Complete writing an empty image to the image output stream. 999: * 1000: * @exception IllegalStateException if output is null 1001: * @exception UnsupportedOperationException if writing empty images 1002: * is not supported 1003: * @exception IllegalArgumentException if a call to 1004: * prepareWriteEmpty was not called previous to this method being 1005: * called (a sequence of prepareWriteEmpty calls must be terminated 1006: * by a call to endWriteEmpty) 1007: * @exception IllegalArgumentException if prepareInsertEmpty was 1008: * called before this method being called (without a terminating 1009: * call to endInsertEmpty) 1010: * @exception IllegalArgumentException if prepareReplacePixels was 1011: * called before this method being called (without a terminating 1012: * call to endReplacePixels) 1013: * @exception IOException if a write error occurs 1014: */ 1015: public void endWriteEmpty () 1016: throws IOException 1017: { 1018: if (!canWriteEmpty()) 1019: throw new UnsupportedOperationException(); 1020: } 1021: 1022: /** 1023: * Complete writing a sequence of images to the output stream. This 1024: * method may patch header data and write out footer data. 1025: * 1026: * @exception IllegalStateException if output is null 1027: * @exception IllegalStateException if prepareWriteSequence has not 1028: * been called 1029: * @exception UnsupportedOperationException if writing a sequence of 1030: * images is not supported 1031: * @exception IOException if a write error occurs 1032: */ 1033: public void endWriteSequence () 1034: throws IOException 1035: { 1036: checkOutputSet(); 1037: if (!canWriteSequence()) 1038: throw new UnsupportedOperationException(); 1039: } 1040: 1041: /** 1042: * Start inserting an empty image in the image output stream. All 1043: * indices after the specified index are incremented. An index of 1044: * -1 implies that the empty image should be appended to the end of 1045: * the current image list. 1046: * 1047: * The insertion that this method call starts is not complete until 1048: * endInsertEmpty is called. prepareInsertEmpty cannot be called 1049: * again until endInsertEmpty is called and calls to 1050: * prepareWriteEmpty and prepareInsertEmpty may not be intersperced. 1051: * 1052: * @param imageIndex the image index 1053: * @param imageType the image type specifier 1054: * @param width the image width 1055: * @param height the image height 1056: * @param imageMetadata the image metadata, or null 1057: * @param thumbnails a list of thumbnails, or null 1058: * @param param image write parameters, or null 1059: * 1060: * @exception IllegalStateException if output is null 1061: * @exception UnsupportedOperationException if inserting empty 1062: * images is not supported 1063: * @exception IndexOutOfBoundsException if imageIndex is less than 1064: * -1 or greater than the last index in the current image list 1065: * @exception IllegalStateException if a previous call to 1066: * prepareInsertEmpty was made (without a terminating call to 1067: * endInsertEmpty) 1068: * @exception IllegalStateException if a previous call to 1069: * prepareWriteEmpty was made (without a terminating call to 1070: * endWriteEmpty) 1071: * @exception IllegalArgumentException if imageType is null or 1072: * thumbnails contain non-BufferedImage objects 1073: * @exception IllegalArgumentException if either width or height is 1074: * less than 1 1075: * @exception IOException if a write error occurs 1076: */ 1077: public void prepareInsertEmpty (int imageIndex, ImageTypeSpecifier imageType, 1078: int width, int height, 1079: IIOMetadata imageMetadata, 1080: List<? extends BufferedImage> thumbnails, 1081: ImageWriteParam param) 1082: throws IOException 1083: { 1084: if (!canInsertEmpty(imageIndex)) 1085: throw new UnsupportedOperationException(); 1086: } 1087: 1088: /** 1089: * Start the replacement of pixels within an image in the output 1090: * stream. Output pixels will be clipped to lie within region. 1091: * 1092: * @param imageIndex the index of the image in which pixels are 1093: * being replaced 1094: * @param region the rectangle to which to limit pixel replacement 1095: * 1096: * @exception IllegalStateException if output is null 1097: * @exception UnsupportedOperationException if replacing pixels is 1098: * not supported 1099: * @exception IndexOutOfBoundsException if imageIndex is less than 0 1100: * or greater than the last index in the current image list 1101: * @exception IllegalStateException if a previous call to 1102: * prepareReplacePixels was made (without a terminating call to 1103: * endReplacePixels) 1104: * @exception IllegalArgumentException if either region.width or 1105: * region.height is less than 1, or if region is null 1106: * @exception IOException if a write error occurs 1107: */ 1108: public void prepareReplacePixels (int imageIndex, Rectangle region) 1109: throws IOException 1110: { 1111: if (canReplacePixels(imageIndex)) 1112: throw new UnsupportedOperationException(); 1113: } 1114: 1115: /** 1116: * Start writing an empty image to the end of the image output 1117: * stream. 1118: * 1119: * The writing that this method call starts is not complete until 1120: * endWriteEmpty is called. prepareWritetEmpty cannot be called 1121: * again until endWriteEmpty is called and calls to 1122: * prepareWriteEmpty and prepareInsertEmpty may not be intersperced. 1123: * 1124: * @param streamMetadata metadata associated with the stream, or null 1125: * @param imageType the image type specifier 1126: * @param width the image width 1127: * @param height the image height 1128: * @param imageMetadata the image metadata, or null 1129: * @param thumbnails a list of thumbnails, or null 1130: * @param param image write parameters, or null 1131: * 1132: * @exception IllegalStateException if output is null 1133: * @exception UnsupportedOperationException if writing empty images 1134: * is not supported 1135: * @exception IndexOutOfBoundsException if imageIndex is less than 1136: * -1 or greater than the last index in the current image list 1137: * @exception IllegalStateException if a previous call to 1138: * prepareInsertEmpty was made (without a terminating call to 1139: * endInsertEmpty) 1140: * @exception IllegalStateException if a previous call to 1141: * prepareWriteEmpty was made (without a terminating call to 1142: * endWriteEmpty) 1143: * @exception IllegalArgumentException if imageType is null or 1144: * thumbnails contain non-BufferedImage objects 1145: * @exception IllegalArgumentException if either width or height is 1146: * less than 1 1147: * @exception IOException if a write error occurs 1148: */ 1149: public void prepareWriteEmpty (IIOMetadata streamMetadata, 1150: ImageTypeSpecifier imageType, 1151: int width, int height, 1152: IIOMetadata imageMetadata, 1153: List<? extends BufferedImage> thumbnails, 1154: ImageWriteParam param) 1155: throws IOException 1156: { 1157: if (!canWriteEmpty()) 1158: throw new UnsupportedOperationException(); 1159: } 1160: 1161: /** 1162: * Start the writing of a sequence of images. 1163: * 1164: * @param streamMetadata the stream metadata, or null 1165: * 1166: * @exception IllegalStateException if output is null 1167: * @exception UnsupportedOperationException if writing sequences of 1168: * images is not supported 1169: * @exception IOException if a write error occurs 1170: */ 1171: public void prepareWriteSequence (IIOMetadata streamMetadata) 1172: throws IOException 1173: { 1174: checkOutputSet(); 1175: if (!canWriteSequence()) 1176: throw new UnsupportedOperationException(); 1177: } 1178: 1179: /** 1180: * Remove the image at the specified index from the output stream. 1181: * 1182: * @param imageIndex the frame index from which to remove the image 1183: * 1184: * @exception IllegalStateException if output is null 1185: * @exception UnsupportedOperationException if removing this image 1186: * is not supported 1187: * @exception IndexOutOfBoundsException if imageIndex is less than 0 1188: * or greater than the last index in the current image list 1189: * @exception IOException if a write error occurs 1190: */ 1191: public void removeImage (int imageIndex) 1192: throws IOException 1193: { 1194: if (!canRemoveImage(imageIndex)) 1195: throw new UnsupportedOperationException(); 1196: } 1197: 1198: /** 1199: * Replace the metadata associated with the image at the given 1200: * index. 1201: * 1202: * @param imageIndex the index of the image whose metadata should be 1203: * replaced 1204: * @param imageMetadata the metadata, or null 1205: * 1206: * @exception IllegalStateException if output is null 1207: * @exception UnsupportedOperationException if replacing this 1208: * image's metadata is not supported 1209: * @exception IndexOutOfBoundsException if imageIndex is less than 0 1210: * or greater than the last index in the current image list 1211: * @exception IOException if a write error occurs 1212: */ 1213: public void replaceImageMetadata (int imageIndex, IIOMetadata imageMetadata) 1214: throws IOException 1215: { 1216: if (!canReplaceImageMetadata(imageIndex)) 1217: throw new UnsupportedOperationException(); 1218: } 1219: 1220: /** 1221: * Replace a region of an image in the output stream with a portion 1222: * of the given rendered image. The image data must be of the same 1223: * type as that in the output stream. The destination region is 1224: * given by the image writing parameters and the source region is 1225: * the one given to prepareReplacePixels. 1226: * 1227: * @param image the rendered image with which to overwrite the image 1228: * region in the stream 1229: * @param param the image writing parameters 1230: * 1231: * @exception IllegalStateException if output is null 1232: * @exception UnsupportedOperationException if replacing pixels is 1233: * not supported 1234: * @exception IllegalStateException if prepareReplacePixels was not 1235: * called before this method was called 1236: * @exception IllegalArgumentException if image is null or if param 1237: * is null or if the overlap of the source and destination regions 1238: * contains no pixels or if the image types differ and no conversion 1239: * is possible 1240: * @exception IOException if a write error occurs 1241: */ 1242: public void replacePixels (RenderedImage image, 1243: ImageWriteParam param) 1244: throws IOException 1245: { 1246: if (!canReplacePixels(0)) 1247: throw new UnsupportedOperationException(); 1248: } 1249: 1250: /** 1251: * Replace a region of an image in the output stream with a portion 1252: * of the given raster data. The image data must be of the same 1253: * type as that in the output stream. The destination region is 1254: * given by the image writing parameters and the source region is 1255: * the one given to prepareReplacePixels. 1256: * 1257: * @param raster the raster data with which to overwrite the image 1258: * region in the stream 1259: * @param param the image writing parameters 1260: * 1261: * @exception IllegalStateException if output is null 1262: * @exception UnsupportedOperationException if replacing pixels is 1263: * not supported 1264: * @exception IllegalStateException if prepareReplacePixels was not 1265: * called before this method was called 1266: * @exception UnsupportedOperationException if raster data is not 1267: * supported 1268: * @exception IllegalArgumentException if raster is null or if param 1269: * is null or if the overlap of the source and destination regions 1270: * contains no pixels or if the image types differ and no conversion 1271: * is possible 1272: * @exception IOException if a write error occurs 1273: */ 1274: public void replacePixels (Raster raster, ImageWriteParam param) 1275: throws IOException 1276: { 1277: if (!canReplacePixels(0)) 1278: throw new UnsupportedOperationException(); 1279: } 1280: 1281: /** 1282: * Replace the metadata associated with this image stream. 1283: * 1284: * @param streamMetadata the stream metadata, or null 1285: * 1286: * @exception IllegalStateException if output is null 1287: * @exception UnsupportedOperationException if replacing the stream 1288: * metadata is not supported 1289: * @exception IOException if a write error occurs 1290: */ 1291: public void replaceStreamMetadata (IIOMetadata streamMetadata) 1292: throws IOException 1293: { 1294: if (!canReplaceStreamMetadata()) 1295: throw new UnsupportedOperationException(); 1296: } 1297: 1298: /** 1299: * Write a rendered image to the output stream. 1300: * 1301: * @param image a rendered image containing image data to be written 1302: * 1303: * @exception IllegalStateException if output is null 1304: * @exception IllegalArgumentException if image is null 1305: * @exception IOException if a write error occurs 1306: */ 1307: public void write (RenderedImage image) 1308: throws IOException 1309: { 1310: checkOutputSet(); 1311: write (null, new IIOImage(image, null, null), null); 1312: } 1313: 1314: /** 1315: * Write a image data, metadata and thumbnails to the output stream. 1316: * 1317: * @param image image data, metadata and thumbnails to be written 1318: * 1319: * @exception IllegalStateException if output is null 1320: * @exception UnsupportedOperationException if image contains raster 1321: * data but this writer does not support rasters 1322: * @exception IllegalArgumentException if image is null 1323: * @exception IOException if a write error occurs 1324: */ 1325: public void write (IIOImage image) 1326: throws IOException 1327: { 1328: checkOutputSet(); 1329: write (null, image, null); 1330: } 1331: 1332: /** 1333: * Insert an image into the output stream. Indices greater than the 1334: * specified index are incremented accordingly. Specifying an index 1335: * of -1 causes the image to be appended at the end of the current 1336: * image list. 1337: * 1338: * @param imageIndex the frame index at which to insert the image 1339: * @param image the image data, metadata and thumbnails to be 1340: * inserted 1341: * @param param image write parameters, or null 1342: * 1343: * @exception IllegalStateException if output is null 1344: * @exception UnsupportedOperationException if image insertion is 1345: * not supported 1346: * @exception IllegalArgumentException if image is null 1347: * @exception IndexOutOfBoundsException if imageIndex is less than 1348: * -1 or greater than the last index in the current image list 1349: * @exception UnsupportedOperationException if image contains raster 1350: * data but this writer does not support rasters 1351: * @exception IOException if a write error occurs 1352: */ 1353: public void writeInsert (int imageIndex, IIOImage image, ImageWriteParam param) 1354: throws IOException 1355: { 1356: if (!canInsertImage(imageIndex)) 1357: throw new UnsupportedOperationException(); 1358: } 1359: 1360: /** 1361: * Write a sequence of images, including thumbnails and metadata, to 1362: * the output stream. The output must have been set prior to this 1363: * method being called. Metadata associated with the stream may be 1364: * supplied, or it can be left null. IIOImage may contain raster 1365: * data if this writer supports rasters, or it will contain a 1366: * rendered image. Thumbnails are resized if need be. Image 1367: * writing parameters may be specified to affect writing, or may be 1368: * left null. 1369: * 1370: * @param streamMetadata metadata associated with this stream, or 1371: * null 1372: * @param image an IIOImage containing image data, metadata and 1373: * thumbnails to be written 1374: * @param param image writing parameters, or null 1375: * 1376: * @exception IllegalStateException if output is null 1377: * @exception UnsupportedOperationException if writing sequences of 1378: * images is not supported 1379: * @exception IllegalArgumentException if image is null 1380: * @exception UnsupportedOperationException if image contains raster 1381: * data but this writer does not support rasters 1382: * @exception IOException if a write error occurs 1383: */ 1384: public void writeToSequence (IIOImage image, ImageWriteParam param) 1385: throws IOException 1386: { 1387: if (!canWriteSequence()) 1388: throw new UnsupportedOperationException(); 1389: } 1390: }