View Javadoc

1   package com.atlassian.core.util.thumbnail.loader;
2   
3   import com.atlassian.core.util.ImageInfo;
4   import com.google.common.base.Optional;
5   import com.google.common.base.Throwables;
6   import com.sun.media.jai.codec.SeekableStream;
7   import org.apache.commons.io.IOUtils;
8   
9   import javax.media.jai.JAI;
10  import javax.media.jai.OpImage;
11  import javax.media.jai.PlanarImage;
12  import javax.media.jai.RenderedOp;
13  import java.awt.image.BufferedImage;
14  import java.io.IOException;
15  import java.io.InputStream;
16  
17  class JAIImageLoader implements ImageLoader
18  {
19  
20      @Override
21      public Optional<BufferedImage> loadImage(final InputStream inputStream, ImageInfo imageInfo) throws IOException
22      {
23          if(imageInfo != null && imageInfo.getFormat() == ImageInfo.FORMAT_PNG)
24          {
25              // JAI has some issues with PNG files(JRA-35816) and we use JAI, because of CMYK JPEGs (JRA-20072)
26              // so it's safe to disable this loader for PNGs
27              throw new IOException("PNG format is not supported by JAIImageLoader");
28          }
29  
30          SeekableStream seekableStream = null;
31          RenderedOp img = null;
32          try
33          {
34              seekableStream = SeekableStream.wrapInputStream(inputStream, true);
35              img = JAI.create("stream", seekableStream);
36              if (img == null)
37                  return Optional.absent();
38              removeTileCache(img);
39              return Optional.fromNullable(img.getAsBufferedImage());
40          }
41          catch (Exception e)
42          {
43              //JAI throws RuntimeExceptions when image is corrupted, we need to wrap them
44  			Throwables.propagateIfInstanceOf(e, IOException.class);
45              throw new IOException(e);
46          }
47          finally
48          {
49              IOUtils.closeQuietly(seekableStream);
50              if(img != null)
51              {
52                  img.dispose();
53              }
54          }
55      }
56  
57      /**
58       * We don't want to cache image tiles in memory.
59       */
60      private void removeTileCache(final RenderedOp img)
61      {
62          final PlanarImage imgRendering = img.getRendering();
63          if (imgRendering instanceof OpImage)
64          {
65              ((OpImage) imgRendering).setTileCache(null);
66          }
67      }
68  }