Source for javax.imageio.ImageIO

   1: /* ImageIO.java --
   2:    Copyright (C) 2004, 2005  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package javax.imageio;
  40: 
  41: import java.awt.image.BufferedImage;
  42: import java.awt.image.RenderedImage;
  43: import java.io.File;
  44: import java.io.FileInputStream;
  45: import java.io.FileOutputStream;
  46: import java.io.IOException;
  47: import java.io.InputStream;
  48: import java.io.OutputStream;
  49: import java.net.URL;
  50: import java.util.ArrayList;
  51: import java.util.Collections;
  52: import java.util.Iterator;
  53: 
  54: import javax.imageio.spi.IIORegistry;
  55: import javax.imageio.spi.ImageReaderSpi;
  56: import javax.imageio.spi.ImageWriterSpi;
  57: import javax.imageio.spi.ServiceRegistry;
  58: import javax.imageio.stream.ImageInputStream;
  59: import javax.imageio.stream.ImageOutputStream;
  60: import javax.imageio.stream.MemoryCacheImageInputStream;
  61: import javax.imageio.stream.MemoryCacheImageOutputStream;
  62: 
  63: public final class ImageIO
  64: {
  65:   /**
  66:    * This class isn't intended to be instantiated.
  67:    */
  68:   private ImageIO() {}
  69: 
  70:   private static final class ReaderFormatFilter implements ServiceRegistry.Filter
  71:   {
  72:     private String formatName;
  73: 
  74:     public ReaderFormatFilter(String formatName)
  75:     {
  76:       this.formatName = formatName;
  77:     }
  78: 
  79:     public boolean filter (Object provider)
  80:     {
  81:       if (provider instanceof ImageReaderSpi)
  82:         {
  83:           ImageReaderSpi spi = (ImageReaderSpi) provider;
  84:           String[] formatNames = spi.getFormatNames();
  85: 
  86:           for (int i = formatNames.length - 1; i >= 0; --i)
  87:             if (formatName.equals(formatNames[i]))
  88:               return true;
  89:         }
  90: 
  91:       return false;
  92:     }
  93:   }
  94: 
  95:   private static final class ReaderMIMETypeFilter implements ServiceRegistry.Filter
  96:   {
  97:     private String MIMEType;
  98: 
  99:     public ReaderMIMETypeFilter(String MIMEType)
 100:     {
 101:       this.MIMEType = MIMEType;
 102:     }
 103: 
 104:     public boolean filter(Object provider)
 105:     {
 106:       if (provider instanceof ImageReaderSpi)
 107:         {
 108:           ImageReaderSpi spi = (ImageReaderSpi) provider;
 109:           String[] mimetypes = spi.getMIMETypes();
 110: 
 111:           for (int i = mimetypes.length - 1; i >= 0; --i)
 112:             if (MIMEType.equals(mimetypes[i]))
 113:               return true;
 114:         }
 115: 
 116:       return false;
 117:     }
 118:   }
 119:   
 120:   private static final class ReaderSuffixFilter implements ServiceRegistry.Filter
 121:   {
 122:     private String fileSuffix;
 123: 
 124:     public ReaderSuffixFilter(String fileSuffix)
 125:     {
 126:       this.fileSuffix = fileSuffix;
 127:     }
 128: 
 129:     public boolean filter(Object provider)
 130:     {
 131:       if (provider instanceof ImageReaderSpi)
 132:         {
 133:           ImageReaderSpi spi = (ImageReaderSpi) provider;
 134:           String[] suffixes = spi.getFileSuffixes();
 135: 
 136:           for (int i = suffixes.length - 1; i >= 0; --i)
 137:             if (fileSuffix.equals(suffixes[i]))
 138:               return true;
 139:         }
 140: 
 141:       return false;
 142:     }
 143:   }
 144:   
 145:   private static final class WriterFormatFilter implements ServiceRegistry.Filter
 146:   {
 147:     private String formatName;
 148: 
 149:     public WriterFormatFilter(String formatName)
 150:     {
 151:       this.formatName = formatName;
 152:     }
 153: 
 154:     public boolean filter(Object provider)
 155:     {
 156:       if (provider instanceof ImageWriterSpi)
 157:     {
 158:       ImageWriterSpi spi = (ImageWriterSpi) provider;
 159:       String[] formatNames = spi.getFormatNames();
 160:       
 161:       for (int i = formatNames.length - 1; i >= 0; --i)
 162:             if (formatName.equals(formatNames[i]))
 163:               return true;
 164:     }
 165: 
 166:       return false;
 167:     }
 168:   }
 169: 
 170:   private static final class WriterMIMETypeFilter implements ServiceRegistry.Filter
 171:   {
 172:     private String MIMEType;
 173: 
 174:     public WriterMIMETypeFilter(String MIMEType)
 175:     {
 176:       this.MIMEType = MIMEType;
 177:     }
 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: 
 186:           for (int i = mimetypes.length - 1; i >= 0; --i)
 187:             if (MIMEType.equals(mimetypes[i]))
 188:               return true;
 189:         }
 190: 
 191:       return false;
 192:     }
 193:   }
 194:   
 195:   private static final class WriterSuffixFilter implements ServiceRegistry.Filter
 196:   {
 197:     private String fileSuffix;
 198: 
 199:     public WriterSuffixFilter(String fileSuffix)
 200:     {
 201:       this.fileSuffix = fileSuffix;
 202:     }
 203: 
 204:     public boolean filter(Object provider)
 205:     {
 206:       if (provider instanceof ImageWriterSpi)
 207:         {
 208:           ImageWriterSpi spi = (ImageWriterSpi) provider;
 209:           String[] suffixes = spi.getFileSuffixes();
 210: 
 211:           for (int i = suffixes.length - 1; i >= 0; --i)
 212:             if (fileSuffix.equals(suffixes[i]))
 213:               return true;
 214:         }
 215: 
 216:       return false;
 217:     }
 218:   }
 219: 
 220:   private static final class ImageReaderIterator implements Iterator
 221:   {
 222:     Iterator it;
 223:     Object readerExtension;
 224:     
 225:     public ImageReaderIterator(Iterator it, Object readerExtension)
 226:     {
 227:       this.it = it;
 228:       this.readerExtension = readerExtension;
 229:     }
 230: 
 231:     public boolean hasNext()
 232:     {
 233:       return it.hasNext();
 234:     }
 235: 
 236:     public Object next()
 237:     {
 238:       try
 239:         {
 240:           return ((ImageReaderSpi) it.next()).createReaderInstance(readerExtension);
 241:         }
 242:       catch (IOException e)
 243:         {
 244:           return null;
 245:         }
 246:     }
 247: 
 248:     public void remove()
 249:     {
 250:       throw new UnsupportedOperationException();
 251:     }
 252:   }
 253: 
 254:   private static final class ImageWriterIterator implements Iterator
 255:   {
 256:     Iterator it;
 257:     Object writerExtension;
 258:     
 259:     public ImageWriterIterator(Iterator it, Object writerExtension)
 260:     {
 261:       this.it = it;
 262:       this.writerExtension = writerExtension;
 263:     }
 264: 
 265:     public boolean hasNext()
 266:     {
 267:       return it.hasNext();
 268:     }
 269: 
 270:     public Object next()
 271:     {
 272:       try
 273:         {
 274:           return ((ImageWriterSpi) it.next()).createWriterInstance(writerExtension);
 275:         }
 276:       catch (IOException e)
 277:         {
 278:           return null;
 279:         }
 280:     }
 281: 
 282:     public void remove()
 283:     {
 284:       throw new UnsupportedOperationException();
 285:     }
 286:   }
 287:   
 288:   private static File cacheDirectory;
 289:   private static boolean useCache = true;
 290: 
 291:   private static Iterator getReadersByFilter(Class type,
 292:                                              ServiceRegistry.Filter filter,
 293:                                              Object readerExtension)
 294:   {
 295:     try
 296:       {
 297:         Iterator it = getRegistry().getServiceProviders(type, filter, true);
 298:         return new ImageReaderIterator(it, readerExtension);
 299:       }
 300:     catch (IllegalArgumentException e)
 301:       {
 302:         return Collections.EMPTY_SET.iterator();
 303:       }
 304:   }
 305:   
 306:   private static Iterator getWritersByFilter(Class type,
 307:                          ServiceRegistry.Filter filter,
 308:                                              Object writerExtension)
 309:   {
 310:     try
 311:       {
 312:         Iterator it = getRegistry().getServiceProviders(type, filter, true);
 313:         return new ImageWriterIterator(it, writerExtension);
 314:       }
 315:     catch (IllegalArgumentException e)
 316:       {
 317:         return Collections.EMPTY_SET.iterator();
 318:       }
 319:   }
 320: 
 321:   public static File getCacheDirectory()
 322:   {
 323:     return cacheDirectory;
 324:   }
 325: 
 326:   public static Iterator getImageReadersByFormatName(String formatName)
 327:   {
 328:     if (formatName == null)
 329:       throw new IllegalArgumentException("formatName may not be null");
 330: 
 331:     return getReadersByFilter(ImageReaderSpi.class,
 332:                               new ReaderFormatFilter(formatName),
 333:                               formatName);
 334:   }
 335: 
 336:   public static Iterator getImageReadersByMIMEType(String MIMEType)
 337:   {
 338:     if (MIMEType == null)
 339:       throw new IllegalArgumentException("MIMEType may not be null");
 340: 
 341:     return getReadersByFilter(ImageReaderSpi.class,
 342:                               new ReaderMIMETypeFilter(MIMEType),
 343:                               MIMEType);
 344:   }
 345: 
 346:   public static Iterator getImageReadersBySuffix(String fileSuffix)
 347:   {
 348:     if (fileSuffix == null)
 349:       throw new IllegalArgumentException("formatName may not be null");
 350:     
 351:     return getReadersByFilter(ImageReaderSpi.class,
 352:                               new ReaderSuffixFilter(fileSuffix),
 353:                               fileSuffix);
 354:   }
 355: 
 356:   public static Iterator getImageWritersByFormatName(String formatName)
 357:   {
 358:     if (formatName == null)
 359:       throw new IllegalArgumentException("formatName may not be null");
 360:     
 361:     return getWritersByFilter(ImageWriterSpi.class,
 362:                               new WriterFormatFilter(formatName),
 363:                               formatName);
 364:   }
 365: 
 366:   public static Iterator getImageWritersByMIMEType(String MIMEType)
 367:   {
 368:     if (MIMEType == null)
 369:       throw new IllegalArgumentException("MIMEType may not be null");
 370:     
 371:     return getWritersByFilter(ImageWriterSpi.class,
 372:                               new WriterMIMETypeFilter(MIMEType),
 373:                               MIMEType);
 374:   }
 375: 
 376:   public static Iterator getImageWritersBySuffix(String fileSuffix)
 377:   {
 378:     if (fileSuffix == null)
 379:       throw new IllegalArgumentException("fileSuffix may not be null");
 380:     
 381:     return getWritersByFilter(ImageWriterSpi.class,
 382:                               new WriterSuffixFilter(fileSuffix),
 383:                               fileSuffix);
 384:   }
 385: 
 386:   public static String[] getReaderFormatNames()
 387:   {
 388:     try
 389:       {
 390:         Iterator it =
 391:       getRegistry().getServiceProviders(ImageReaderSpi.class, true);
 392:     ArrayList result = new ArrayList();
 393: 
 394:     while (it.hasNext())
 395:       {
 396:         ImageReaderSpi spi = (ImageReaderSpi) it.next();
 397:         String[] names = spi.getFormatNames();
 398: 
 399:         for (int i = names.length - 1; i >= 0; --i)
 400:           result.add(names[i]);
 401:       }
 402: 
 403:     return (String[]) result.toArray(new String[result.size()]);
 404:       }
 405:     catch (IllegalArgumentException e)
 406:       {
 407:         return new String[0];
 408:       }
 409:   }
 410: 
 411:   public static String[] getReaderMIMETypes()
 412:   {
 413:     try
 414:       {
 415:         Iterator it =
 416:       getRegistry().getServiceProviders(ImageReaderSpi.class, true);
 417:     ArrayList result = new ArrayList();
 418: 
 419:     while (it.hasNext())
 420:       {
 421:         ImageReaderSpi spi = (ImageReaderSpi) it.next();
 422:         String[] names = spi.getMIMETypes();
 423: 
 424:         for (int i = names.length - 1; i >= 0; --i)
 425:           result.add(names[i]);
 426:       }
 427: 
 428:     return (String[]) result.toArray(new String[result.size()]);
 429:       }
 430:     catch (IllegalArgumentException e)
 431:       {
 432:         return new String[0];
 433:       }
 434:   }
 435: 
 436:   private static IIORegistry getRegistry()
 437:   {
 438:     return IIORegistry.getDefaultInstance();
 439:   }
 440: 
 441:   public static boolean getUseCache()
 442:   {
 443:     return useCache;
 444:   }
 445: 
 446:   public static String[] getWriterFormatNames()
 447:   {
 448:     try
 449:       {
 450:         Iterator it =
 451:       getRegistry().getServiceProviders(ImageWriterSpi.class, true);
 452:     ArrayList result = new ArrayList();
 453: 
 454:     while (it.hasNext())
 455:       {
 456:         ImageWriterSpi spi = (ImageWriterSpi) it.next();
 457:         String[] names = spi.getFormatNames();
 458: 
 459:         for (int i = names.length - 1; i >= 0; --i)
 460:           result.add(names[i]);
 461:       }
 462: 
 463:     return (String[]) result.toArray(new String[result.size()]);
 464:       }
 465:     catch (IllegalArgumentException e)
 466:       {
 467:         return new String[0];
 468:       }
 469:   }
 470: 
 471:   public static String[] getWriterMIMETypes()
 472:   {
 473:     try
 474:       {
 475:         Iterator it =
 476:       getRegistry().getServiceProviders(ImageWriterSpi.class, true);
 477:     ArrayList result = new ArrayList();
 478: 
 479:     while (it.hasNext())
 480:       {
 481:         ImageWriterSpi spi = (ImageWriterSpi) it.next();
 482:         String[] names = spi.getMIMETypes();
 483: 
 484:         for (int i = names.length - 1; i >= 0; --i)
 485:           result.add(names[i]);
 486:       }
 487: 
 488:     return (String[]) result.toArray(new String[result.size()]);
 489:       }
 490:     catch (IllegalArgumentException e)
 491:       {
 492:         return new String[0];
 493:       }
 494:   }
 495:   
 496:   /**
 497:    * Rescans the application classpath for ImageIO service providers
 498:    * and registers them.
 499:    */
 500:   public static void scanForPlugins()
 501:   {
 502:     IIORegistry.getDefaultInstance().registerApplicationClasspathSpis();
 503:   }
 504: 
 505:   public static void setCacheDirectory(File cacheDirectory)
 506:   {
 507:     if (cacheDirectory != null)
 508:       {
 509:         if (!cacheDirectory.isDirectory())
 510:           throw new IllegalArgumentException("cacheDirectory must be a directory");
 511: 
 512:         cacheDirectory.canWrite();
 513:       }
 514:     
 515:     ImageIO.cacheDirectory = cacheDirectory;
 516:   }
 517: 
 518:   public static void setUseCache(boolean useCache)
 519:   {
 520:     ImageIO.useCache = useCache;
 521:   }
 522: 
 523:   /* 
 524:    * "Standard" simplified entry points.
 525:    */
 526: 
 527:   public static boolean write(RenderedImage im,
 528:                               String formatName,
 529:                               File output)
 530:     throws IOException
 531:   {
 532:     return write(im, formatName, new FileOutputStream(output));
 533:   }
 534: 
 535:   public static boolean write(RenderedImage im,
 536:                               String formatName,
 537:                               OutputStream output)
 538:     throws IOException
 539:   {
 540:     return write(im, formatName, new MemoryCacheImageOutputStream(output));
 541:   }
 542:   
 543:   
 544:   public static boolean write(RenderedImage im,
 545:                               String formatName,
 546:                               ImageOutputStream output)
 547:     throws IOException
 548:   {
 549:     Iterator writers = getImageWritersByFormatName(formatName);
 550:     IIOImage img = new IIOImage(im, null, null);
 551:     while (writers.hasNext())
 552:       {
 553:         ImageWriter w = (ImageWriter) writers.next();
 554:         try 
 555:           {
 556:             w.setOutput(output);
 557:           }
 558:         catch (IllegalArgumentException e)
 559:           {
 560:             continue;
 561:           }
 562:         
 563:         w.write(null, img, null);
 564:         output.close();
 565:         return true;
 566:       }
 567:     return false;
 568:   }
 569: 
 570:   public static BufferedImage read(ImageInputStream stream)
 571:     throws IOException
 572:   {
 573:     Iterator providers = getRegistry().getServiceProviders(ImageReaderSpi.class, true);
 574:     while (providers.hasNext())
 575:       {
 576:         ImageReaderSpi spi = (ImageReaderSpi) providers.next();
 577:         if (spi.canDecodeInput(stream))
 578:           {
 579:             ImageReader reader = spi.createReaderInstance();
 580:             reader.setInput(stream);
 581:             return reader.read(0, null);
 582:           }
 583:       }
 584:     return null;
 585:   }
 586:         
 587:   public static BufferedImage read(URL input)
 588:     throws IOException
 589:   {
 590:     return read(input.openStream());
 591:   }
 592: 
 593:   public static BufferedImage read(InputStream input)
 594:     throws IOException
 595:   {
 596:     return read(new MemoryCacheImageInputStream(input));
 597:   }
 598: 
 599:   public static BufferedImage read(File input)
 600:     throws IOException
 601:   {
 602:     return read(new FileInputStream(input));
 603:   }
 604: 
 605: }