1. /*
  2. * @(#)ImageWriter.java 1.90 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.imageio;
  8. import java.awt.Dimension;
  9. import java.awt.Rectangle;
  10. import java.awt.image.RenderedImage;
  11. import java.awt.image.Raster;
  12. import java.io.IOException;
  13. import java.util.ArrayList;
  14. import java.util.List;
  15. import java.util.Locale;
  16. import java.util.ResourceBundle;
  17. import javax.imageio.event.IIOWriteWarningListener;
  18. import javax.imageio.event.IIOWriteProgressListener;
  19. import javax.imageio.metadata.IIOMetadata;
  20. import javax.imageio.stream.ImageOutputStream;
  21. import javax.imageio.spi.ImageWriterSpi;
  22. /**
  23. * An abstract superclass for encoding and writing images. This class
  24. * must be subclassed by classes that write out images in the context
  25. * of the Java Image I/O framework.
  26. *
  27. * <p> <code>ImageWriter</code> objects are normally instantiated by
  28. * the service provider class for the specific format. Service
  29. * provider classes are registered with the <code>IIORegistry</code>,
  30. * which uses them for format recognition and presentation of
  31. * available format readers and writers.
  32. *
  33. * <p>
  34. *
  35. * @see ImageReader
  36. * @see ImageWriteParam
  37. * @see javax.imageio.spi.IIORegistry
  38. * @see javax.imageio.spi.ImageWriterSpi
  39. *
  40. * @version 0.5
  41. */
  42. public abstract class ImageWriter implements ImageTranscoder {
  43. /**
  44. * The <code>ImageWriterSpi</code> that instantiated this object,
  45. * or <code>null</code> if its identity is not known or none
  46. * exists. By default it is initialized to <code>null</code>.
  47. */
  48. protected ImageWriterSpi originatingProvider = null;
  49. /**
  50. * The <code>ImageOutputStream</code> or other <code>Object</code>
  51. * set by <code>setOutput</code> and retrieved by
  52. * <code>getOutput</code>. By default it is initialized to
  53. * <code>null</code>.
  54. */
  55. protected Object output = null;
  56. /**
  57. * An array of <code>Locale</code>s that may be used to localize
  58. * warning messages and compression setting values, or
  59. * <code>null</code> if localization is not supported. By default
  60. * it is initialized to <code>null</code>.
  61. */
  62. protected Locale[] availableLocales = null;
  63. /**
  64. * The current <code>Locale</code> to be used for localization, or
  65. * <code>null</code> if none has been set. By default it is
  66. * initialized to <code>null</code>.
  67. */
  68. protected Locale locale = null;
  69. /**
  70. * A <code>List</code> of currently registered
  71. * <code>IIOWriteWarningListener</code>s, initialized by default to
  72. * <code>null</code>, which is synonymous with an empty
  73. * <code>List</code>.
  74. */
  75. protected List warningListeners = null;
  76. /**
  77. * A <code>List</code> of <code>Locale</code>s, one for each
  78. * element of <code>warningListeners</code>, initialized by default
  79. * <code>null</code>, which is synonymous with an empty
  80. * <code>List</code>.
  81. */
  82. protected List warningLocales = null;
  83. /**
  84. * A <code>List</code> of currently registered
  85. * <code>IIOWriteProgressListener</code>s, initialized by default
  86. * <code>null</code>, which is synonymous with an empty
  87. * <code>List</code>.
  88. */
  89. protected List progressListeners = null;
  90. /**
  91. * If <code>true</code>, the current write operation should be
  92. * aborted.
  93. */
  94. private boolean abortFlag = false;
  95. /**
  96. * Constructs an <code>ImageWriter</code> and sets its
  97. * <code>originatingProvider</code> instance variable to the
  98. * supplied value.
  99. *
  100. * <p> Subclasses that make use of extensions should provide a
  101. * constructor with signature <code>(ImageWriterSpi,
  102. * Object)</code> in order to retrieve the extension object. If
  103. * the extension object is unsuitable, an
  104. * <code>IllegalArgumentException</code> should be thrown.
  105. *
  106. * @param originatingProvider the <code>ImageWriterSpi</code> that
  107. * is constructing this object, or <code>null</code>.
  108. */
  109. protected ImageWriter(ImageWriterSpi originatingProvider) {
  110. this.originatingProvider = originatingProvider;
  111. }
  112. /**
  113. * Returns the <code>ImageWriterSpi</code> object that created
  114. * this <code>ImageWriter</code>, or <code>null</code> if this
  115. * object was not created through the <code>IIORegistry</code>.
  116. *
  117. * <p> The default implementation returns the value of the
  118. * <code>originatingProvider</code> instance variable.
  119. *
  120. * @return an <code>ImageWriterSpi</code>, or <code>null</code>.
  121. *
  122. * @see ImageWriterSpi
  123. */
  124. public ImageWriterSpi getOriginatingProvider() {
  125. return originatingProvider;
  126. }
  127. /**
  128. * Sets the destination to the given
  129. * <code>ImageOutputStream</code> or other <code>Object</code>.
  130. * The destination is assumed to be ready to accept data, and will
  131. * not be closed at the end of each write. This allows distributed
  132. * imaging applications to transmit a series of images over a
  133. * single network connection. If <code>output</code> is
  134. * <code>null</code>, any currently set output will be removed.
  135. *
  136. * <p> If <code>output</code> is an
  137. * <code>ImageOutputStream</code>, calls to the
  138. * <code>write</code>, <code>writeToSequence</code>, and
  139. * <code>prepareWriteEmpty</code>/<code>endWriteEmpty</code>
  140. * methods will preserve the existing contents of the stream.
  141. * Other write methods, such as <code>writeInsert</code>,
  142. * <code>replaceStreamMetadata</code>,
  143. * <code>replaceImageMetadata</code>, <code>replacePixels</code>,
  144. * <code>prepareInsertEmpty</code>/<code>endInsertEmpty</code>,
  145. * and <code>endWriteSequence</code>, require the full contents
  146. * of the stream to be readable and writable, and may alter any
  147. * portion of the stream.
  148. *
  149. * <p> Use of a general <code>Object</code> other than an
  150. * <code>ImageOutputStream</code> is intended for writers that
  151. * interact directly with an output device or imaging protocol.
  152. * The set of legal classes is advertised by the writer's service
  153. * provider's <code>getOutputTypes</code> method; most writers
  154. * will return a single-element array containing only
  155. * <code>ImageOutputStream.class</code> to indicate that they
  156. * accept only an <code>ImageOutputStream</code>.
  157. *
  158. * <p> The default implementation sets the <code>output</code>
  159. * instance variable to the value of <code>output</code> after
  160. * checking <code>output</code> against the set of classes
  161. * advertised by the originating provider, if there is one.
  162. *
  163. * @param output the <code>ImageOutputStream</code> or other
  164. * <code>Object</code> to use for future writing.
  165. *
  166. * @exception IllegalArgumentException if <code>output</code> is
  167. * not an instance of one of the classes returned by the
  168. * originating service provider's <code>getOutputTypes</code>
  169. * method.
  170. *
  171. * @see #getOutput
  172. */
  173. public void setOutput(Object output) {
  174. if (output != null) {
  175. ImageWriterSpi provider = getOriginatingProvider();
  176. if (provider != null) {
  177. Class[] classes = provider.getOutputTypes();
  178. boolean found = false;
  179. for (int i = 0; i < classes.length; i++) {
  180. if (classes[i].isInstance(output)) {
  181. found = true;
  182. break;
  183. }
  184. }
  185. if (!found) {
  186. throw new IllegalArgumentException("Illegal output type!");
  187. }
  188. }
  189. }
  190. this.output = output;
  191. }
  192. /**
  193. * Returns the <code>ImageOutputStream</code> or other
  194. * <code>Object</code> set by the most recent call to the
  195. * <code>setOutput</code> method. If no destination has been
  196. * set, <code>null</code> is returned.
  197. *
  198. * <p> The default implementation returns the value of the
  199. * <code>output</code> instance variable.
  200. *
  201. * @return the <code>Object</code> that was specified using
  202. * <code>setOutput</code>, or <code>null</code>.
  203. *
  204. * @see #setOutput
  205. */
  206. public Object getOutput() {
  207. return output;
  208. }
  209. // Localization
  210. /**
  211. * Returns an array of <code>Locale</code>s that may be used to
  212. * localize warning listeners and compression settings. A return
  213. * value of <code>null</code> indicates that localization is not
  214. * supported.
  215. *
  216. * <p> The default implementation returns a clone of the
  217. * <code>availableLocales</code> instance variable if it is
  218. * non-<code>null</code>, or else returns <code>null</code>.
  219. *
  220. * @return an array of <code>Locale</code>s that may be used as
  221. * arguments to <code>setLocale</code>, or <code>null</code>.
  222. */
  223. public Locale[] getAvailableLocales() {
  224. return (availableLocales == null) ?
  225. null : (Locale[])availableLocales.clone();
  226. }
  227. /**
  228. * Sets the current <code>Locale</code> of this
  229. * <code>ImageWriter</code> to the given value. A value of
  230. * <code>null</code> removes any previous setting, and indicates
  231. * that the writer should localize as it sees fit.
  232. *
  233. * <p> The default implementation checks <code>locale</code>
  234. * against the values returned by
  235. * <code>getAvailableLocales</code>, and sets the
  236. * <code>locale</code> instance variable if it is found. If
  237. * <code>locale</code> is <code>null</code>, the instance variable
  238. * is set to <code>null</code> without any checking.
  239. *
  240. * @param locale the desired <code>Locale</code>, or
  241. * <code>null</code>.
  242. *
  243. * @exception IllegalArgumentException if <code>locale</code> is
  244. * non-<code>null</code> but is not one of the values returned by
  245. * <code>getAvailableLocales</code>.
  246. *
  247. * @see #getLocale
  248. */
  249. public void setLocale(Locale locale) {
  250. if (locale != null) {
  251. Locale[] locales = getAvailableLocales();
  252. boolean found = false;
  253. if (locales != null) {
  254. for (int i = 0; i < locales.length; i++) {
  255. if (locale.equals(locales[i])) {
  256. found = true;
  257. break;
  258. }
  259. }
  260. }
  261. if (!found) {
  262. throw new IllegalArgumentException("Invalid locale!");
  263. }
  264. }
  265. this.locale = locale;
  266. }
  267. /**
  268. * Returns the currently set <code>Locale</code>, or
  269. * <code>null</code> if none has been set.
  270. *
  271. * <p> The default implementation returns the value of the
  272. * <code>locale</code> instance variable.
  273. *
  274. * @return the current <code>Locale</code>, or <code>null</code>.
  275. *
  276. * @see #setLocale
  277. */
  278. public Locale getLocale() {
  279. return locale;
  280. }
  281. // Write params
  282. /**
  283. * Returns a new <code>ImageWriteParam</code> object of the
  284. * appropriate type for this file format containing default
  285. * values, that is, those values that would be used
  286. * if no <code>ImageWriteParam</code> object were specified. This
  287. * is useful as a starting point for tweaking just a few parameters
  288. * and otherwise leaving the default settings alone.
  289. *
  290. * <p> The default implementation constructs and returns a new
  291. * <code>ImageWriteParam</code> object that does not allow tiling,
  292. * progressive encoding, or compression, and that will be
  293. * localized for the current <code>Locale</code> (<i>i.e.</i>,
  294. * what you would get by calling <code>new
  295. * ImageWriteParam(getLocale())</code>.
  296. *
  297. * <p> Individual plug-ins may return an instance of
  298. * <code>ImageWriteParam</code> with additional optional features
  299. * enabled, or they may return an instance of a plug-in specific
  300. * subclass of <code>ImageWriteParam</code>.
  301. *
  302. * @return a new <code>ImageWriteParam</code> object containing
  303. * default values.
  304. */
  305. public ImageWriteParam getDefaultWriteParam() {
  306. return new ImageWriteParam(getLocale());
  307. }
  308. // Metadata
  309. /**
  310. * Returns an <code>IIOMetadata</code> object containing default
  311. * values for encoding a stream of images. The contents of the
  312. * object may be manipulated using either the XML tree structure
  313. * returned by the <code>IIOMetadata.getAsTree</code> method, an
  314. * <code>IIOMetadataController</code> object, or via plug-in
  315. * specific interfaces, and the resulting data supplied to one of
  316. * the <code>write</code> methods that take a stream metadata
  317. * parameter.
  318. *
  319. * <p> An optional <code>ImageWriteParam</code> may be supplied
  320. * for cases where it may affect the structure of the stream
  321. * metadata.
  322. *
  323. * <p> If the supplied <code>ImageWriteParam</code> contains
  324. * optional setting values not supported by this writer, they
  325. * will be ignored.
  326. *
  327. * <p> Writers that do not make use of stream metadata
  328. * (<i>e.g.</i>, writers for single-image formats) should return
  329. * <code>null</code>.
  330. *
  331. * @param param an <code>ImageWriteParam</code> that will be used to
  332. * encode the image, or <code>null</code>.
  333. *
  334. * @return an <code>IIOMetadata</code> object.
  335. */
  336. public abstract IIOMetadata
  337. getDefaultStreamMetadata(ImageWriteParam param);
  338. /**
  339. * Returns an <code>IIOMetadata</code> object containing default
  340. * values for encoding an image of the given type. The contents
  341. * of the object may be manipulated using either the XML tree
  342. * structure returned by the <code>IIOMetadata.getAsTree</code>
  343. * method, an <code>IIOMetadataController</code> object, or via
  344. * plug-in specific interfaces, and the resulting data supplied to
  345. * one of the <code>write</code> methods that take a stream
  346. * metadata parameter.
  347. *
  348. * <p> An optional <code>ImageWriteParam</code> may be supplied
  349. * for cases where it may affect the structure of the image
  350. * metadata.
  351. *
  352. * <p> If the supplied <code>ImageWriteParam</code> contains
  353. * optional setting values not supported by this writer, they
  354. * will be ignored.
  355. *
  356. * @param imageType an <code>ImageTypeSpecifier</code> indicating the
  357. * format of the image to be written later.
  358. * @param param an <code>ImageWriteParam</code> that will be used to
  359. * encode the image, or <code>null</code>.
  360. *
  361. * @return an <code>IIOMetadata</code> object.
  362. */
  363. public abstract IIOMetadata
  364. getDefaultImageMetadata(ImageTypeSpecifier imageType,
  365. ImageWriteParam param);
  366. // comment inherited
  367. public abstract IIOMetadata convertStreamMetadata(IIOMetadata inData,
  368. ImageWriteParam param);
  369. // comment inherited
  370. public abstract IIOMetadata
  371. convertImageMetadata(IIOMetadata inData,
  372. ImageTypeSpecifier imageType,
  373. ImageWriteParam param);
  374. // Thumbnails
  375. /**
  376. * Returns the number of thumbnails suported by the format being
  377. * written, given the image type and any additional write
  378. * parameters and metadata objects that will be used during
  379. * encoding. A return value of <code>-1</code> indicates that
  380. * insufficient information is available.
  381. *
  382. * <p> An <code>ImageWriteParam</code> may optionally be supplied
  383. * for cases where it may affect thumbnail handling.
  384. *
  385. * <p> If the supplied <code>ImageWriteParam</code> contains
  386. * optional setting values not supported by this writer, they
  387. * will be ignored.
  388. *
  389. * <p> The default implementation returns 0.
  390. *
  391. * @param imageType an <code>ImageTypeSpecifier</code> indicating
  392. * the type of image to be written, or <code>null</code>.
  393. * @param param the <code>ImageWriteParam</code> that will be used for
  394. * writing, or <code>null</code>.
  395. * @param streamMetadata an <code>IIOMetadata</code> object that will
  396. * be used for writing, or <code>null</code>.
  397. * @param imageMetadata an <code>IIOMetadata</code> object that will
  398. * be used for writing, or <code>null</code>.
  399. *
  400. * @return the number of thumbnails that may be written given the
  401. * supplied parameters, or <code>-1</code> if insufficient
  402. * information is available.
  403. */
  404. public int getNumThumbnailsSupported(ImageTypeSpecifier imageType,
  405. ImageWriteParam param,
  406. IIOMetadata streamMetadata,
  407. IIOMetadata imageMetadata) {
  408. return 0;
  409. }
  410. /**
  411. * Returns an array of <code>Dimension</code>s indicating the
  412. * legal size ranges for thumbnail images as they will be encoded
  413. * in the output file or stream. This information is merely
  414. * advisory; the writer will resize any supplied thumbnails as
  415. * necessary.
  416. *
  417. * <p> The information is returned as a set of pairs; the first
  418. * element of a pair contains an (inclusive) minimum width and
  419. * height, and the second element contains an (inclusive) maximum
  420. * width and height. Together, each pair defines a valid range of
  421. * sizes. To specify a fixed size, the same width and height will
  422. * appear for both elements. A return value of <code>null</code>
  423. * indicates that the size is arbitrary or unknown.
  424. *
  425. * <p> An <code>ImageWriteParam</code> may optionally be supplied
  426. * for cases where it may affect thumbnail handling.
  427. *
  428. * <p> If the supplied <code>ImageWriteParam</code> contains
  429. * optional setting values not supported by this writer, they
  430. * will be ignored.
  431. *
  432. * <p> The default implementation returns <code>null</code>.
  433. *
  434. * @param imageType an <code>ImageTypeSpecifier</code> indicating the
  435. * type of image to be written, or <code>null</code>.
  436. * @param param the <code>ImageWriteParam</code> that will be used for
  437. * writing, or <code>null</code>.
  438. * @param streamMetadata an <code>IIOMetadata</code> object that will
  439. * be used for writing, or <code>null</code>.
  440. * @param imageMetadata an <code>IIOMetadata</code> object that will
  441. * be used for writing, or <code>null</code>.
  442. *
  443. * @return an array of <code>Dimension</code>s with an even length
  444. * of at least two, or <code>null</code>.
  445. */
  446. public Dimension[] getPreferredThumbnailSizes(ImageTypeSpecifier imageType,
  447. ImageWriteParam param,
  448. IIOMetadata streamMetadata,
  449. IIOMetadata imageMetadata) {
  450. return null;
  451. }
  452. /**
  453. * Returns <code>true</code> if the methods that take an
  454. * <code>IIOImage</code> parameter are capable of dealing with a
  455. * <code>Raster</code> (as opposed to <code>RenderedImage</code>)
  456. * source image. If this method returns <code>false</code>, then
  457. * those methods will throw an
  458. * <code>UnsupportedOperationException</code> if supplied with an
  459. * <code>IIOImage</code> containing a <code>Raster</code>.
  460. *
  461. * <p> The default implementation returns <code>false</code>.
  462. *
  463. * @return <code>true</code> if <code>Raster</code> sources are
  464. * supported.
  465. */
  466. public boolean canWriteRasters() {
  467. return false;
  468. }
  469. /**
  470. * Appends a complete image stream containing a single image and
  471. * associated stream and image metadata and thumbnails to the
  472. * output. Any necessary header information is included. If the
  473. * output is an <code>ImageOutputStream</code>, its existing
  474. * contents prior to the current seek position are not affected,
  475. * and need not be readable or writable.
  476. *
  477. * <p> The output must have been set beforehand using the
  478. * <code>setOutput</code> method.
  479. *
  480. * <p> Stream metadata may optionally be supplied; if it is
  481. * <code>null</code>, default stream metadata will be used.
  482. *
  483. * <p> If <code>canWriteRasters</code> returns <code>true</code>,
  484. * the <code>IIOImage</code> may contain a <code>Raster</code>
  485. * source. Otherwise, it must contain a
  486. * <code>RenderedImage</code> source.
  487. *
  488. * <p> The supplied thumbnails will be resized if needed, and any
  489. * thumbnails in excess of the supported number will be ignored.
  490. * If the format requires additional thumbnails that are not
  491. * provided, the writer should generate them internally.
  492. *
  493. * <p> An <code>ImageWriteParam</code> may
  494. * optionally be supplied to control the writing process. If
  495. * <code>param</code> is <code>null</code>, a default write param
  496. * will be used.
  497. *
  498. * <p> If the supplied <code>ImageWriteParam</code> contains
  499. * optional setting values not supported by this writer, they
  500. * will be ignored.
  501. *
  502. * @param streamMetadata an <code>IIOMetadata</code> object representing
  503. * stream metadata, or <code>null</code> to use default values.
  504. * @param image an <code>IIOImage</code> object containing an
  505. * image, thumbnails, and metadata to be written.
  506. * @param param an <code>ImageWriteParam</code>, or
  507. * <code>null</code> to use a default
  508. * <code>ImageWriteParam</code>.
  509. *
  510. * @exception IllegalStateException if the output has not
  511. * been set.
  512. * @exception UnsupportedOperationException if <code>image</code>
  513. * contains a <code>Raster</code> and <code>canWriteRasters</code>
  514. * returns <code>false</code>.
  515. * @exception IllegalArgumentException if <code>image</code> is
  516. * <code>null</code>.
  517. * @exception IOException if an error occurs during writing.
  518. */
  519. public abstract void write(IIOMetadata streamMetadata,
  520. IIOImage image,
  521. ImageWriteParam param) throws IOException;
  522. /**
  523. * Appends a complete image stream containing a single image with
  524. * default metadata and thumbnails to the output. This method is
  525. * a shorthand for <code>write(null, image, null)</code>.
  526. *
  527. * @param image an <code>IIOImage</code> object containing an
  528. * image, thumbnails, and metadata to be written.
  529. *
  530. * @exception IllegalStateException if the output has not
  531. * been set.
  532. * @exception IllegalArgumentException if <code>image</code> is
  533. * <code>null</code>.
  534. * @exception UnsupportedOperationException if <code>image</code>
  535. * contains a <code>Raster</code> and <code>canWriteRasters</code>
  536. * returns <code>false</code>.
  537. * @exception IOException if an error occurs during writing.
  538. */
  539. public void write(IIOImage image) throws IOException {
  540. write(null, image, null);
  541. }
  542. /**
  543. * Appends a complete image stream consisting of a single image
  544. * with default metadata and thumbnails to the output. This
  545. * method is a shorthand for <code>write(null, new IIOImage(image,
  546. * null, null), null)</code>.
  547. *
  548. * @param image a <code>RenderedImage</code> to be written.
  549. *
  550. * @exception IllegalStateException if the output has not
  551. * been set.
  552. * @exception IllegalArgumentException if <code>image</code> is
  553. * <code>null</code>.
  554. * @exception IOException if an error occurs during writing.
  555. */
  556. public void write(RenderedImage image) throws IOException {
  557. write(null, new IIOImage(image, null, null), null);
  558. }
  559. // Check that the output has been set, then throw an
  560. // UnsupportedOperationException.
  561. private void unsupported() {
  562. if (getOutput() == null) {
  563. throw new IllegalStateException("getOutput() == null!");
  564. }
  565. throw new UnsupportedOperationException("Unsupported write variant!");
  566. }
  567. // Sequence writes
  568. /**
  569. * Returns <code>true</code> if the writer is able to append an
  570. * image to an image stream that already contains header
  571. * information and possibly prior images.
  572. *
  573. * <p> If <code>canWriteSequence</code> returns <code>false</code>,
  574. * <code>writeToSequence</code> and <code>endWriteSequence</code>
  575. * will throw an <code>UnsupportedOperationException</code>.
  576. *
  577. * <p> The default implementation returns <code>false</code>.
  578. *
  579. * @return <code>true</code> if images may be appended sequentially.
  580. */
  581. public boolean canWriteSequence() {
  582. return false;
  583. }
  584. /**
  585. * Prepares a stream to accept a series of subsequent
  586. * <code>writeToSequence</code> calls, using the provided stream
  587. * metadata object. The metadata will be written to the stream if
  588. * it should precede the image data. If the argument is <code>null</code>,
  589. * default stream metadata is used.
  590. *
  591. * <p> If the output is an <code>ImageOutputStream</code>, the existing
  592. * contents of the output prior to the current seek position are
  593. * flushed, and need not be readable or writable. If the format
  594. * requires that <code>endWriteSequence</code> be able to rewind to
  595. * patch up the header information, such as for a sequence of images
  596. * in a single TIFF file, then the metadata written by this method
  597. * must remain in a writable portion of the stream. Other formats
  598. * may flush the stream after this method and after each image.
  599. *
  600. * <p> If <code>canWriteSequence</code> returns <code>false</code>,
  601. * this method will throw an
  602. * <code>UnsupportedOperationException</code>.
  603. *
  604. * <p> The output must have been set beforehand using either
  605. * the <code>setOutput</code> method.
  606. *
  607. * <p> The default implementation throws an
  608. * <code>IllegalStateException</code> if the output is
  609. * <code>null</code>, and otherwise throws an
  610. * <code>UnsupportedOperationException</code>.
  611. *
  612. * @param streamMetadata A stream metadata object, or <code>null</code>.
  613. *
  614. * @exception IllegalStateException if the output has not
  615. * been set.
  616. * @exception UnsupportedOperationException if
  617. * <code>canWriteSequence</code> returns <code>false</code>.
  618. * @exception IOException if an error occurs writing the stream
  619. * metadata.
  620. */
  621. public void prepareWriteSequence(IIOMetadata streamMetadata)
  622. throws IOException {
  623. unsupported();
  624. }
  625. /**
  626. * Appends a single image and possibly associated metadata and
  627. * thumbnails, to the output. If the output is an
  628. * <code>ImageOutputStream</code>, the existing contents of the
  629. * output prior to the current seek position may be flushed, and
  630. * need not be readable or writable, unless the plug-in needs to
  631. * be able to patch up the header information when
  632. * <code>endWriteSequence</code> is called (<italic>e.g.</italic> TIFF).
  633. *
  634. * <p> If <code>canWriteSequence</code> returns <code>false</code>,
  635. * this method will throw an
  636. * <code>UnsupportedOperationException</code>.
  637. *
  638. * <p> The output must have been set beforehand using
  639. * the <code>setOutput</code> method.
  640. *
  641. * <p> <code>prepareWriteSequence</code> must have been called
  642. * beforehand, or an <code>IllegalStateException</code> is thrown.
  643. *
  644. * <p> If <code>canWriteRasters</code> returns <code>true</code>,
  645. * the <code>IIOImage</code> may contain a <code>Raster</code>
  646. * source. Otherwise, it must contain a
  647. * <code>RenderedImage</code> source.
  648. *
  649. * <p> The supplied thumbnails will be resized if needed, and any
  650. * thumbnails in excess of the supported number will be ignored.
  651. * If the format requires additional thumbnails that are not
  652. * provided, the writer will generate them internally.
  653. *
  654. * <p> An <code>ImageWriteParam</code> may optionally be supplied
  655. * to control the writing process. If <code>param</code> is
  656. * <code>null</code>, a default write param will be used.
  657. *
  658. * <p> If the supplied <code>ImageWriteParam</code> contains
  659. * optional setting values not supported by this writer, they
  660. * will be ignored.
  661. *
  662. * <p> The default implementation throws an
  663. * <code>IllegalStateException</code> if the output is
  664. * <code>null</code>, and otherwise throws an
  665. * <code>UnsupportedOperationException</code>.
  666. *
  667. * @param image an <code>IIOImage</code> object containing an
  668. * image, thumbnails, and metadata to be written.
  669. * @param param an <code>ImageWriteParam</code>, or
  670. * <code>null</code> to use a default
  671. * <code>ImageWriteParam</code>.
  672. *
  673. * @exception IllegalStateException if the output has not
  674. * been set, or <code>prepareWriteSequence</code> has not been called.
  675. * @exception UnsupportedOperationException if
  676. * <code>canWriteSequence</code> returns <code>false</code>.
  677. * @exception IllegalArgumentException if <code>image</code> is
  678. * <code>null</code>.
  679. * @exception UnsupportedOperationException if <code>image</code>
  680. * contains a <code>Raster</code> and <code>canWriteRasters</code>
  681. * returns <code>false</code>.
  682. * @exception IOException if an error occurs during writing.
  683. */
  684. public void writeToSequence(IIOImage image, ImageWriteParam param)
  685. throws IOException {
  686. unsupported();
  687. }
  688. /**
  689. * Completes the writing of a sequence of images begun with
  690. * <code>prepareWriteSequence</code>. Any stream metadata that
  691. * should come at the end of the sequence of images is written out,
  692. * and any header information at the beginning of the sequence is
  693. * patched up if necessary. If the output is an
  694. * <code>ImageOutputStream</code>, data through the stream metadata
  695. * at the end of the sequence are flushed and need not be readable
  696. * or writable.
  697. *
  698. * <p> If <code>canWriteSequence</code> returns <code>false</code>,
  699. * this method will throw an
  700. * <code>UnsupportedOperationException</code>.
  701. *
  702. * <p> The default implementation throws an
  703. * <code>IllegalStateException</code> if the output is
  704. * <code>null</code>, and otherwise throws an
  705. * <code>UnsupportedOperationException</code>.
  706. *
  707. * @exception IllegalStateException if the output has not
  708. * been set, or <code>prepareWriteSequence</code> has not been called.
  709. * @exception UnsupportedOperationException if
  710. * <code>canWriteSequence</code> returns <code>false</code>.
  711. * @exception IOException if an error occurs during writing.
  712. */
  713. public void endWriteSequence() throws IOException {
  714. unsupported();
  715. }
  716. // Metadata replacement
  717. /**
  718. * Returns <code>true</code> if it is possible to replace the
  719. * stream metadata already present in the output.
  720. *
  721. * <p> The default implementation throws an
  722. * <code>IllegalStateException</code> if the output is
  723. * <code>null</code>, and otherwise returns <code>false</code>.
  724. *
  725. * @return <code>true</code> if replacement of stream metadata is
  726. * allowed.
  727. *
  728. * @exception IllegalStateException if the output has not
  729. * been set.
  730. * @exception IOException if an I/O error occurs during the query.
  731. */
  732. public boolean canReplaceStreamMetadata() throws IOException {
  733. if (getOutput() == null) {
  734. throw new IllegalStateException("getOutput() == null!");
  735. }
  736. return false;
  737. }
  738. /**
  739. * Replaces the stream metadata in the output with new
  740. * information. If the output is an
  741. * <code>ImageOutputStream</code>, the prior contents of the
  742. * stream are examined and possibly edited to make room for the
  743. * new data. All of the prior contents of the output must be
  744. * available for reading and writing.
  745. *
  746. * <p> If <code>canReplaceStreamMetadata</code> returns
  747. * <code>false</code>, an
  748. * <code>UnsupportedOperationException</code> will be thrown.
  749. *
  750. * <p> The default implementation throws an
  751. * <code>IllegalStateException</code> if the output is
  752. * <code>null</code>, and otherwise throws an
  753. * <code>UnsupportedOperationException</code>.
  754. *
  755. * @param streamMetadata an <code>IIOMetadata</code> object representing
  756. * stream metadata, or <code>null</code> to use default values.
  757. *
  758. * @exception IllegalStateException if the output has not
  759. * been set.
  760. * @exception UnsupportedOperationException if the
  761. * <code>canReplaceStreamMetadata</code> returns
  762. * <code>false</code>. modes do not include
  763. * @exception IOException if an error occurs during writing.
  764. */
  765. public void replaceStreamMetadata(IIOMetadata streamMetadata)
  766. throws IOException {
  767. unsupported();
  768. }
  769. /**
  770. * Returns <code>true</code> if it is possible to replace the
  771. * image metadata associated with an existing image with index
  772. * <code>imageIndex</code>. If this method returns
  773. * <code>false</code>, a call to
  774. * <code>replaceImageMetadata(imageIndex)</code> will throw an
  775. * <code>UnsupportedOperationException</code>.
  776. *
  777. * <p> A writer that does not support any image metadata
  778. * replacement may return <code>false</code> without performing
  779. * bounds checking on the index.
  780. *
  781. * <p> The default implementation throws an
  782. * <code>IllegalStateException</code> if the output is
  783. * <code>null</code>, and otherwise returns <code>false</code>
  784. * without checking the value of <code>imageIndex</code>.
  785. *
  786. * @param imageIndex the index of the image whose metadata is to
  787. * be replaced.
  788. *
  789. * @return <code>true</code> if the image metadata of the given
  790. * image can be replaced.
  791. *
  792. * @exception IllegalStateException if the output has not
  793. * been set.
  794. * @exception IndexOutOfBoundsException if the writer supports
  795. * image metadata replacement in general, but
  796. * <code>imageIndex</code> is less than 0 or greater than the
  797. * largest available index.
  798. * @exception IOException if an I/O error occurs during the query.
  799. */
  800. public boolean canReplaceImageMetadata(int imageIndex)
  801. throws IOException {
  802. if (getOutput() == null) {
  803. throw new IllegalStateException("getOutput() == null!");
  804. }
  805. return false;
  806. }
  807. /**
  808. * Replaces the image metadata associated with an existing image.
  809. *
  810. * <p> If <code>canReplaceImageMetadata(imageIndex)</code> returns
  811. * <code>false</code>, an
  812. * <code>UnsupportedOperationException</code> will be thrown.
  813. *
  814. * <p> The default implementation throws an
  815. * <code>IllegalStateException</code> if the output is
  816. * <code>null</code>, and otherwise throws an
  817. * <code>UnsupportedOperationException</code>.
  818. *
  819. * @param imageIndex the index of the image whose metadata is to
  820. * be replaced.
  821. * @param imageMetadata an <code>IIOMetadata</code> object
  822. * representing image metadata, or <code>null</code>.
  823. *
  824. * @exception IllegalStateException if the output has not been
  825. * set.
  826. * @exception UnsupportedOperationException if
  827. * <code>canReplaceImageMetadata</code> returns
  828. * <code>false</code>.
  829. * @exception IndexOutOfBoundsException if <code>imageIndex</code>
  830. * is less than 0 or greater than the largest available index.
  831. * @exception IOException if an error occurs during writing.
  832. */
  833. public void replaceImageMetadata(int imageIndex,
  834. IIOMetadata imageMetadata)
  835. throws IOException {
  836. unsupported();
  837. }
  838. // Image insertion
  839. /**
  840. * Returns <code>true</code> if the writer supports the insertion
  841. * of a new image at the given index. Existing images with
  842. * indices greater than or equal to the insertion index will have
  843. * their indices increased by 1. A value for
  844. * <code>imageIndex</code> of <code>-1</code> may be used to
  845. * signify an index one larger than the current largest index.
  846. *
  847. * <p> A writer that does not support any image insertion may
  848. * return <code>false</code> without performing bounds checking on
  849. * the index.
  850. *
  851. * <p> The default implementation throws an
  852. * <code>IllegalStateException</code> if the output is
  853. * <code>null</code>, and otherwise returns <code>false</code>
  854. * withour checking the value of <code>imageIndex</code>.
  855. *
  856. * @param imageIndex the index at which the image is to be
  857. * inserted.
  858. *
  859. * @return <code>true</code> if an image may be inserted at the
  860. * given index.
  861. *
  862. * @exception IllegalStateException if the output has not
  863. * been set.
  864. * @exception IndexOutOfBoundsException if the writer supports
  865. * image insertion in general, but <code>imageIndex</code> is less
  866. * than -1 or greater than the largest available index.
  867. * @exception IOException if an I/O error occurs during the query.
  868. */
  869. public boolean canInsertImage(int imageIndex) throws IOException {
  870. if (getOutput() == null) {
  871. throw new IllegalStateException("getOutput() == null!");
  872. }
  873. return false;
  874. }
  875. /**
  876. * Inserts a new image into an existing image stream. Existing
  877. * images with an index greater than <code>imageIndex</code> are
  878. * preserved, and their indices are each increased by 1. A value
  879. * for <code>imageIndex</code> of -1 may be used to signify an
  880. * index one larger than the previous largest index; that is, it
  881. * will cause the image to be logically appended to the end of the
  882. * sequence. If the output is an <code>ImageOutputStream</code>,
  883. * the entirety of the stream must be both readable and writeable.
  884. *
  885. * <p> If <code>canInsertImage(imageIndex)</code> returns
  886. * <code>false</code>, an
  887. * <code>UnsupportedOperationException</code> will be thrown.
  888. *
  889. * <p> An <code>ImageWriteParam</code> may optionally be supplied
  890. * to control the writing process. If <code>param</code> is
  891. * <code>null</code>, a default write param will be used.
  892. *
  893. * <p> If the supplied <code>ImageWriteParam</code> contains
  894. * optional setting values not supported by this writer, they
  895. * will be ignored.
  896. *
  897. * <p> The default implementation throws an
  898. * <code>IllegalStateException</code> if the output is
  899. * <code>null</code>, and otherwise throws an
  900. * <code>UnsupportedOperationException</code>.
  901. *
  902. * @param imageIndex the index at which to write the image.
  903. * @param image an <code>IIOImage</code> object containing an
  904. * image, thumbnails, and metadata to be written.
  905. * @param param an <code>ImageWriteParam</code>, or
  906. * <code>null</code> to use a default
  907. * <code>ImageWriteParam</code>.
  908. *
  909. * @exception IllegalStateException if the output has not
  910. * been set.
  911. * @exception UnsupportedOperationException if
  912. * <code>canInsertImage(imageIndex)</code> returns <code>false</code>.
  913. * @exception IllegalArgumentException if <code>image</code> is
  914. * <code>null</code>.
  915. * @exception IndexOutOfBoundsException if <code>imageIndex</code>
  916. * is less than -1 or greater than the largest available index.
  917. * @exception UnsupportedOperationException if <code>image</code>
  918. * contains a <code>Raster</code> and <code>canWriteRasters</code>
  919. * returns <code>false</code>.
  920. * @exception IOException if an error occurs during writing.
  921. */
  922. public void writeInsert(int imageIndex,
  923. IIOImage image,
  924. ImageWriteParam param) throws IOException {
  925. unsupported();
  926. }
  927. // Image removal
  928. /**
  929. * Returns <code>true</code> if the writer supports the removal
  930. * of an existing image at the given index. Existing images with
  931. * indices greater than the insertion index will have
  932. * their indices decreased by 1.
  933. *
  934. * <p> A writer that does not support any image removal may
  935. * return <code>false</code> without performing bounds checking on
  936. * the index.
  937. *
  938. * <p> The default implementation throws an
  939. * <code>IllegalStateException</code> if the output is
  940. * <code>null</code>, and otherwise returns <code>false</code>
  941. * without checking the value of <code>imageIndex</code>.
  942. *
  943. * @param imageIndex the index of the image to be removed.
  944. *
  945. * @return <code>true</code> if it is possible to remove the given
  946. * image.
  947. *
  948. * @exception IllegalStateException if the output has not
  949. * been set.
  950. * @exception IndexOutOfBoundsException if the writer supports
  951. * image removal in general, but <code>imageIndex</code> is less
  952. * than 0 or greater than the largest available index.
  953. * @exception IOException if an I/O error occurs during the
  954. * query.
  955. */
  956. public boolean canRemoveImage(int imageIndex) throws IOException {
  957. if (getOutput() == null) {
  958. throw new IllegalStateException("getOutput() == null!");
  959. }
  960. return false;
  961. }
  962. /**
  963. * Removes an image from the stream.
  964. *
  965. * <p> If <code>canRemoveImage(imageIndex)</code> returns false,
  966. * an <code>UnsupportedOperationException</code>will be thrown.
  967. *
  968. * <p> The removal may or may not cause a reduction in the actual
  969. * file size.
  970. *
  971. * <p> The default implementation throws an
  972. * <code>IllegalStateException</code> if the output is
  973. * <code>null</code>, and otherwise throws an
  974. * <code>UnsupportedOperationException</code>.
  975. *
  976. * @param imageIndex the index of the image to be removed.
  977. *
  978. * @exception IllegalStateException if the output has not
  979. * been set.
  980. * @exception UnsupportedOperationException if
  981. * <code>canRemoveImage(imageIndex)</code> returns <code>false</code>.
  982. * @exception IndexOutOfBoundsException if <code>imageIndex</code>
  983. * is less than 0 or greater than the largest available index.
  984. * @exception IOException if an I/O error occurs during the
  985. * removal.
  986. */
  987. public void removeImage(int imageIndex) throws IOException {
  988. unsupported();
  989. }
  990. // Empty images
  991. /**
  992. * Returns <code>true</code> if the writer supports the writing of
  993. * a complete image stream consisting of a single image with
  994. * undefined pixel values and associated metadata and thumbnails
  995. * to the output. The pixel values may be defined by future
  996. * calls to the <code>replacePixels</code> methods. If the output
  997. * is an <code>ImageOutputStream</code>, its existing contents
  998. * prior to the current seek position are not affected, and need
  999. * not be readable or writable.
  1000. *
  1001. * <p> The default implementation throws an
  1002. * <code>IllegalStateException</code> if the output is
  1003. * <code>null</code>, and otherwise returns <code>false</code>.
  1004. *
  1005. * @return <code>true</code> if the writing of complete image
  1006. * stream with contents to be defined later is supported.
  1007. *
  1008. * @exception IllegalStateException if the output has not been
  1009. * set.
  1010. * @exception IOException if an I/O error occurs during the
  1011. * query.
  1012. */
  1013. public boolean canWriteEmpty() throws IOException {
  1014. if (getOutput() == null) {
  1015. throw new IllegalStateException("getOutput() == null!");
  1016. }
  1017. return false;
  1018. }
  1019. /**
  1020. * Begins the writing of a complete image stream, consisting of a
  1021. * single image with undefined pixel values and associated
  1022. * metadata and thumbnails, to the output. The pixel values will
  1023. * be defined by future calls to the <code>replacePixels</code>
  1024. * methods. If the output is an <code>ImageOutputStream</code>,
  1025. * its existing contents prior to the current seek position are
  1026. * not affected, and need not be readable or writable.
  1027. *
  1028. * <p> The writing is not complete until a call to
  1029. * <code>endWriteEmpty</code> occurs. Calls to
  1030. * <code>prepareReplacePixels</code>, <code>replacePixels</code>,
  1031. * and <code>endReplacePixels</code> may occur between calls to
  1032. * <code>prepareWriteEmpty</code> and <code>endWriteEmpty</code>.
  1033. * However, calls to <code>prepareWriteEmpty</code> cannot be
  1034. * nested, and calls to <code>prepareWriteEmpty</code> and
  1035. * <code>prepareInsertEmpty</code> may not be interspersed.
  1036. *
  1037. * <p> If <code>canWriteEmpty</code> returns <code>false</code>,
  1038. * an <code>UnsupportedOperationException</code> will be thrown.
  1039. *
  1040. * <p> An <code>ImageWriteParam</code> may optionally be supplied
  1041. * to control the writing process. If <code>param</code> is
  1042. * <code>null</code>, a default write param will be used.
  1043. *
  1044. * <p> If the supplied <code>ImageWriteParam</code> contains
  1045. * optional setting values not supported by this writer, they
  1046. * will be ignored.
  1047. *
  1048. * <p> The default implementation throws an
  1049. * <code>IllegalStateException</code> if the output is
  1050. * <code>null</code>, and otherwise throws an
  1051. * <code>UnsupportedOperationException</code>.
  1052. *
  1053. * @param streamMetadata an <code>IIOMetadata</code> object representing
  1054. * stream metadata, or <code>null</code> to use default values.
  1055. * @param imageType an <code>ImageTypeSpecifier</code> describing
  1056. * the layout of the image.
  1057. * @param width the width of the image.
  1058. * @param height the height of the image.
  1059. * @param imageMetadata an <code>IIOMetadata</code> object
  1060. * representing image metadata, or <code>null</code>.
  1061. * @param thumbnails a <code>List</code> of
  1062. * <code>BufferedImage</code> thumbnails for this image, or
  1063. * <code>null</code>.
  1064. * @param param an <code>ImageWriteParam</code>, or
  1065. * <code>null</code> to use a default
  1066. * <code>ImageWriteParam</code>.
  1067. *
  1068. * @exception IllegalStateException if the output has not
  1069. * been set.
  1070. * @exception UnsupportedOperationException if
  1071. * <code>canWriteEmpty</code> returns <code>false</code>.
  1072. * @exception IllegalStateException if a previous call to
  1073. * <code>prepareWriteEmpty</code> has been made without a
  1074. * corresponding call to <code>endWriteEmpty</code>.
  1075. * @exception IllegalStateException if a previous call to
  1076. * <code>prepareInsertEmpty</code> has been made without a
  1077. * corresponding call to <code>endInsertEmpty</code>.
  1078. * @exception IllegalArgumentException if <code>imageType</code>
  1079. * is <code>null</code> or <code>thumbnails</code> contains
  1080. * <code>null</code> references or objects other than
  1081. * <code>BufferedImage</code>s.
  1082. * @exception IllegalArgumentException if width or height are less
  1083. * than 1.
  1084. * @exception IOException if an I/O error occurs during writing.
  1085. */
  1086. public void prepareWriteEmpty(IIOMetadata streamMetadata,
  1087. ImageTypeSpecifier imageType,
  1088. int width, int height,
  1089. IIOMetadata imageMetadata,
  1090. List thumbnails,
  1091. ImageWriteParam param) throws IOException {
  1092. unsupported();
  1093. }
  1094. /**
  1095. * Completes the writing of a new image that was begun with a
  1096. * prior call to <code>prepareWriteEmpty</code>.
  1097. *
  1098. * <p> If <code>canWriteEmpty()</code> returns <code>false</code>,
  1099. * an <code>UnsupportedOperationException</code> will be thrown.
  1100. *
  1101. * <p> The default implementation throws an
  1102. * <code>IllegalStateException</code> if the output is
  1103. * <code>null</code>, and otherwise throws an
  1104. * <code>UnsupportedOperationException</code>.
  1105. *
  1106. * @exception IllegalStateException if the output has not
  1107. * been set.
  1108. * @exception UnsupportedOperationException if
  1109. * <code>canWriteEmpty(imageIndex)</code> returns
  1110. * <code>false</code>.
  1111. * @exception IllegalStateException if a previous call to
  1112. * <code>prepareWriteEmpty</code> without a corresponding call to
  1113. * <code>endWriteEmpty</code> has not been made.
  1114. * @exception IllegalStateException if a previous call to
  1115. * <code>prepareInsertEmpty</code> without a corresponding call to
  1116. * <code>endInsertEmpty</code> has been made.
  1117. * @exception IllegalStateException if a call to
  1118. * <code>prepareReiplacePixels</code> has been made without a
  1119. * matching call to <code>endReplacePixels</code>.
  1120. * @exception IOException if an I/O error occurs during writing.
  1121. */
  1122. public void endWriteEmpty() throws IOException {
  1123. if (getOutput() == null) {
  1124. throw new IllegalStateException("getOutput() == null!");
  1125. }
  1126. throw new IllegalStateException("No call to prepareWriteEmpty!");
  1127. }
  1128. /**
  1129. * Returns <code>true</code> if the writer supports the insertion
  1130. * of a new, empty image at the given index. The pixel values of
  1131. * the image are undefined, and may be specified in pieces using
  1132. * the <code>replacePixels</code> methods. Existing images with
  1133. * indices greater than or equal to the insertion index will have
  1134. * their indices increased by 1. A value for
  1135. * <code>imageIndex</code> of <code>-1</code> may be used to
  1136. * signify an index one larger than the current largest index.
  1137. *
  1138. * <p> A writer that does not support insertion of empty images
  1139. * may return <code>false</code> without performing bounds
  1140. * checking on the index.
  1141. *
  1142. * <p> The default implementation throws an
  1143. * <code>IllegalStateException</code> if the output is
  1144. * <code>null</code>, and otherwise returns <code>false</code>
  1145. * without checking the value of <code>imageIndex</code>.
  1146. *
  1147. * @param imageIndex the index at which the image is to be
  1148. * inserted.
  1149. *
  1150. * @return <code>true</code> if an empty image may be inserted at
  1151. * the given index.
  1152. *
  1153. * @exception IllegalStateException if the output has not been
  1154. * set.
  1155. * @exception IndexOutOfBoundsException if the writer supports
  1156. * empty image insertion in general, but <code>imageIndex</code>
  1157. * is less than -1 or greater than the largest available index.
  1158. * @exception IOException if an I/O error occurs during the
  1159. * query.
  1160. */
  1161. public boolean canInsertEmpty(int imageIndex) throws IOException {
  1162. if (getOutput() == null) {
  1163. throw new IllegalStateException("getOutput() == null!");
  1164. }
  1165. return false;
  1166. }
  1167. /**
  1168. * Begins the insertion of a new image with undefined pixel values
  1169. * into an existing image stream. Existing images with an index
  1170. * greater than <code>imageIndex</code> are preserved, and their
  1171. * indices are each increased by 1. A value for
  1172. * <code>imageIndex</code> of -1 may be used to signify an index
  1173. * one larger than the previous largest index; that is, it will
  1174. * cause the image to be logically appended to the end of the
  1175. * sequence. If the output is an <code>ImageOutputStream</code>,
  1176. * the entirety of the stream must be both readable and writeable.
  1177. *
  1178. * <p> The image contents may be
  1179. * supplied later using the <code>replacePixels</code> method.
  1180. * The insertion is not complete until a call to
  1181. * <code>endInsertEmpty</code> occurs. Calls to
  1182. * <code>prepareReplacePixels</code>, <code>replacePixels</code>,
  1183. * and <code>endReplacePixels</code> may occur between calls to
  1184. * <code>prepareInsertEmpty</code> and
  1185. * <code>endInsertEmpty</code>. However, calls to
  1186. * <code>prepareInsertEmpty</code> cannot be nested, and calls to
  1187. * <code>prepareWriteEmpty</code> and
  1188. * <code>prepareInsertEmpty</code> may not be interspersed.
  1189. *
  1190. * <p> If <code>canInsertEmpty(imageIndex)</code> returns
  1191. * <code>false</code>, an
  1192. * <code>UnsupportedOperationException</code> will be thrown.
  1193. *
  1194. * <p> An <code>ImageWriteParam</code> may optionally be supplied
  1195. * to control the writing process. If <code>param</code> is
  1196. * <code>null</code>, a default write param will be used.
  1197. *
  1198. * <p> If the supplied <code>ImageWriteParam</code> contains
  1199. * optional setting values not supported by this writer, they
  1200. * will be ignored.
  1201. *
  1202. * <p> The default implementation throws an
  1203. * <code>IllegalStateException</code> if the output is
  1204. * <code>null</code>, and otherwise throws an
  1205. * <code>UnsupportedOperationException</code>.
  1206. *
  1207. * @param imageIndex the index at which to write the image.
  1208. * @param imageType an <code>ImageTypeSpecifier</code> describing
  1209. * the layout of the image.
  1210. * @param width the width of the image.
  1211. * @param height the height of the image.
  1212. * @param imageMetadata an <code>IIOMetadata</code> object
  1213. * representing image metadata, or <code>null</code>.
  1214. * @param thumbnails a <code>List</code> of
  1215. * <code>BufferedImage</code> thumbnails for this image, or
  1216. * <code>null</code>.
  1217. * @param param an <code>ImageWriteParam</code>, or
  1218. * <code>null</code> to use a default
  1219. * <code>ImageWriteParam</code>.
  1220. *
  1221. * @exception IllegalStateException if the output has not
  1222. * been set.
  1223. * @exception UnsupportedOperationException if
  1224. * <code>canInsertEmpty(imageIndex)</code> returns
  1225. * <code>false</code>.
  1226. * @exception IndexOutOfBoundsException if <code>imageIndex</code>
  1227. * is less than -1 or greater than the largest available index.
  1228. * @exception IllegalStateException if a previous call to
  1229. * <code>prepareInsertEmpty</code> has been made without a
  1230. * corresponding call to <code>endInsertEmpty</code>.
  1231. * @exception IllegalStateException if a previous call to
  1232. * <code>prepareWriteEmpty</code> has been made without a
  1233. * corresponding call to <code>endWriteEmpty</code>.
  1234. * @exception IllegalArgumentException if <code>imageType</code>
  1235. * is <code>null</code> or <code>thumbnails</code> contains
  1236. * <code>null</code> references or objects other than
  1237. * <code>BufferedImage</code>s.
  1238. * @exception IllegalArgumentException if width or height are less
  1239. * than 1.
  1240. * @exception IOException if an I/O error occurs during writing.
  1241. */
  1242. public void prepareInsertEmpty(int imageIndex,
  1243. ImageTypeSpecifier imageType,
  1244. int width, int height,
  1245. IIOMetadata imageMetadata,
  1246. List thumbnails,
  1247. ImageWriteParam param) throws IOException {
  1248. unsupported();
  1249. }
  1250. /**
  1251. * Completes the insertion of a new image that was begun with a
  1252. * prior call to <code>prepareInsertEmpty</code>.
  1253. *
  1254. * <p> The default implementation throws an
  1255. * <code>IllegalStateException</code> if the output is
  1256. * <code>null</code>, and otherwise throws an
  1257. * <code>UnsupportedOperationException</code>.
  1258. *
  1259. * @exception IllegalStateException if the output has not
  1260. * been set.
  1261. * @exception UnsupportedOperationException if
  1262. * <code>canInsertEmpty(imageIndex)</code> returns
  1263. * <code>false</code>.
  1264. * @exception IllegalStateException if a previous call to
  1265. * <code>prepareInsertEmpty</code> without a corresponding call to
  1266. * <code>endInsertEmpty</code> has not been made.
  1267. * @exception IllegalStateException if a previous call to
  1268. * <code>prepareWriteEmpty</code> without a corresponding call to
  1269. * <code>endWriteEmpty</code> has been made.
  1270. * @exception IllegalStateException if a call to
  1271. * <code>prepareReplacePixels</code> has been made without a
  1272. * matching call to <code>endReplacePixels</code>.
  1273. * @exception IOException if an I/O error occurs during writing.
  1274. */
  1275. public void endInsertEmpty() throws IOException {
  1276. unsupported();
  1277. }
  1278. // Pixel replacement
  1279. /**
  1280. * Returns <code>true</code> if the writer allows pixels of the
  1281. * given image to be replaced using the <code>replacePixels</code>
  1282. * methods.
  1283. *
  1284. * <p> A writer that does not support any pixel replacement may
  1285. * return <code>false</code> without performing bounds checking on
  1286. * the index.
  1287. *
  1288. * <p> The default implementation throws an
  1289. * <code>IllegalStateException</code> if the output is
  1290. * <code>null</code>, and otherwise returns <code>false</code>
  1291. * without checking the value of <code>imageIndex</code>.
  1292. *
  1293. * @param imageIndex the index of the image whose pixels are to be
  1294. * replaced.
  1295. *
  1296. * @return <code>true</code> if the pixels of the given
  1297. * image can be replaced.
  1298. *
  1299. * @exception IllegalStateException if the output has not been
  1300. * set.
  1301. * @exception IndexOutOfBoundsException if the writer supports
  1302. * pixel replacement in general, but <code>imageIndex</code> is
  1303. * less than 0 or greater than the largest available index.
  1304. * @exception IOException if an I/O error occurs during the query.
  1305. */
  1306. public boolean canReplacePixels(int imageIndex) throws IOException {
  1307. if (getOutput() == null) {
  1308. throw new IllegalStateException("getOutput() == null!");
  1309. }
  1310. return false;
  1311. }
  1312. /**
  1313. * Prepares the writer to handle a series of calls to the
  1314. * <code>replacePixels</code> methods. The affected pixel area
  1315. * will be clipped against the supplied
  1316. *
  1317. * <p> If <code>canReplacePixels</code> returns
  1318. * <code>false</code>, and
  1319. * <code>UnsupportedOperationException</code> will be thrown.
  1320. *
  1321. * <p> The default implementation throws an
  1322. * <code>IllegalStateException</code> if the output is
  1323. * <code>null</code>, and otherwise throws an
  1324. * <code>UnsupportedOperationException</code>.
  1325. *
  1326. * @param imageIndex the index of the image whose pixels are to be
  1327. * replaced.
  1328. * @param region a <code>Rectangle</code> that will be used to clip
  1329. * future pixel regions.
  1330. *
  1331. * @exception IllegalStateException if the output has not
  1332. * been set.
  1333. * @exception UnsupportedOperationException if
  1334. * <code>canReplacePixels(imageIndex)</code> returns
  1335. * <code>false</code>.
  1336. * @exception IndexOutOfBoundsException if <code>imageIndex</code>
  1337. * is less than 0 or greater than the largest available index.
  1338. * @exception IllegalStateException if there is a previous call to
  1339. * <code>prepareReplacePixels</code> without a matching call to
  1340. * <code>endReplacePixels</code> (<i>i.e.</i>, nesting is not
  1341. * allowed).
  1342. * @exception IllegalArgumentException if <code>region</code> is
  1343. * <code>null</code> or has a width or height less than 1.
  1344. * @exception IOException if an I/O error occurs during the
  1345. * preparation.
  1346. */
  1347. public void prepareReplacePixels(int imageIndex,
  1348. Rectangle region) throws IOException {
  1349. unsupported();
  1350. }
  1351. /**
  1352. * Replaces a portion of an image already present in the output
  1353. * with a portion of the given image. The image data must match,
  1354. * or be convertible to, the image layout of the existing image.
  1355. *
  1356. * <p> The destination region is specified in the
  1357. * <code>param</code> argument, and will be clipped to the image
  1358. * boundaries and the region supplied to
  1359. * <code>prepareReplacePixels</code>. At least one pixel of the
  1360. * source must not be clipped, or an exception is thrown.
  1361. *
  1362. * <p> An <code>ImageWriteParam</code> may optionally be supplied
  1363. * to control the writing process. If <code>param</code> is
  1364. * <code>null</code>, a default write param will be used.
  1365. *
  1366. * <p> If the supplied <code>ImageWriteParam</code> contains
  1367. * optional setting values not supported by this writer, they
  1368. * will be ignored.
  1369. *
  1370. * <p> This method may only be called after a call to
  1371. * <code>prepareReplacePixels</code>, or else an
  1372. * <code>IllegalStateException</code> will be thrown.
  1373. *
  1374. * <p> The default implementation throws an
  1375. * <code>IllegalStateException</code> if the output is
  1376. * <code>null</code>, and otherwise throws an
  1377. * <code>UnsupportedOperationException</code>.
  1378. *
  1379. * @param image a <code>RenderedImage</code> containing source
  1380. * pixels.
  1381. * @param param an <code>ImageWriteParam</code>, or
  1382. * <code>null</code> to use a default
  1383. * <code>ImageWriteParam</code>.
  1384. *
  1385. * @exception IllegalStateException if the output has not
  1386. * been set.
  1387. * @exception UnsupportedOperationException if
  1388. * <code>canReplacePixels(imageIndex)</code> returns
  1389. * <code>false</code>.
  1390. * @exception IllegalStateException if there is no previous call to
  1391. * <code>prepareReplacePixels</code> without a matching call to
  1392. * <code>endReplacePixels</code>.
  1393. * @exception IllegalArgumentException if any of the following are true:
  1394. * <li> <code>image</code> is <code>null</code>.
  1395. * <li> <code>param</code> is <code>null</code>.
  1396. * <li> the intersected region does not contain at least one pixel.
  1397. * <li> the layout of <code>image</code> does not match, or this
  1398. * writer cannot convert it to, the existing image layout.
  1399. * </ul>
  1400. * @exception IOException if an I/O error occurs during writing.
  1401. */
  1402. public void replacePixels(RenderedImage image, ImageWriteParam param)
  1403. throws IOException {
  1404. unsupported();
  1405. }
  1406. /**
  1407. * Replaces a portion of an image already present in the output
  1408. * with a portion of the given <code>Raster</code>. The image
  1409. * data must match, or be convertible to, the image layout of the
  1410. * existing image.
  1411. *
  1412. * <p> An <code>ImageWriteParam</code> may optionally be supplied
  1413. * to control the writing process. If <code>param</code> is
  1414. * <code>null</code>, a default write param will be used.
  1415. *
  1416. * <p> The destination region is specified in the
  1417. * <code>param</code> argument, and will be clipped to the image
  1418. * boundaries and the region supplied to
  1419. * <code>prepareReplacePixels</code>. At least one pixel of the
  1420. * source must not be clipped, or an exception is thrown.
  1421. *
  1422. * <p> If the supplied <code>ImageWriteParam</code> contains
  1423. * optional setting values not supported by this writer, they
  1424. * will be ignored.
  1425. *
  1426. * <p> This method may only be called after a call to
  1427. * <code>prepareReplacePixels</code>, or else an
  1428. * <code>IllegalStateException</code> will be thrown.
  1429. *
  1430. * <p> The default implementation throws an
  1431. * <code>IllegalStateException</code> if the output is
  1432. * <code>null</code>, and otherwise throws an
  1433. * <code>UnsupportedOperationException</code>.
  1434. *
  1435. * @param raster a <code>Raster</code> containing source
  1436. * pixels.
  1437. * @param param an <code>ImageWriteParam</code>, or
  1438. * <code>null</code> to use a default
  1439. * <code>ImageWriteParam</code>.
  1440. *
  1441. * @exception IllegalStateException if the output has not
  1442. * been set.
  1443. * @exception UnsupportedOperationException if
  1444. * <code>canReplacePixels(imageIndex)</code> returns
  1445. * <code>false</code>.
  1446. * @exception IllegalStateException if there is no previous call to
  1447. * <code>prepareReplacePixels</code> without a matching call to
  1448. * <code>endReplacePixels</code>.
  1449. * @exception UnsupportedOperationException if
  1450. * <code>canWriteRasters</code> returns <code>false</code>.
  1451. * @exception IllegalArgumentException if any of the following are true:
  1452. * <li> <code>raster</code> is <code>null</code>.
  1453. * <li> <code>param</code> is <code>null</code>.
  1454. * <li> the intersected region does not contain at least one pixel.
  1455. * <li> the layout of <code>raster</code> does not match, or this
  1456. * writer cannot convert it to, the existing image layout.
  1457. * </ul>
  1458. * @exception IOException if an I/O error occurs during writing.
  1459. */
  1460. public void replacePixels(Raster raster, ImageWriteParam param)
  1461. throws IOException {
  1462. unsupported();
  1463. }
  1464. /**
  1465. * Terminates a sequence of calls to <code>replacePixels</code>.
  1466. *
  1467. * <p> If <code>canReplacePixels</code> returns
  1468. * <code>false</code>, and
  1469. * <code>UnsupportedOperationException</code> will be thrown.
  1470. *
  1471. * <p> The default implementation throws an
  1472. * <code>IllegalStateException</code> if the output is
  1473. * <code>null</code>, and otherwise throws an
  1474. * <code>UnsupportedOperationException</code>.
  1475. *
  1476. * @exception IllegalStateException if the output has not
  1477. * been set.
  1478. * @exception UnsupportedOperationException if
  1479. * <code>canReplacePixels(imageIndex)</code> returns
  1480. * <code>false</code>.
  1481. * @exception IllegalStateException if there is no previous call
  1482. * to <code>prepareReplacePixels</code> without a matching call to
  1483. * <code>endReplacePixels</code>.
  1484. * @exception IOException if an I/O error occurs during writing.
  1485. */
  1486. public void endReplacePixels() throws IOException {
  1487. unsupported();
  1488. }
  1489. // Abort
  1490. /**
  1491. * Requests that any current write operation be aborted. The
  1492. * contents of the output following the abort will be undefined.
  1493. *
  1494. * <p> Writers should call <code>clearAbortRequest</code> at the
  1495. * beginning of each write operation, and poll the value of
  1496. * <code>abortRequested</code> regularly during the write.
  1497. */
  1498. public synchronized void abort() {
  1499. this.abortFlag = true;
  1500. }
  1501. /**
  1502. * Returns <code>true</code> if a request to abort the current
  1503. * write operation has been made since the writer was instantiated or
  1504. * <code>clearAbortRequest</code> was called.
  1505. *
  1506. * @return <code>true</code> if the current write operation should
  1507. * be aborted.
  1508. *
  1509. * @see #abort
  1510. * @see #clearAbortRequest
  1511. */
  1512. protected synchronized boolean abortRequested() {
  1513. return this.abortFlag;
  1514. }
  1515. /**
  1516. * Clears any previous abort request. After this method has been
  1517. * called, <code>abortRequested</code> will return
  1518. * <code>false</code>.
  1519. *
  1520. * @see #abort
  1521. * @see #abortRequested
  1522. */
  1523. protected synchronized void clearAbortRequest() {
  1524. this.abortFlag = false;
  1525. }
  1526. // Listeners
  1527. /**
  1528. * Adds an <code>IIOWriteWarningListener</code> to the list of
  1529. * registered warning listeners. If <code>listener</code> is
  1530. * <code>null</code>, no exception will be thrown and no action
  1531. * will be taken. Messages sent to the given listener will be
  1532. * localized, if possible, to match the current
  1533. * <code>Locale</code>. If no <code>Locale</code> has been set,
  1534. * warning messages may be localized as the writer sees fit.
  1535. *
  1536. * @param listener an <code>IIOWriteWarningListener</code> to be
  1537. * registered.
  1538. *
  1539. * @see #removeIIOWriteWarningListener
  1540. */
  1541. public void addIIOWriteWarningListener(IIOWriteWarningListener listener) {
  1542. if (listener == null) {
  1543. return;
  1544. }
  1545. warningListeners = ImageReader.addToList(warningListeners, listener);
  1546. warningLocales = ImageReader.addToList(warningLocales, getLocale());
  1547. }
  1548. /**
  1549. * Removes an <code>IIOWriteWarningListener</code> from the list
  1550. * of registered warning listeners. If the listener was not
  1551. * previously registered, or if <code>listener</code> is
  1552. * <code>null</code>, no exception will be thrown and no action
  1553. * will be taken.
  1554. *
  1555. * @param listener an <code>IIOWriteWarningListener</code> to be
  1556. * deregistered.
  1557. *
  1558. * @see #addIIOWriteWarningListener
  1559. */
  1560. public
  1561. void removeIIOWriteWarningListener(IIOWriteWarningListener listener) {
  1562. if (listener == null || warningListeners == null) {
  1563. return;
  1564. }
  1565. int index = warningListeners.indexOf(listener);
  1566. if (index != -1) {
  1567. warningListeners.remove(index);
  1568. warningLocales.remove(index);
  1569. if (warningListeners.size() == 0) {
  1570. warningListeners = warningLocales = null;
  1571. }
  1572. }
  1573. }
  1574. /**
  1575. * Removes all currently registered
  1576. * <code>IIOWriteWarningListener</code> objects.
  1577. *
  1578. * <p> The default implementation sets the
  1579. * <code>warningListeners</code> and <code>warningLocales</code>
  1580. * instance variables to <code>null</code>.
  1581. */
  1582. public void removeAllIIOWriteWarningListeners() {
  1583. this.warningListeners = null;
  1584. this.warningLocales = null;
  1585. }
  1586. /**
  1587. * Adds an <code>IIOWriteProgressListener</code> to the list of
  1588. * registered progress listeners. If <code>listener</code> is
  1589. * <code>null</code>, no exception will be thrown and no action
  1590. * will be taken.
  1591. *
  1592. * @param listener an <code>IIOWriteProgressListener</code> to be
  1593. * registered.
  1594. *
  1595. * @see #removeIIOWriteProgressListener
  1596. */
  1597. public void
  1598. addIIOWriteProgressListener(IIOWriteProgressListener listener) {
  1599. if (listener == null) {
  1600. return;
  1601. }
  1602. progressListeners = ImageReader.addToList(progressListeners, listener);
  1603. }
  1604. /**
  1605. * Removes an <code>IIOWriteProgressListener</code> from the list
  1606. * of registered progress listeners. If the listener was not
  1607. * previously registered, or if <code>listener</code> is
  1608. * <code>null</code>, no exception will be thrown and no action
  1609. * will be taken.
  1610. *
  1611. * @param listener an <code>IIOWriteProgressListener</code> to be
  1612. * deregistered.
  1613. *
  1614. * @see #addIIOWriteProgressListener
  1615. */
  1616. public void
  1617. removeIIOWriteProgressListener(IIOWriteProgressListener listener) {
  1618. if (listener == null || progressListeners == null) {
  1619. return;
  1620. }
  1621. progressListeners =
  1622. ImageReader.removeFromList(progressListeners, listener);
  1623. }
  1624. /**
  1625. * Removes all currently registered
  1626. * <code>IIOWriteProgressListener</code> objects.
  1627. *
  1628. * <p> The default implementation sets the
  1629. * <code>progressListeners</code> instance variable to
  1630. * <code>null</code>.
  1631. */
  1632. public void removeAllIIOWriteProgressListeners() {
  1633. this.progressListeners = null;
  1634. }
  1635. /**
  1636. * Broadcasts the start of an image write to all registered
  1637. * <code>IIOWriteProgressListener</code>s by calling their
  1638. * <code>imageStarted</code> method. Subclasses may use this
  1639. * method as a convenience.
  1640. *
  1641. * @param imageIndex the index of the image about to be written.
  1642. */
  1643. protected void processImageStarted(int imageIndex) {
  1644. if (progressListeners == null) {
  1645. return;
  1646. }
  1647. int numListeners = progressListeners.size();
  1648. for (int i = 0; i < numListeners; i++) {
  1649. IIOWriteProgressListener listener =
  1650. (IIOWriteProgressListener)progressListeners.get(i);
  1651. listener.imageStarted(this, imageIndex);
  1652. }
  1653. }
  1654. /**
  1655. * Broadcasts the current percentage of image completion to all
  1656. * registered <code>IIOWriteProgressListener</code>s by calling
  1657. * their <code>imageProgress</code> method. Subclasses may use
  1658. * this method as a convenience.
  1659. *
  1660. * @param percentageDone the current percentage of completion,
  1661. * as a <code>float</code>.
  1662. */
  1663. protected void processImageProgress(float percentageDone) {
  1664. if (progressListeners == null) {
  1665. return;
  1666. }
  1667. int numListeners = progressListeners.size();
  1668. for (int i = 0; i < numListeners; i++) {
  1669. IIOWriteProgressListener listener =
  1670. (IIOWriteProgressListener)progressListeners.get(i);
  1671. listener.imageProgress(this, percentageDone);
  1672. }
  1673. }
  1674. /**
  1675. * Broadcasts the completion of an image write to all registered
  1676. * <code>IIOWriteProgressListener</code>s by calling their
  1677. * <code>imageComplete</code> method. Subclasses may use this
  1678. * method as a convenience.
  1679. */
  1680. protected void processImageComplete() {
  1681. if (progressListeners == null) {
  1682. return;
  1683. }
  1684. int numListeners = progressListeners.size();
  1685. for (int i = 0; i < numListeners; i++) {
  1686. IIOWriteProgressListener listener =
  1687. (IIOWriteProgressListener)progressListeners.get(i);
  1688. listener.imageComplete(this);
  1689. }
  1690. }
  1691. /**
  1692. * Broadcasts the start of a thumbnail write to all registered
  1693. * <code>IIOWriteProgressListener</code>s by calling their
  1694. * <code>thumbnailStarted</code> method. Subclasses may use this
  1695. * method as a convenience.
  1696. *
  1697. * @param imageIndex the index of the image associated with the
  1698. * thumbnail.
  1699. * @param thumbnailIndex the index of the thumbnail.
  1700. */
  1701. protected void processThumbnailStarted(int imageIndex,
  1702. int thumbnailIndex) {
  1703. if (progressListeners == null) {
  1704. return;
  1705. }
  1706. int numListeners = progressListeners.size();
  1707. for (int i = 0; i < numListeners; i++) {
  1708. IIOWriteProgressListener listener =
  1709. (IIOWriteProgressListener)progressListeners.get(i);
  1710. listener.thumbnailStarted(this, imageIndex, thumbnailIndex);
  1711. }
  1712. }
  1713. /**
  1714. * Broadcasts the current percentage of thumbnail completion to
  1715. * all registered <code>IIOWriteProgressListener</code>s by calling
  1716. * their <code>thumbnailProgress</code> method. Subclasses may
  1717. * use this method as a convenience.
  1718. *
  1719. * @param percentageDone the current percentage of completion,
  1720. * as a <code>float</code>.
  1721. */
  1722. protected void processThumbnailProgress(float percentageDone) {
  1723. if (progressListeners == null) {
  1724. return;
  1725. }
  1726. int numListeners = progressListeners.size();
  1727. for (int i = 0; i < numListeners; i++) {
  1728. IIOWriteProgressListener listener =
  1729. (IIOWriteProgressListener)progressListeners.get(i);
  1730. listener.thumbnailProgress(this, percentageDone);
  1731. }
  1732. }
  1733. /**
  1734. * Broadcasts the completion of a thumbnail write to all registered
  1735. * <code>IIOWriteProgressListener</code>s by calling their
  1736. * <code>thumbnailComplete</code> method. Subclasses may use this
  1737. * method as a convenience.
  1738. */
  1739. protected void processThumbnailComplete() {
  1740. if (progressListeners == null) {
  1741. return;
  1742. }
  1743. int numListeners = progressListeners.size();
  1744. for (int i = 0; i < numListeners; i++) {
  1745. IIOWriteProgressListener listener =
  1746. (IIOWriteProgressListener)progressListeners.get(i);
  1747. listener.thumbnailComplete(this);
  1748. }
  1749. }
  1750. /**
  1751. * Broadcasts that the write has been aborted to all registered
  1752. * <code>IIOWriteProgressListener</code>s by calling their
  1753. * <code>writeAborted</code> method. Subclasses may use this
  1754. * method as a convenience.
  1755. */
  1756. protected void processWriteAborted() {
  1757. if (progressListeners == null) {
  1758. return;
  1759. }
  1760. int numListeners = progressListeners.size();
  1761. for (int i = 0; i < numListeners; i++) {
  1762. IIOWriteProgressListener listener =
  1763. (IIOWriteProgressListener)progressListeners.get(i);
  1764. listener.writeAborted(this);
  1765. }
  1766. }
  1767. /**
  1768. * Broadcasts a warning message to all registered
  1769. * <code>IIOWriteWarningListener</code>s by calling their
  1770. * <code>warningOccurred</code> method. Subclasses may use this
  1771. * method as a convenience.
  1772. *
  1773. * @param imageIndex the index of the image on which the warning
  1774. * occurred.
  1775. * @param warning the warning message.
  1776. */
  1777. protected void processWarningOccurred(int imageIndex,
  1778. String warning) {
  1779. if (warningListeners == null) {
  1780. return;
  1781. }
  1782. int numListeners = warningListeners.size();
  1783. for (int i = 0; i < numListeners; i++) {
  1784. IIOWriteWarningListener listener =
  1785. (IIOWriteWarningListener)warningListeners.get(i);
  1786. listener.warningOccurred(this, imageIndex, warning);
  1787. }
  1788. }
  1789. /**
  1790. * Broadcasts a localized warning message to all registered
  1791. * <code>IIOWriteWarningListener</code>s by calling their
  1792. * <code>warningOccurred</code> method with a string taken
  1793. * from a <code>ResourceBundle</code>. Subclasses may use this
  1794. * method as a convenience.
  1795. *
  1796. * @param imageIndex the index of the image on which the warning
  1797. * occurred.
  1798. * @param baseName the base name of a set of
  1799. * <code>ResourceBundle</code>s containing localized warning
  1800. * messages.
  1801. * @param keyword the keyword used to index the warning message
  1802. * within the set of <code>ResourceBundle</code>s.
  1803. */
  1804. protected void processWarningOccurred(int imageIndex,
  1805. String baseName,
  1806. String keyword) {
  1807. if (warningListeners == null) {
  1808. return;
  1809. }
  1810. int numListeners = warningListeners.size();
  1811. for (int i = 0; i < numListeners; i++) {
  1812. IIOWriteWarningListener listener =
  1813. (IIOWriteWarningListener)warningListeners.get(i);
  1814. Locale locale = (Locale)warningLocales.get(i);
  1815. ResourceBundle bundle = (locale == null)
  1816. ? ResourceBundle.getBundle(baseName)
  1817. : ResourceBundle.getBundle(baseName, locale);
  1818. String warning = bundle.getString(keyword);
  1819. listener.warningOccurred(this, imageIndex, warning);
  1820. }
  1821. }
  1822. // State management
  1823. /**
  1824. * Restores the <code>ImageWriter</code> to its initial state.
  1825. *
  1826. * <p> The default implementation calls
  1827. * <code>setOutput(null)</code>, <code>setLocale(null)</code>,
  1828. * <code>removeAllIIOWriteWarningListeners()</code>,
  1829. * <code>removeAllIIOWriteProgressListeners()</code>, and
  1830. * <code>clearAbortRequest</code>.
  1831. */
  1832. public void reset() {
  1833. setOutput(null);
  1834. setLocale(null);
  1835. removeAllIIOWriteWarningListeners();
  1836. removeAllIIOWriteProgressListeners();
  1837. clearAbortRequest();
  1838. }
  1839. /**
  1840. * Allows any resources held by this object to be released. The
  1841. * result of calling any other method (other than
  1842. * <code>finalize</code>) subsequent to a call to this method
  1843. * is undefined.
  1844. *
  1845. * <p>It is important for applications to call this method when they
  1846. * know they will no longer be using this <code>ImageWriter</code>.
  1847. * Otherwise, the writer may continue to hold on to resources
  1848. * indefinitely.
  1849. *
  1850. * <p>The default implementation of this method in the superclass does
  1851. * nothing. Subclass implementations should ensure that all resources,
  1852. * especially native resources, are released.
  1853. */
  1854. public void dispose() {
  1855. }
  1856. }