
package info.freelibrary.jiiify.image;

import java.io.File;
import java.io.IOException;

import org.opencv.core.Mat;
import org.opencv.core.Rect;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import info.freelibrary.jiiify.iiif.ImageFormat;
import info.freelibrary.jiiify.iiif.ImageQuality;
import info.freelibrary.jiiify.iiif.ImageRegion;
import info.freelibrary.jiiify.iiif.ImageRegion.Region;
import info.freelibrary.jiiify.iiif.ImageRotation;
import info.freelibrary.jiiify.iiif.ImageSize;

public class NativeImageObject implements ImageObject {

    private Mat myImage;

    public NativeImageObject(final File aSourceImage) {
        myImage = Imgcodecs.imread(aSourceImage.getAbsolutePath());
    }

    @Override
    public void extractRegion(final ImageRegion aRegion) throws IOException {
        final Rect roi = new Rect();
        final Mat newImage;

        if (aRegion.isFullImage()) {
            return;
        } else if (aRegion.usesPercentages()) {
            // TODO
        } else {
            roi.height = aRegion.getInt(Region.HEIGHT);
            roi.width = aRegion.getInt(Region.WIDTH);
            roi.x = aRegion.getInt(Region.X);
            roi.y = aRegion.getInt(Region.Y);
        }

        newImage = myImage.submat(roi);
        myImage.release();
        myImage = newImage;
    }

    @Override
    public void resize(final ImageSize aSize) throws IOException {
        final Mat resizedImage;

        if (!aSize.isFullSize()) {
            final int width = aSize.getWidth(myImage.width(), myImage.height());
            final int height = aSize.getHeight(myImage.height(), myImage.width());

            resizedImage = new Mat(myImage.rows(), myImage.cols(), myImage.type());
            Imgproc.resize(myImage, resizedImage, new Size(width, height));
            myImage.release();
            myImage = resizedImage;
        }
    }

    @Override
    public void rotate(final ImageRotation aRotation) throws IOException {

    }

    @Override
    public void adjustQuality(final ImageQuality aQuality) throws IOException {

    }

    @Override
    public void changeFormat(final ImageFormat aFormat) throws IOException {

    }

    @Override
    public void write(final File aImageFile) throws IOException {
        final File parent = aImageFile.getParentFile();

        if (!parent.exists() && !parent.mkdirs()) {
            throw new IOException("Unable to create directory structure: " + parent);
        }

        if (!Imgcodecs.imwrite(aImageFile.getAbsolutePath(), myImage)) {
            myImage.release();
            throw new IOException("Unable to write image with native libraries");
        }
    }

}

@@ -1323,38 +1323,35 @@
         myImage.
+f
 re
-leas
 e();%0A        myI
@@ -1860,38 +1860,35 @@
         myImage.
+f
 re
-leas
 e();%0A           
@@ -2362,16 +2362,47 @@
 tFile();
+%0A        final boolean written;
 %0A%0A      
@@ -2552,21 +2552,26 @@
         
-if (!
+written = 
 Imgcodec
@@ -2618,31 +2618,26 @@
 myImage)
-) %7B%0A   
+;%0A
         
  myImage
@@ -2628,25 +2628,24 @@
         
- 
 myImage.
 release(
@@ -2640,18 +2640,40 @@
 age.
+f
 re
-leas
 e();
+%0A%0A        if (!written) %7B
 %0A   

Fix native library memory issues