ImageIO.java 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242
  1. /* ImageIO.java --
  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.image.BufferedImage;
  33. import java.awt.image.RenderedImage;
  34. import java.io.File;
  35. import java.io.FileInputStream;
  36. import java.io.FileOutputStream;
  37. import java.io.IOException;
  38. import java.io.InputStream;
  39. import java.io.OutputStream;
  40. import java.net.URL;
  41. import java.util.ArrayList;
  42. import java.util.Collections;
  43. import java.util.Iterator;
  44. import javax.imageio.spi.IIORegistry;
  45. import javax.imageio.spi.ImageInputStreamSpi;
  46. import javax.imageio.spi.ImageOutputStreamSpi;
  47. import javax.imageio.spi.ImageReaderSpi;
  48. import javax.imageio.spi.ImageTranscoderSpi;
  49. import javax.imageio.spi.ImageWriterSpi;
  50. import javax.imageio.spi.ServiceRegistry;
  51. import javax.imageio.stream.ImageInputStream;
  52. import javax.imageio.stream.ImageOutputStream;
  53. import javax.imageio.stream.MemoryCacheImageInputStream;
  54. import javax.imageio.stream.MemoryCacheImageOutputStream;
  55. /**
  56. * An uninstantiable class that provides static methods for locating
  57. * and using image readers and writers.
  58. */
  59. public final class ImageIO
  60. {
  61. /**
  62. * Construct an ImageIO. Private since ImageIO is not instantiable.
  63. */
  64. private ImageIO()
  65. {
  66. }
  67. private static final class ReaderFormatFilter implements ServiceRegistry.Filter
  68. {
  69. private String formatName;
  70. public ReaderFormatFilter(String formatName)
  71. {
  72. this.formatName = formatName;
  73. }
  74. public boolean filter (Object provider)
  75. {
  76. if (provider instanceof ImageReaderSpi)
  77. {
  78. ImageReaderSpi spi = (ImageReaderSpi) provider;
  79. String[] formatNames = spi.getFormatNames();
  80. for (int i = formatNames.length - 1; i >= 0; --i)
  81. if (formatName.equals(formatNames[i]))
  82. return true;
  83. }
  84. return false;
  85. }
  86. }
  87. private static final class ReaderMIMETypeFilter implements ServiceRegistry.Filter
  88. {
  89. private String MIMEType;
  90. public ReaderMIMETypeFilter(String MIMEType)
  91. {
  92. this.MIMEType = MIMEType;
  93. }
  94. public boolean filter(Object provider)
  95. {
  96. if (provider instanceof ImageReaderSpi)
  97. {
  98. ImageReaderSpi spi = (ImageReaderSpi) provider;
  99. String[] mimetypes = spi.getMIMETypes();
  100. for (int i = mimetypes.length - 1; i >= 0; --i)
  101. if (MIMEType.equals(mimetypes[i]))
  102. return true;
  103. }
  104. return false;
  105. }
  106. }
  107. private static final class ReaderObjectFilter implements ServiceRegistry.Filter
  108. {
  109. private Object object;
  110. public ReaderObjectFilter(Object object)
  111. {
  112. this.object = object;
  113. }
  114. public boolean filter(Object provider)
  115. {
  116. if (provider instanceof ImageReaderSpi)
  117. {
  118. ImageReaderSpi spi = (ImageReaderSpi) provider;
  119. try
  120. {
  121. if (spi.canDecodeInput(object))
  122. return true;
  123. }
  124. catch (IOException e)
  125. {
  126. // Return false in this case
  127. }
  128. }
  129. return false;
  130. }
  131. }
  132. private static final class ReaderSuffixFilter implements ServiceRegistry.Filter
  133. {
  134. private String fileSuffix;
  135. public ReaderSuffixFilter(String fileSuffix)
  136. {
  137. this.fileSuffix = fileSuffix;
  138. }
  139. public boolean filter(Object provider)
  140. {
  141. if (provider instanceof ImageReaderSpi)
  142. {
  143. ImageReaderSpi spi = (ImageReaderSpi) provider;
  144. String[] suffixes = spi.getFileSuffixes();
  145. for (int i = suffixes.length - 1; i >= 0; --i)
  146. if (fileSuffix.equals(suffixes[i]))
  147. return true;
  148. }
  149. return false;
  150. }
  151. }
  152. private static final class WriterFormatFilter implements ServiceRegistry.Filter
  153. {
  154. private String formatName;
  155. public WriterFormatFilter(String formatName)
  156. {
  157. this.formatName = formatName;
  158. }
  159. public boolean filter(Object provider)
  160. {
  161. if (provider instanceof ImageWriterSpi)
  162. {
  163. ImageWriterSpi spi = (ImageWriterSpi) provider;
  164. String[] formatNames = spi.getFormatNames();
  165. for (int i = formatNames.length - 1; i >= 0; --i)
  166. if (formatName.equals(formatNames[i]))
  167. return true;
  168. }
  169. return false;
  170. }
  171. }
  172. private static final class WriterMIMETypeFilter implements ServiceRegistry.Filter
  173. {
  174. private String MIMEType;
  175. public WriterMIMETypeFilter(String MIMEType)
  176. {
  177. this.MIMEType = MIMEType;
  178. }
  179. public boolean filter(Object provider)
  180. {
  181. if (provider instanceof ImageWriterSpi)
  182. {
  183. ImageWriterSpi spi = (ImageWriterSpi) provider;
  184. String[] mimetypes = spi.getMIMETypes();
  185. for (int i = mimetypes.length - 1; i >= 0; --i)
  186. if (MIMEType.equals(mimetypes[i]))
  187. return true;
  188. }
  189. return false;
  190. }
  191. }
  192. private static final class WriterSuffixFilter implements ServiceRegistry.Filter
  193. {
  194. private String fileSuffix;
  195. public WriterSuffixFilter(String fileSuffix)
  196. {
  197. this.fileSuffix = fileSuffix;
  198. }
  199. public boolean filter(Object provider)
  200. {
  201. if (provider instanceof ImageWriterSpi)
  202. {
  203. ImageWriterSpi spi = (ImageWriterSpi) provider;
  204. String[] suffixes = spi.getFileSuffixes();
  205. for (int i = suffixes.length - 1; i >= 0; --i)
  206. if (fileSuffix.equals(suffixes[i]))
  207. return true;
  208. }
  209. return false;
  210. }
  211. }
  212. private static final class WriterObjectFilter implements ServiceRegistry.Filter
  213. {
  214. private ImageTypeSpecifier type;
  215. private String formatName;
  216. public WriterObjectFilter(ImageTypeSpecifier type,
  217. String formatName)
  218. {
  219. this.type = type;
  220. this.formatName = formatName;
  221. }
  222. public boolean filter(Object provider)
  223. {
  224. if (provider instanceof ImageWriterSpi)
  225. {
  226. ImageWriterSpi spi = (ImageWriterSpi) provider;
  227. if (spi.canEncodeImage(type))
  228. {
  229. String[] formatNames = spi.getFormatNames();
  230. for (int i = formatNames.length - 1; i >= 0; --i)
  231. if (formatName.equals(formatNames[i]))
  232. return true;
  233. }
  234. }
  235. return false;
  236. }
  237. }
  238. private static final class TranscoderFilter implements ServiceRegistry.Filter
  239. {
  240. private ImageReader reader;
  241. private ImageWriter writer;
  242. public TranscoderFilter(ImageReader reader,
  243. ImageWriter writer)
  244. {
  245. this.reader = reader;
  246. this.writer = writer;
  247. }
  248. public boolean filter(Object provider)
  249. {
  250. if (provider instanceof ImageTranscoderSpi)
  251. {
  252. ImageTranscoderSpi spi = (ImageTranscoderSpi) provider;
  253. if (spi.getReaderServiceProviderName().equals
  254. (reader.getOriginatingProvider().getClass().getName())
  255. && spi.getWriterServiceProviderName().equals
  256. (writer.getOriginatingProvider().getClass().getName()))
  257. return true;
  258. }
  259. return false;
  260. }
  261. }
  262. private static final class ImageReaderIterator
  263. implements Iterator<ImageReader>
  264. {
  265. Iterator<ImageReaderSpi> it;
  266. Object readerExtension;
  267. public ImageReaderIterator(Iterator<ImageReaderSpi> it,
  268. Object readerExtension)
  269. {
  270. this.it = it;
  271. this.readerExtension = readerExtension;
  272. }
  273. public ImageReaderIterator(Iterator<ImageReaderSpi> it)
  274. {
  275. this.it = it;
  276. }
  277. public boolean hasNext()
  278. {
  279. return it.hasNext();
  280. }
  281. public ImageReader next()
  282. {
  283. try
  284. {
  285. ImageReaderSpi spi = it.next();
  286. return (readerExtension == null
  287. ? spi.createReaderInstance()
  288. : spi.createReaderInstance(readerExtension));
  289. }
  290. catch (IOException e)
  291. {
  292. return null;
  293. }
  294. }
  295. public void remove()
  296. {
  297. throw new UnsupportedOperationException();
  298. }
  299. }
  300. private static final class ImageWriterIterator
  301. implements Iterator<ImageWriter>
  302. {
  303. Iterator<ImageWriterSpi> it;
  304. Object writerExtension;
  305. public ImageWriterIterator(Iterator<ImageWriterSpi> it,
  306. Object writerExtension)
  307. {
  308. this.it = it;
  309. this.writerExtension = writerExtension;
  310. }
  311. public ImageWriterIterator(Iterator<ImageWriterSpi> it)
  312. {
  313. this.it = it;
  314. }
  315. public boolean hasNext()
  316. {
  317. return it.hasNext();
  318. }
  319. public ImageWriter next()
  320. {
  321. try
  322. {
  323. ImageWriterSpi spi = it.next();
  324. return (writerExtension == null
  325. ? spi.createWriterInstance()
  326. : spi.createWriterInstance(writerExtension));
  327. }
  328. catch (IOException e)
  329. {
  330. return null;
  331. }
  332. }
  333. public void remove()
  334. {
  335. throw new UnsupportedOperationException();
  336. }
  337. }
  338. private static File cacheDirectory;
  339. private static boolean useCache = true;
  340. private static Iterator<ImageReader> getReadersByFilter(Class<ImageReaderSpi> type,
  341. ServiceRegistry.Filter filter,
  342. Object readerExtension)
  343. {
  344. try
  345. {
  346. Iterator<ImageReaderSpi> it
  347. = getRegistry().getServiceProviders(type, filter, true);
  348. return new ImageReaderIterator(it, readerExtension);
  349. }
  350. catch (IllegalArgumentException e)
  351. {
  352. return Collections.EMPTY_SET.iterator();
  353. }
  354. }
  355. private static Iterator<ImageWriter> getWritersByFilter(Class<ImageWriterSpi> type,
  356. ServiceRegistry.Filter filter,
  357. Object writerExtension)
  358. {
  359. try
  360. {
  361. Iterator<ImageWriterSpi> it
  362. = getRegistry().getServiceProviders(type, filter, true);
  363. return new ImageWriterIterator(it, writerExtension);
  364. }
  365. catch (IllegalArgumentException e)
  366. {
  367. return Collections.EMPTY_SET.iterator();
  368. }
  369. }
  370. /**
  371. * Retrieve the current cache directory.
  372. *
  373. * @return the current cache directory or null if none is set.
  374. */
  375. public static File getCacheDirectory()
  376. {
  377. return cacheDirectory;
  378. }
  379. /**
  380. * Retrieve an iterator over all registered readers for the given
  381. * format.
  382. *
  383. * @param formatName an infomal format name (e.g. "jpeg" or "bmp")
  384. *
  385. * @return an iterator over a collection of image readers
  386. *
  387. * @exception IllegalArgumentException if formatName is null
  388. */
  389. public static Iterator<ImageReader> getImageReadersByFormatName(String formatName)
  390. {
  391. if (formatName == null)
  392. throw new IllegalArgumentException("formatName may not be null");
  393. return getReadersByFilter(ImageReaderSpi.class,
  394. new ReaderFormatFilter(formatName),
  395. formatName);
  396. }
  397. /**
  398. * Retrieve an iterator over all registered readers for the given
  399. * MIME type.
  400. *
  401. * @param MIMEType a MIME specification for an image type
  402. * (e.g. "image/jpeg" or "image/x-bmp")
  403. *
  404. * @return an iterator over a collection of image readers
  405. *
  406. * @exception IllegalArgumentException if MIMEType is null
  407. */
  408. public static Iterator<ImageReader> getImageReadersByMIMEType(String MIMEType)
  409. {
  410. if (MIMEType == null)
  411. throw new IllegalArgumentException("MIMEType may not be null");
  412. return getReadersByFilter(ImageReaderSpi.class,
  413. new ReaderMIMETypeFilter(MIMEType),
  414. MIMEType);
  415. }
  416. /**
  417. * Retrieve an iterator over all registered readers for the given
  418. * file suffix.
  419. *
  420. * @param fileSuffix an image file suffix (e.g. "jpg" or "bmp")
  421. *
  422. * @return an iterator over a collection of image readers
  423. *
  424. * @exception IllegalArgumentException if fileSuffix is null
  425. */
  426. public static Iterator<ImageReader> getImageReadersBySuffix(String fileSuffix)
  427. {
  428. if (fileSuffix == null)
  429. throw new IllegalArgumentException("formatName may not be null");
  430. return getReadersByFilter(ImageReaderSpi.class,
  431. new ReaderSuffixFilter(fileSuffix),
  432. fileSuffix);
  433. }
  434. /**
  435. * Retrieve an iterator over all registered writers for the given
  436. * format.
  437. *
  438. * @param formatName an infomal format name (e.g. "jpeg" or "bmp")
  439. *
  440. * @return an iterator over a collection of image writers
  441. *
  442. * @exception IllegalArgumentException if formatName is null
  443. */
  444. public static Iterator<ImageWriter> getImageWritersByFormatName(String formatName)
  445. {
  446. if (formatName == null)
  447. throw new IllegalArgumentException("formatName may not be null");
  448. return getWritersByFilter(ImageWriterSpi.class,
  449. new WriterFormatFilter(formatName),
  450. formatName);
  451. }
  452. /**
  453. * Retrieve an iterator over all registered writers for the given
  454. * MIME type.
  455. *
  456. * @param MIMEType a MIME specification for an image type
  457. * (e.g. "image/jpeg" or "image/x-bmp")
  458. *
  459. * @return an iterator over a collection of image writers
  460. *
  461. * @exception IllegalArgumentException if MIMEType is null
  462. */
  463. public static Iterator<ImageWriter> getImageWritersByMIMEType(String MIMEType)
  464. {
  465. if (MIMEType == null)
  466. throw new IllegalArgumentException("MIMEType may not be null");
  467. return getWritersByFilter(ImageWriterSpi.class,
  468. new WriterMIMETypeFilter(MIMEType),
  469. MIMEType);
  470. }
  471. /**
  472. * Retrieve an iterator over all registered writers for the given
  473. * file suffix.
  474. *
  475. * @param fileSuffix an image file suffix (e.g. "jpg" or "bmp")
  476. *
  477. * @return an iterator over a collection of image writers
  478. *
  479. * @exception IllegalArgumentException if fileSuffix is null
  480. */
  481. public static Iterator<ImageWriter> getImageWritersBySuffix(String fileSuffix)
  482. {
  483. if (fileSuffix == null)
  484. throw new IllegalArgumentException("fileSuffix may not be null");
  485. return getWritersByFilter(ImageWriterSpi.class,
  486. new WriterSuffixFilter(fileSuffix),
  487. fileSuffix);
  488. }
  489. /**
  490. * Retrieve all the informal format names supported by the
  491. * collection of registered image readers.
  492. *
  493. * @return an array of format names
  494. */
  495. public static String[] getReaderFormatNames()
  496. {
  497. try
  498. {
  499. Iterator it =
  500. getRegistry().getServiceProviders(ImageReaderSpi.class, true);
  501. ArrayList result = new ArrayList();
  502. while (it.hasNext())
  503. {
  504. ImageReaderSpi spi = (ImageReaderSpi) it.next();
  505. String[] names = spi.getFormatNames();
  506. for (int i = names.length - 1; i >= 0; --i)
  507. result.add(names[i]);
  508. }
  509. return (String[]) result.toArray(new String[result.size()]);
  510. }
  511. catch (IllegalArgumentException e)
  512. {
  513. return new String[0];
  514. }
  515. }
  516. /**
  517. * Retrieve all the MIME types supported by the collection of
  518. * registered image readers.
  519. *
  520. * @return an array of MIME types
  521. */
  522. public static String[] getReaderMIMETypes()
  523. {
  524. try
  525. {
  526. Iterator it =
  527. getRegistry().getServiceProviders(ImageReaderSpi.class, true);
  528. ArrayList result = new ArrayList();
  529. while (it.hasNext())
  530. {
  531. ImageReaderSpi spi = (ImageReaderSpi) it.next();
  532. String[] names = spi.getMIMETypes();
  533. for (int i = names.length - 1; i >= 0; --i)
  534. result.add(names[i]);
  535. }
  536. return (String[]) result.toArray(new String[result.size()]);
  537. }
  538. catch (IllegalArgumentException e)
  539. {
  540. return new String[0];
  541. }
  542. }
  543. private static IIORegistry getRegistry()
  544. {
  545. return IIORegistry.getDefaultInstance();
  546. }
  547. /**
  548. * Check whether or not an on-disk cache is used for image input and
  549. * output streams.
  550. *
  551. * @return true if an on-disk cache is available, false otherwise
  552. */
  553. public static boolean getUseCache()
  554. {
  555. return useCache;
  556. }
  557. /**
  558. * Retrieve all the informal format names supported by the
  559. * collection of registered image writers.
  560. *
  561. * @return an array of format names
  562. */
  563. public static String[] getWriterFormatNames()
  564. {
  565. try
  566. {
  567. Iterator it =
  568. getRegistry().getServiceProviders(ImageWriterSpi.class, true);
  569. ArrayList result = new ArrayList();
  570. while (it.hasNext())
  571. {
  572. ImageWriterSpi spi = (ImageWriterSpi) it.next();
  573. String[] names = spi.getFormatNames();
  574. for (int i = names.length - 1; i >= 0; --i)
  575. result.add(names[i]);
  576. }
  577. return (String[]) result.toArray(new String[result.size()]);
  578. }
  579. catch (IllegalArgumentException e)
  580. {
  581. return new String[0];
  582. }
  583. }
  584. /**
  585. * Retrieve all the MIME types supported by the collection of
  586. * registered image writers.
  587. *
  588. * @return an array of MIME types
  589. */
  590. public static String[] getWriterMIMETypes()
  591. {
  592. try
  593. {
  594. Iterator it =
  595. getRegistry().getServiceProviders(ImageWriterSpi.class, true);
  596. ArrayList result = new ArrayList();
  597. while (it.hasNext())
  598. {
  599. ImageWriterSpi spi = (ImageWriterSpi) it.next();
  600. String[] names = spi.getMIMETypes();
  601. for (int i = names.length - 1; i >= 0; --i)
  602. result.add(names[i]);
  603. }
  604. return (String[]) result.toArray(new String[result.size()]);
  605. }
  606. catch (IllegalArgumentException e)
  607. {
  608. return new String[0];
  609. }
  610. }
  611. /**
  612. * Rescans the application classpath for ImageIO service providers
  613. * and registers them.
  614. */
  615. public static void scanForPlugins()
  616. {
  617. IIORegistry.getDefaultInstance().registerApplicationClasspathSpis();
  618. }
  619. /**
  620. * Set the directory to be used for caching image data. A null
  621. * argument means to use the default system temporary directory.
  622. * This cache directory is only used if getUseCache returns true.
  623. *
  624. * @param cacheDirectory the directory where image data should be
  625. * cached
  626. *
  627. * @exception IllegalArgumentException if cacheDirectory is not a
  628. * directory
  629. */
  630. public static void setCacheDirectory(File cacheDirectory)
  631. {
  632. // FIXME: add SecurityManager call
  633. if (cacheDirectory != null)
  634. {
  635. if (!cacheDirectory.isDirectory())
  636. throw new IllegalArgumentException("cacheDirectory must be a directory");
  637. cacheDirectory.canWrite();
  638. }
  639. ImageIO.cacheDirectory = cacheDirectory;
  640. }
  641. /**
  642. * Control whether or not an on-disk cache is used. This cache is
  643. * used to store input or output data from an image data stream when
  644. * data in the stream needs to be re-processed.
  645. *
  646. * If useCache is false the cache will be stored in memory. Doing
  647. * so eliminates file creation and deletion overhead. The default
  648. * is to use an on-disk cache.
  649. *
  650. * @param useCache true to use an on-disk cache, false otherwise
  651. */
  652. public static void setUseCache(boolean useCache)
  653. {
  654. ImageIO.useCache = useCache;
  655. }
  656. /**
  657. * Write an image to a file using a registered writer that supports
  658. * the given format, overwriting the file if it already exists.
  659. *
  660. * @param im the image data to write
  661. * @param formatName an informal description of the output format
  662. * @param output the file to which the image will be written
  663. *
  664. * @return false if no registered writer supports the given format,
  665. * true otherwise
  666. *
  667. * @exception IllegalArgumentException if any argument is null
  668. * @exception IOException if a writing error occurs
  669. */
  670. public static boolean write(RenderedImage im,
  671. String formatName,
  672. File output)
  673. throws IOException
  674. {
  675. if (im == null || formatName == null || output == null)
  676. throw new IllegalArgumentException ("null argument");
  677. return write(im, formatName, new FileOutputStream(output));
  678. }
  679. /**
  680. * Write an image to an output stream using a registered writer that
  681. * supports the given format.
  682. *
  683. * @param im the image data to write
  684. * @param formatName an informal description of the output format
  685. * @param output the output stream to which the image will be
  686. * written
  687. *
  688. * @return false if no registered writer supports the given format,
  689. * true otherwise
  690. *
  691. * @exception IllegalArgumentException if any argument is null
  692. * @exception IOException if a writing error occurs
  693. */
  694. public static boolean write(RenderedImage im,
  695. String formatName,
  696. OutputStream output)
  697. throws IOException
  698. {
  699. if (im == null || formatName == null || output == null)
  700. throw new IllegalArgumentException ("null argument");
  701. return write(im, formatName, new MemoryCacheImageOutputStream(output));
  702. }
  703. /**
  704. * Write an image to an ImageOutputStream using a registered writer
  705. * that supports the given format. Image data is written starting
  706. * at the ImageOutputStream's current stream pointer, overwriting
  707. * any existing data.
  708. *
  709. * @param im the image data to write
  710. * @param formatName an informal description of the output format
  711. * @param output the image output stream to which the image will be
  712. * written
  713. *
  714. * @return false if no registered writer supports the given format,
  715. * true otherwise
  716. *
  717. * @exception IllegalArgumentException if any argument is null
  718. * @exception IOException if a writing error occurs
  719. */
  720. public static boolean write(RenderedImage im,
  721. String formatName,
  722. ImageOutputStream output)
  723. throws IOException
  724. {
  725. if (im == null || formatName == null || output == null)
  726. throw new IllegalArgumentException ("null argument");
  727. Iterator writers = getImageWritersByFormatName(formatName);
  728. IIOImage img = new IIOImage(im, null, null);
  729. while (writers.hasNext())
  730. {
  731. ImageWriter w = (ImageWriter) writers.next();
  732. try
  733. {
  734. w.setOutput(output);
  735. }
  736. catch (IllegalArgumentException e)
  737. {
  738. continue;
  739. }
  740. w.write(null, img, null);
  741. w.dispose();
  742. output.close();
  743. return true;
  744. }
  745. return false;
  746. }
  747. /**
  748. * Create a buffered image from an image input stream. An image
  749. * reader that supports the given image data is automatically
  750. * selected from the collection of registered readers. If no
  751. * registered reader can handle the input format, null is returned.
  752. *
  753. * @param stream the image input stream from which to read image
  754. * data
  755. *
  756. * @return a new buffered image created from the given image data,
  757. * or null
  758. *
  759. * @exception IllegalArgumentException if stream is null
  760. * @exception IOException if a reading error occurs
  761. */
  762. public static BufferedImage read(ImageInputStream stream)
  763. throws IOException
  764. {
  765. if (stream == null)
  766. throw new IllegalArgumentException("null argument");
  767. Iterator providers = getRegistry().getServiceProviders(ImageReaderSpi.class, true);
  768. while (providers.hasNext())
  769. {
  770. ImageReaderSpi spi = (ImageReaderSpi) providers.next();
  771. if (spi.canDecodeInput(stream))
  772. {
  773. ImageReader reader = spi.createReaderInstance();
  774. reader.setInput(stream);
  775. return reader.read(0, null);
  776. }
  777. }
  778. return null;
  779. }
  780. /**
  781. * Create a buffered image from a URL. An image reader that
  782. * supports the given image data is automatically selected from the
  783. * collection of registered readers. If no registered reader can
  784. * handle the input format, null is returned.
  785. *
  786. * The image data will be cached in the current cache directory if
  787. * caching is enabled.
  788. *
  789. * This method does not locate readers that read data directly from
  790. * a URL. To locate such readers manually, use IIORegistry and
  791. * ImageReaderSpi.
  792. *
  793. * @param input the URL from which to retrieve the image file
  794. *
  795. * @return a new buffered image created from the given image URL, or
  796. * null
  797. *
  798. * @exception IllegalArgumentException if input is null
  799. * @exception IOException if a reading error occurs
  800. */
  801. public static BufferedImage read(URL input)
  802. throws IOException
  803. {
  804. if (input == null)
  805. throw new IllegalArgumentException("null argument");
  806. return read(input.openStream());
  807. }
  808. /**
  809. * Create a buffered image from an input stream. An image reader
  810. * that supports the given image data is automatically selected from
  811. * the collection of registered readers. If no registered reader
  812. * can handle the input format, null is returned.
  813. *
  814. * The image data will be cached in the current cache directory if
  815. * caching is enabled.
  816. *
  817. * This method does not locate readers that read data directly from
  818. * an input stream. To locate such readers manually, use
  819. * IIORegistry and ImageReaderSpi.
  820. *
  821. * @param input the input stream from which to read the image data
  822. *
  823. * @return a new buffered image created from the given input stream,
  824. * or null
  825. *
  826. * @exception IllegalArgumentException if input is null
  827. * @exception IOException if a reading error occurs
  828. */
  829. public static BufferedImage read(InputStream input)
  830. throws IOException
  831. {
  832. if (input == null)
  833. throw new IllegalArgumentException("null argument");
  834. return read(new MemoryCacheImageInputStream(input));
  835. }
  836. /**
  837. * Create a buffered image from a file. An image reader that
  838. * supports the given image data is automatically selected from the
  839. * collection of registered readers. If no registered reader can
  840. * handle the input format, null is returned.
  841. *
  842. * The image data will be cached in the current cache directory if
  843. * caching is enabled.
  844. *
  845. * This method does not locate readers that read data directly from
  846. * a file. To locate such readers manually, use IIORegistry and
  847. * ImageReaderSpi.
  848. *
  849. * @param input the file from which to read image data
  850. *
  851. * @return a new buffered image created from the given image file,
  852. * or null
  853. *
  854. * @exception IllegalArgumentException if input is null
  855. * @exception IOException if a reading error occurs
  856. */
  857. public static BufferedImage read(File input)
  858. throws IOException
  859. {
  860. if (input == null)
  861. throw new IllegalArgumentException("null argument");
  862. return read(new FileInputStream(input));
  863. }
  864. /**
  865. * Create an image input stream from the given object. The
  866. * collection of ImageInputStreamSpis registered with the
  867. * IIORegistry is searched for an image input stream that can take
  868. * input from the given object. null is returned if no such SPI is
  869. * registered.
  870. *
  871. * The image data will be cached in the current cache directory if
  872. * caching is enabled.
  873. *
  874. * @param input an object from which to read image data
  875. *
  876. * @return an ImageInputStream that can read data from input, or
  877. * null
  878. *
  879. * @exception IllegalArgumentException if input is null
  880. * @exception IOException if caching is required but not enabled
  881. */
  882. public static ImageInputStream createImageInputStream (Object input)
  883. throws IOException
  884. {
  885. if (input == null)
  886. throw new IllegalArgumentException ("null argument");
  887. Iterator spis = getRegistry().getServiceProviders
  888. (ImageInputStreamSpi.class, true);
  889. ImageInputStreamSpi foundSpi = null;
  890. while(spis.hasNext())
  891. {
  892. ImageInputStreamSpi spi = (ImageInputStreamSpi) spis.next();
  893. if (input.getClass().equals(spi.getInputClass()))
  894. {
  895. foundSpi = spi;
  896. break;
  897. }
  898. }
  899. return foundSpi == null ? null :
  900. foundSpi.createInputStreamInstance (input,
  901. getUseCache(),
  902. getCacheDirectory());
  903. }
  904. /**
  905. * Create an image output stream from the given object. The
  906. * collection of ImageOutputStreamSpis registered with the
  907. * IIORegistry is searched for an image output stream that can send
  908. * output to the given object. null is returned if no such SPI is
  909. * registered.
  910. *
  911. * The image data will be cached in the current cache directory if
  912. * caching is enabled.
  913. *
  914. * @param output an object to which to write image data
  915. *
  916. * @return an ImageOutputStream that can send data to output, or
  917. * null
  918. *
  919. * @exception IllegalArgumentException if output is null
  920. * @exception IOException if caching is required but not enabled
  921. */
  922. public static ImageOutputStream createImageOutputStream (Object output)
  923. throws IOException
  924. {
  925. if (output == null)
  926. throw new IllegalArgumentException ("null argument");
  927. Iterator spis = getRegistry().getServiceProviders
  928. (ImageOutputStreamSpi.class, true);
  929. ImageOutputStreamSpi foundSpi = null;
  930. while(spis.hasNext())
  931. {
  932. ImageOutputStreamSpi spi = (ImageOutputStreamSpi) spis.next();
  933. if (output.getClass().equals(spi.getOutputClass()))
  934. {
  935. foundSpi = spi;
  936. break;
  937. }
  938. }
  939. return foundSpi == null ? null :
  940. foundSpi.createOutputStreamInstance (output,
  941. getUseCache(),
  942. getCacheDirectory());
  943. }
  944. /**
  945. * Retrieve an image reader corresponding to an image writer, or
  946. * null if writer is not registered or if no corresponding reader is
  947. * registered.
  948. *
  949. * @param writer a registered image writer
  950. *
  951. * @return an image reader corresponding to writer, or null
  952. *
  953. * @exception IllegalArgumentException if writer is null
  954. */
  955. public static ImageReader getImageReader (ImageWriter writer)
  956. {
  957. if (writer == null)
  958. throw new IllegalArgumentException ("null argument");
  959. ImageWriterSpi spi = writer.getOriginatingProvider();
  960. String[] readerSpiNames = spi.getImageReaderSpiNames();
  961. ImageReader r = null;
  962. if (readerSpiNames != null)
  963. {
  964. try
  965. {
  966. Class readerClass = Class.forName (readerSpiNames[0]);
  967. r = (ImageReader) readerClass.newInstance ();
  968. }
  969. catch (Exception e)
  970. {
  971. return null;
  972. }
  973. }
  974. return r;
  975. }
  976. /**
  977. * Retrieve an iterator over the collection of registered image
  978. * readers that support reading data from the given object.
  979. *
  980. * @param input the object for which to retrieve image readers
  981. *
  982. * @return an iterator over a collection of image readers
  983. */
  984. public static Iterator<ImageReader> getImageReaders (Object input)
  985. {
  986. if (input == null)
  987. throw new IllegalArgumentException ("null argument");
  988. Iterator<ImageReaderSpi> spiIterator
  989. = getRegistry().getServiceProviders (ImageReaderSpi.class,
  990. new ReaderObjectFilter(input),
  991. true);
  992. return new ImageReaderIterator(spiIterator);
  993. }
  994. /**
  995. * Retrieve an iterator over the collection of registered image
  996. * writers that support writing images of the given type and in the
  997. * given format.
  998. *
  999. * @param type the output image's colour and sample models
  1000. * @param formatName the output image format
  1001. *
  1002. * @return an iterator over a collection of image writers
  1003. */
  1004. public static Iterator<ImageWriter> getImageWriters (ImageTypeSpecifier type,
  1005. String formatName)
  1006. {
  1007. if (type == null || formatName == null)
  1008. throw new IllegalArgumentException ("null argument");
  1009. final Iterator<ImageWriterSpi> spiIterator
  1010. = getRegistry().getServiceProviders (ImageWriterSpi.class,
  1011. new WriterObjectFilter(type,
  1012. formatName),
  1013. true);
  1014. return new ImageWriterIterator(spiIterator);
  1015. }
  1016. /**
  1017. * Retrieve an image writer corresponding to an image reader, or
  1018. * null if reader is not registered or if no corresponding writer is
  1019. * registered. This method is useful for preserving metadata
  1020. * without needing to understand its format, since the returned
  1021. * writer will be able to write, unchanged, the metadata passed to
  1022. * it by the reader.
  1023. *
  1024. * @param reader a registered image reader
  1025. *
  1026. * @return an image writer corresponding to reader, or null
  1027. *
  1028. * @exception IllegalArgumentException if reader is null
  1029. */
  1030. public static ImageWriter getImageWriter (ImageReader reader)
  1031. {
  1032. if (reader == null)
  1033. throw new IllegalArgumentException ("null argument");
  1034. ImageReaderSpi spi = reader.getOriginatingProvider();
  1035. String[] writerSpiNames = spi.getImageWriterSpiNames();
  1036. ImageWriter w = null;
  1037. if (writerSpiNames != null)
  1038. {
  1039. try
  1040. {
  1041. Class writerClass = Class.forName (writerSpiNames[0]);
  1042. w = (ImageWriter) writerClass.newInstance ();
  1043. }
  1044. catch (Exception e)
  1045. {
  1046. return null;
  1047. }
  1048. }
  1049. return w;
  1050. }
  1051. /**
  1052. * Retrieve an iterator over a collection of image transcoders that
  1053. * support transcoding from the given image reader's metadata format
  1054. * to the given writer's metadata format.
  1055. *
  1056. * @param reader an image reader
  1057. * @param writer an image writer
  1058. *
  1059. * @return an iterator over a collection of image transcoders
  1060. *
  1061. * @exception IllegalArgumentException if either reader or writer is
  1062. * null
  1063. */
  1064. public static Iterator<ImageTranscoder> getImageTranscoders (ImageReader reader,
  1065. ImageWriter writer)
  1066. {
  1067. if (reader == null || writer == null)
  1068. throw new IllegalArgumentException ("null argument");
  1069. final Iterator<ImageTranscoderSpi> spiIterator
  1070. = getRegistry().getServiceProviders (ImageTranscoderSpi.class,
  1071. new TranscoderFilter (reader,
  1072. writer),
  1073. true);
  1074. return new Iterator<ImageTranscoder>()
  1075. {
  1076. public boolean hasNext()
  1077. {
  1078. return spiIterator.hasNext();
  1079. }
  1080. public ImageTranscoder next()
  1081. {
  1082. return spiIterator.next().createTranscoderInstance();
  1083. }
  1084. public void remove()
  1085. {
  1086. throw new UnsupportedOperationException();
  1087. }
  1088. };
  1089. }
  1090. }