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   
7   import javax.imageio.ImageIO;
8   import javax.imageio.ImageReadParam;
9   import javax.imageio.ImageReader;
10  import javax.imageio.ImageTypeSpecifier;
11  import javax.imageio.stream.ImageInputStream;
12  import java.awt.image.BufferedImage;
13  import java.io.IOException;
14  import java.io.InputStream;
15  import java.util.Iterator;
16  
17  /**
18   * This is a workaround for JDK bug:
19   * http://bugs.sun.com/view_bug.do?bug_id=4884308
20   * "IllegalArgExptn thrown when reading image using TYPE_BYTE_GRAY after TYPE_CUSTOM"
21   * <p/>
22   * Such image will be loaded Black-and-white instead of not being loaded at all.
23   */
24  class FixedImageLoader implements ImageLoader
25  {
26  
27      @Override
28      public Optional<BufferedImage> loadImage(final InputStream inputStream, ImageInfo imageInfo) throws IOException
29      {
30          ImageInputStream imageInputStream = null;
31          BufferedImage bufferedImage = null;
32          Exception lastException = null;
33          try
34          {
35              inputStream.reset();
36              imageInputStream = ImageIO.createImageInputStream(inputStream);
37              final Iterator<ImageReader> imageReaders = ImageIO.getImageReadersByFormatName("JPEG");
38  
39              while (imageReaders.hasNext())
40              {
41                  ImageReader reader = null;
42                  try
43                  {
44                      reader = imageReaders.next();
45                      reader.setInput(imageInputStream);
46  
47                      bufferedImage = reader.read(0, getFixedReadParam(reader));
48                      if (null != bufferedImage) break;
49                  }
50                  catch (Exception e)
51                  {
52                      lastException = e;
53                  }
54                  finally
55                  {
56                      if (null != reader)
57                          reader.dispose();
58                  }
59              }
60          }
61          finally
62          {
63              if (imageInputStream != null)
64                  imageInputStream.close();
65          }
66          if(bufferedImage == null)
67          {
68              Throwables.propagateIfInstanceOf(lastException, IOException.class);
69              throw new IOException(lastException);
70          }
71          return Optional.of(bufferedImage);
72      }
73  
74      private ImageReadParam getFixedReadParam(final ImageReader reader) throws IOException
75      {
76          ImageReadParam param = reader.getDefaultReadParam();
77          Iterator<ImageTypeSpecifier> imageTypes = reader.getImageTypes(0);
78          while (imageTypes.hasNext())
79          {
80              ImageTypeSpecifier imageTypeSpecifier = imageTypes.next();
81              int bufferedImageType = imageTypeSpecifier.getBufferedImageType();
82              if (bufferedImageType == BufferedImage.TYPE_BYTE_GRAY)
83              {
84                  param.setDestinationType(imageTypeSpecifier);
85                  break;
86              }
87          }
88          return param;
89      }
90  }