docs: public static BufferedImage getDestination(final ImageReadParam param, final Iterator<ImageTypeSpecifier> types,
                                                 final int width, final int height) throws IIOException {
          // Adapted from http://java.net/jira/secure/attachment/29712/TIFFImageReader.java.patch,
          // to allow reading parts/tiles of huge images.
  
          if (types == null || !types.hasNext()) {
              throw new IllegalArgumentException("imageTypes null or empty!");
          }
  
          ImageTypeSpecifier imageType = null;
  
          // If param is non-null, use it
          if (param != null) {
              // Try to get the explicit destination image
              BufferedImage dest = param.getDestination();
  
              if (dest != null) {
                  boolean found = false;
  
                  while (types.hasNext()) {
                      ImageTypeSpecifier specifier = types.next();
                      int bufferedImageType = specifier.getBufferedImageType();
  
                      if (bufferedImageType != 0 && bufferedImageType == dest.getType()) {
                          // Known types equal, perfect match
                          found = true;
                          break;
                      }
                      else {
                          // If types are different, or TYPE_CUSTOM, test if
                          // - transferType is ok
                          // - bands are ok
                          // TODO: Test if color model is ok?
                          if (specifier.getSampleModel().getTransferType() == dest.getSampleModel().getTransferType() &&
                                  specifier.getNumBands() <= dest.getSampleModel().getNumBands()) {
                              found = true;
                              break;
                          }
                      }
                  }
  
                  if (!found) {
                      throw new IIOException(String.format("Destination image from ImageReadParam does not match legal imageTypes from reader: %s", dest));
                  }
  
                  return dest;
              }
  
              // No image, get the image type
              imageType = param.getDestinationType();
          }
  
          // No info from param, use fallback image type
          if (imageType == null) {
              imageType = types.next();
          }
          else {
              boolean foundIt = false;
  
              while (types.hasNext()) {
                  ImageTypeSpecifier type = types.next();
  
                  if (type.equals(imageType)) {
                      foundIt = true;
                      break;
                  }
              }
  
              if (!foundIt) {
                  throw new IIOException(String.format("Destination type from ImageReadParam does not match legal imageTypes from reader: %s", imageType));
              }
          }
  
          Rectangle srcRegion = new Rectangle(0, 0, 0, 0);
          Rectangle destRegion = new Rectangle(0, 0, 0, 0);
          computeRegions(param, width, height, null, srcRegion, destRegion);
  
          int destWidth = destRegion.x + destRegion.width;
          int destHeight = destRegion.y + destRegion.height;
  
          if ((long) destWidth * destHeight > Integer.MAX_VALUE) {
              throw new IllegalArgumentException(String.format("destination width * height > Integer.MAX_VALUE: %d", (long) destWidth * destHeight));
          }
  
          // Create a new image based on the type specifier
          return imageType.createBufferedImage(destWidth, destHeight);
      }