docs: public byte[] generateThumbnail(
          InputStream pdfInputStream,
          int boxWidth,
          int boxHeight,
          String imageFormat,
          int pageIndex) throws Exception {
  
          org.jpedal.io.ObjectStore.temp_dir = CmsFileUtil.normalizePath(
              OpenCms.getSystemInfo().getWebInfRfsPath() + CmsPdfThumbnailCache.PDF_CACHE_FOLDER + File.separatorChar);
          PdfDecoder decoder = new PdfDecoder(true);
  
          try {
              decoder.openPdfFileFromInputStream(pdfInputStream, false);
              int numPages = decoder.getPageCount();
              if (pageIndex >= numPages) {
                  pageIndex = numPages - 1;
              } else if (pageIndex < 0) {
                  pageIndex = 0;
              }
  
              // width/height are in points (1/72 of an inch)
              PdfPageData pageData = decoder.getPdfPageData();
              double aspectRatio = (pageData.getCropBoxWidth(1 + pageIndex) * 1.0)
                  / pageData.getCropBoxHeight(1 + pageIndex);
              int rotation = pageData.getRotation(1 + pageIndex);
              if ((rotation == 90) || (rotation == 270)) {
                  // landscape
                  aspectRatio = 1 / aspectRatio;
              }
  
              if ((boxWidth < 0) && (boxHeight < 0)) {
                  throw new IllegalArgumentException("At least one of width / height must be positive!");
              } else if ((boxWidth < 0) && (boxHeight > 0)) {
                  boxWidth = (int)Math.round(aspectRatio * boxHeight);
              } else if ((boxWidth > 0) && (boxHeight < 0)) {
                  boxHeight = (int)Math.round(boxWidth / aspectRatio);
              }
  
              // calculateDimensions only takes integers, but only their ratio matters, we multiply the box width with a big number
              int fakePixelWidth = (int)(FAKE_PIXEL_MULTIPLIER * aspectRatio);
              int fakePixelHeight = (FAKE_PIXEL_MULTIPLIER);
              int[] unpaddedThumbnailDimensions = CmsImageScaler.calculateDimension(
                  fakePixelWidth,
                  fakePixelHeight,
                  boxWidth,
                  boxHeight);
              decoder.decodePage(1 + pageIndex);
              BufferedImage pageImage = decoder.getPageAsImage(1 + pageIndex);
              BufferedImage paddedImage = new BufferedImage(boxWidth, boxHeight, BufferedImage.TYPE_3BYTE_BGR);
  
              Graphics2D g = paddedImage.createGraphics();
              int uw = unpaddedThumbnailDimensions[0];
              int uh = unpaddedThumbnailDimensions[1];
  
              // Scale to fit in  the box
              AffineTransformOp op = new AffineTransformOp(
                  AffineTransform.getScaleInstance((uw * 1.0) / pageImage.getWidth(), (uh * 1.0) / pageImage.getHeight()),
                  AffineTransformOp.TYPE_BILINEAR);
  
              g.setColor(Color.WHITE);
              // Fill box image with white, then draw the image data for the PDF in the middle
              g.fillRect(0, 0, paddedImage.getWidth(), paddedImage.getHeight());
              //g.drawImage(pageImage, (boxWidth - pageImage.getWidth()) / 2, (boxHeight - pageImage.getHeight()) / 2, null);
              g.drawImage(pageImage, op, (boxWidth - uw) / 2, (boxHeight - uh) / 2);
              BufferedImage pageThumbnail = paddedImage;
              ByteArrayOutputStream out = new ByteArrayOutputStream();
              ImageIOUtil.writeImage(pageThumbnail, imageFormat, out);
              byte[] imageData = out.toByteArray();
              return imageData;
          } finally {
              if (decoder.isOpen()) {
                  decoder.closePdfFile();
              }
              pdfInputStream.close();
  
          }
      }