ImageWriter.java 45 KB

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