Skip to content

Conversation

JorisJ1
Copy link
Contributor

@JorisJ1 JorisJ1 commented Jun 9, 2019

In the code below two methods are shown to add a WMF image to the document. The first method creates the WmfImage from a filepath, the second from a byte array from the same file. Both should work, but the second throws a NullpointerException.

// Method 1: WmfImageData from file (works).
WmfImageData imageData1 = new WmfImageData("C:\\\\temp\\\\test.wmf");
PdfFormXObject xObject1 = new PdfFormXObject(imageData1, pdf);
document.add(new Image(xObject1));

// Method 2: WmfImageData from byte[] (fails).
byte[] wmfBytes = Files.readAllBytes(Paths.get("C:\\\\temp\\\\test.wmf"));
WmfImageData imageData2 = new WmfImageData(wmfBytes);
PdfFormXObject xObject2 = new PdfFormXObject(imageData2, pdf);
document.add(new Image(xObject2));

The cause of this Exception is the constructor accepting a byte array in the iText.Kernel.Pdf.Canvas.Wmf.WmfImageData class. It tries to check whether the argument is a proper WMF image, but does so by trying to load bytes from an URL which does not exist. It should instead read the first few bytes from the array.

@ars18wrw
Copy link
Contributor

ars18wrw commented Jul 1, 2019

Hi @JorisJ1!

Thank you for your contribution! Before merging your changes, I have several minor remarks. Could you look at them? If you don't want to do it, I can do it myself.

  1. Since we support both Java and .NET versions of iText, we tend to write our code easily autoportable. Unfortunately there is not straight analogue on .Net for the following line:

Files.readAllBytes(Paths.get(sourceFolder + "example2.wmf"));

So could you write your test without usage of "readAllBytes"?
For example, you can use the approach which is demonstrated in inlineImagesTest02 (one of PdfCanvasTest's tests)

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    StreamUtil.transferBytes(new FileInputStream(sourceFolder + "example2.wmf"), baos);
    ImageData img = new WmfImageData(baos.toByteArray());
  1. Why have you decided to return an empty array if the the bytes's length is less than 8? In such a case the corresponding URL-parameterized method returns an array which contains the bytes which have been read from the stream. If there is no reasoning behind the decision, could you rewrite the method so that it works consistently with the URL-parameterized one?

  2. Could you squash your commits in a single commit?

When creating a WmfImage from a byte array use the first few bytes
(instead of a null URL) to check whether it is a WMF image.

Loading a WmfImage from a filepath or URL compares the first few
bytes from the file. For a byte array the same method was used,
which failed because no URL is provided.
@JorisJ1 JorisJ1 changed the title Use starting bytes to check if byte[] is WmfImage Use initial bytes to check if byte[] is WmfImage Jul 1, 2019
@JorisJ1
Copy link
Contributor Author

JorisJ1 commented Jul 1, 2019

Thank you for the great feedback @ars18wrw, I made the adjustments.

@avlemos
Copy link

avlemos commented Jul 29, 2019

Hi @JorisJ1 ,

Your contribution has been reviewed and merged into our code base.

Thank you!

@avlemos avlemos closed this Jul 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants