code: public static Dimension readImageSize(byte[] bytes) {
          ByteArrayInputStream in = new ByteArrayInputStream(bytes);
          ImageInfo ii = new ImageInfo();
          ii.setInput(in);
          if (ii.check()) {
              return new Dimension(ii.getWidth(), ii.getHeight());
          } else {
              in.reset();
              BufferedImage image;
              try {
                  image = ImageIO.read(in);
                  if (image == null) {
                      throw new IOException("failed to read image; format is probably not supported");
                  }
                  return new Dimension(image.getWidth(), image.getHeight());
              } catch (IOException ex) {
                  Integer m1 = bytes.length > 0 ? Integer.valueOf(bytes[0]) : null;
                  Integer m2 = bytes.length > 1 ? Integer.valueOf(bytes[1]) : null;
                  Logger.getLogger(ImageInfos.class.getName())
                          .log(Level.FINER, "reading image failed on array of "
                                  + "length {0} with magic number {1} {2}: {3}", 
                                  new Object[]{bytes.length, m1, m2, ex});
                  return new Dimension(0, 0);
              }
          }
      }
docs: Reads the image size from a byte array containing image data. This
  first attempts to use {@link ImageInfo} to read just the header data,
  but if that fails the whole image is buffered into memory with
  {@link ImageIO#read(java.io.InputStream) }. In any case, this method
  never throws an exception; instead, if the image data is unreadable,
  it returns a dimension object with zero width and height.
  
  <p>In common deployments, the fallback of loading the image into
  memory probably never works, because {@code ImageInfo}'s support is
  a superset of JDK image format support. But some installations may
  have extra codecs installed, and it's nice to make use of those if
  they're there.
  @param bytes the image data bytes
  @return the image dimensions