-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Open
Labels
Description
The following code creates corrupt imagefiles (one in a few thousands). When trying to read the file 1 hour later we see an error. The location to write to is a remote file server.
static boolean writeFile(final byte[] imageAsBytes, final String label, final Path imageFilePath) {
try (final BytePointer imageBytesInNativeMemoryPointer = new BytePointer(imageAsBytes); // Copies the bytes of the image from the heap (because 'bytes' is an array) to the native memory and creates a pointer.
final Mat imageBytesInNativeMemoryMatrix = new Mat(imageBytesInNativeMemoryPointer, false); // Creates a matrix representation for the given pointer. Just a wrapper, that does not copy anything.
final Mat imageDecodedInNativeMemoryMatrix = imdecode(imageBytesInNativeMemoryMatrix, CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR); // Decodes the image to a new matrix in native memory with real pixel values.
final Point textBottomLeftCorner = new Point(10, 55);
final Scalar textWhiteColor = new Scalar(255, 255, 255, 255)
) {
// Add image description in the upper left corner
putText(imageDecodedInNativeMemoryMatrix, label, textBottomLeftCorner, FONT_HERSHEY_SIMPLEX, 0.7, textWhiteColor, 2, LINE_AA, false);
FilesAndFoldersUtil.createFolder(imageFilePath.getParent());
// Stores the given image matrix from native memory to the given file
final boolean writeSuccess = imwrite(imageFilePath.toString(), imageDecodedInNativeMemoryMatrix);
final boolean fileCreated = Files.exists(imageFilePath);
if (!writeSuccess || !fileCreated) {
throw new IOException("Could not write image to file " + imageFilePath + ". Was a file created? " + fileCreated + ". File size " + (fileCreated ? Files.size(imageFilePath) : -1) + ". Matrix size: [width= " + imageDecodedInNativeMemoryMatrix.size().width() + "|height=" + imageBytesInNativeMemoryMatrix.size().height() + "]");
}
} catch (final Exception ex) {
LOG.warn("Exception while writing image to file", ex);
return false;
}
return true;
}
if (!writeSuccess || !fileCreated) : This condition was false so imwrite says its finished by returning true and the file exists.
An example of a corrupt imagefile:

Error when reading:
javax.imageio.IIOException: Error reading PNG image data
at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1528)
at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.read(PNGImageReader.java:1845)
at java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1466)
at java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1315)
...
Caused by: javax.imageio.IIOException: Unknown row filter type (= 30)!
at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.decodePass(PNGImageReader.java:1267)
at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.decodeImage(PNGImageReader.java:1379)
at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1519)
How to prevent this? Write to memory first and than send it over the line?
Add a thread sleep after imwrite()?
Add a release() or something?