Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7031957

DIB header of type BITMAPV2INFOHEADER & BITMAPV3INFOHEADER is not supported in BMPImageReader

    Details

    • Type: Enhancement
    • Status: Resolved
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 7, 8, 9, 10
    • Fix Version/s: 11
    • Component/s: client-libs
    • Subcomponent:
    • Resolved In Build:
      b07
    • CPU:
      generic
    • OS:
      generic

      Description

      A DESCRIPTION OF THE REQUEST :
      Both Adobe Photoshop and the GIMP are capable of creating 32-bit Windows Bitmap (.bmp) files with 8-8-8-8 RGBA bitfield encoding, which cannot be read by the ImageIO utilities in the latest release (March 24, 2011) of the JDK preview, nor current releases of JDK 6. If one attempts to load one of these images with ImageIO.read(File file), a "java.lang.RuntimeException: New BMP version not implemented yet" is thrown.

      Such an image can be created in GIMP 2.7.1 or 2.6.11 by creating an image, and then choosing Save As (2.6.11) or Export (2.7.1) from the file menu, typing in a name with a .bmp extension, hitting "Save"/"Export", and then choosing Advanced Options. The 32 bits -> X8 R8 G8 B8 option must be selected, and the image then finally saved/exported.

      JUSTIFICATION :
      As at least two major photo editing programs support this variant of the bitmap format, it likely will at least occasionally occur that Java users will try to open such files and receive this exception. It would preferable to have native support for a wider range of bitmap formats, especially as current versions of these popular programs are capable of creating these files.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I would like to see Java be able to read a BufferedImage from such files using a single invocation of ImageIO.read(File file).
      ACTUAL -
      Instead, an error is printed:
       java.lang.RuntimeException: New BMP version not implemented yet.
      at com.sun.imageio.plugins.bmp.BMPImageReader.readHeader(BMPImageReader.java:480)
      at com.sun.imageio.plugins.bmp.BMPImageReader.read(BMPImageReader.java:708)
      at javax.imageio.ImageIO.read(ImageIO.java:1448)
      at javax.imageio.ImageIO.read(ImageIO.java:1308)

      ---------- BEGIN SOURCE ----------
      import java.awt.Dimension;
      import java.awt.Graphics;
      import java.awt.GridBagConstraints;
      import java.awt.GridBagLayout;
      import java.awt.Image;
      import java.awt.image.BufferedImage;
      import java.io.File;
      import java.io.IOException;
      import javax.imageio.ImageIO;
      import javax.swing.JFileChooser;
      import javax.swing.JFrame;
      import javax.swing.JMenu;
      import javax.swing.JMenuBar;
      import javax.swing.JMenuItem;
      import javax.swing.JPanel;
      import javax.swing.JScrollPane;
      import javax.swing.filechooser.FileNameExtensionFilter;
      //Minimal image viewer - will correctly display 'standard' bitmaps with imageio
      public class Main extends JFrame {
      javax.swing.JMenuBar menuBar = new JMenuBar();
      JMenu fileMenu = new JMenu("File");
      JMenuItem open = new JMenuItem("Open");
      IconPanel pnlImageViewer = new IconPanel();
      JScrollPane scrollBar = new JScrollPane();
      JFileChooser jFileChooser1 = new JFileChooser();

      BufferedImage image = null;

          public Main()
          {
              System.out.println(System.getProperty("java.version"));
              setTitle("Bitmap Viewer");
              open.addActionListener(new java.awt.event.ActionListener()
              {
                  public void actionPerformed(java.awt.event.ActionEvent evt)
                  {
                      int response = jFileChooser1.showOpenDialog(null);
                      if (response == JFileChooser.APPROVE_OPTION)
                      {
                          String fileName = "";
                          try{
                              fileName = jFileChooser1.getSelectedFile().getCanonicalPath();
                              image = ImageIO.read(new File(fileName));
                              pnlImageViewer.setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
                              pnlImageViewer.revalidate();
                              pnlImageViewer.setImage(image);
                          }
                          catch(IOException e)
                          {
                              System.out.println("IOException: " + e);
                          }
                          pnlImageViewer.setImage(image);
                          Graphics gphx = pnlImageViewer.getGraphics();
                          pnlImageViewer.update(gphx);
                          gphx.dispose();
                      }
                  }
              });
              fileMenu.add(open);
              menuBar.add(fileMenu);

              this.setJMenuBar(menuBar);

              GridBagConstraints g = new GridBagConstraints();
              g.gridx = g.gridy = 0;
              g.weightx = g.weighty = 1;
              g.fill = GridBagConstraints.BOTH;
              scrollBar = new JScrollPane(pnlImageViewer);
              getContentPane().setLayout(new GridBagLayout());
              getContentPane().add(scrollBar, g);
              pnlImageViewer.setVisible(true);
              pack();
              
              FileNameExtensionFilter wbmFilter = new FileNameExtensionFilter("Windows Bitmaps", "bmp");
              jFileChooser1.setFileFilter(wbmFilter);

              setSize(new Dimension(640, 480));
              this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          }
          public static void main(String[] args) {
              new Main().setVisible(true);
          }
          
          public class IconPanel extends JPanel{
              Image myImage;
              public void setImage(Image image)
              {
                  myImage = image;
              }
              public void paint(Graphics g)
              {
                  super.paint(g);
                  if (this.isVisible())
                  {
                      if (g!= null && myImage != null)
                          g.drawImage(myImage, 0, 0, null);
                  }
              }
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      It's possible to write one's own class to read in bitmap files, including this type, and convert them into BufferedImages. However this requires detailed knowledge of the BMP format.

      The root of the problem seems to be that BMPImageReader.java in the com.sun.imageio.plugins.bmp package requires the size of the bitmap header to be either 40 bytes (Windows 3.x bitmap) or 108/124 bytes (Windows 4.x bitmaps). GIMP and Photoshop both list the bitmap header size of these images as 56 bytes. The header, thus, is conceptually the same thing as the Windows 3.x bitmap header with bitfield encoding (which specifies an extra 12 bytes are red for the bitfield masks - this is also known as the Windows 3.x NT header), plus four extra bytes for the alpha mask. It can also be thought of as a Windows 4.x header where only the first 56 bytes are specified, and the others (declared and initialized in lines 393-405 of BMPImageReader.java) revert to their 'default' values.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                jdv Jayathirth D V
                Reporter:
                webbuggrp Webbug Group
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: