code: package freed.jni;
  
  import android.os.Build;
  import android.os.ParcelFileDescriptor;
  
  import java.io.File;
  import java.io.IOException;
  import java.io.RandomAccessFile;
  import java.nio.ByteBuffer;
  import java.nio.MappedByteBuffer;
  import java.nio.channels.FileChannel;
  import java.util.Date;
  
  import freed.dng.DngProfile;
  import freed.utils.StorageFileManager;
  
  /**
   * Created by troop on 15.02.2015.
   */
  public class RawToDng
  {
      static
      {
          System.loadLibrary("freedcam");
      }
  
      private final String TAG = RawToDng.class.getSimpleName();
  
      private ByteBuffer byteBuffer;
  
      private String wbct;
  
      private OpCode opCode;
      private ParcelFileDescriptor fileout;
  
      private native ByteBuffer init();
      private native void recycle(ByteBuffer byteBuffer);
      private native long GetRawBytesSize(ByteBuffer byteBuffer);
      private native void SetGPSData(ByteBuffer byteBuffer, ByteBuffer gpsBuffer);
      private native void SetThumbData(byte[] mThumb, int widht, int height,ByteBuffer byteBuffer);
      private native void WriteDNG(ByteBuffer byteBuffer);
      private native void SetOpCode(ByteBuffer byteBuffer, ByteBuffer opcode);
      private native void SetModelAndMake(String model, String make,ByteBuffer byteBuffer);
      private native void SetBayerData(byte[] fileBytes, String fileout,ByteBuffer byteBuffer);
      private native void SetBayerDataFD(byte[] fileBytes, int fileout, String filename,ByteBuffer byteBuffer);
      private native void SetBayerDataBufferFD(ByteBuffer fileBytes, int fileout, String filename,ByteBuffer byteBuffer);
      private native void SetBayerInfo(ByteBuffer matrix, ByteBuffer dngprofile,ByteBuffer byteBuffer);
      private native void SetExifData(ByteBuffer exifInfo,ByteBuffer byteBuffer);
  
      private native void SetDateTime(String datetime,ByteBuffer byteBuffer);
  
      private native void SetToneCurve(float[] tonecurve, ByteBuffer byteBuffer);
      private native void SetHueSatMapData1(float[] tonecurve, ByteBuffer byteBuffer);
      private native void SetHueSatMapData2(float[] tonecurve, ByteBuffer byteBuffer);
      private native void SetHueSatMapDims(int[] dims,ByteBuffer byteBuffer);
      private native void SetBaselineExposure(float baselineexposure,ByteBuffer byteBuffer);
      private native void SetBaselineExposureOffset(float baselineexposureoffset,ByteBuffer byteBuffer);
      private native void setBayerGreenSplit(int greensplit,ByteBuffer byteBuffer);
      private native void setCropWidthHeight(int width,int height,ByteBuffer byteBuffer);
  
      public static RawToDng GetInstance()
      {
          return new RawToDng();
      }
  
      private RawToDng()
      {
          byteBuffer = init();
          wbct = "";
      }
  
      @Override
      protected void finalize() throws Throwable {
          super.finalize();
          if (byteBuffer == null)
              return;
          recycle(byteBuffer);
          byteBuffer = null;
      }
  
      public void setOpCode(OpCode opCode)
      {
          this.opCode = opCode;
      }
  
      public void SetWBCT(String wbct)
      {
          this.wbct =wbct;
      }
  
      private long GetRawSize()
      {
          return GetRawBytesSize(byteBuffer);
      }
  
      public void SetGpsData(ByteBuffer gpsBuffer)
      {
          if (byteBuffer != null)
              SetGPSData(byteBuffer, gpsBuffer);
      }
  
      public void setExifData(ExifInfo exifData)
      {
          SetExifData(exifData.getByteBuffer(),byteBuffer);
          SetDateTime(StorageFileManager.getStringExifPattern().format(new Date()),byteBuffer);
      }
  
      public void setThumbData(byte[] mThumb, int widht, int height)
      {
          SetThumbData(mThumb, widht,height,byteBuffer);
      }
  
      private void SetModelAndMake(String make)
      {
          SetModelAndMake(Build.MODEL, Build.MANUFACTURER,byteBuffer);
      }
  
      public void setBayerData(byte[] fileBytes, String fileout) throws NullPointerException
      {
          if (fileBytes == null) {
              throw new NullPointerException();
          }
  
          SetBayerData(fileBytes, fileout,byteBuffer);
          if (opCode != null)
              SetOpCode(byteBuffer,opCode.getByteBuffer());
  
      }
  
      public void SetBayerDataFD(byte[] fileBytes, ParcelFileDescriptor fileout, String filename) throws NullPointerException
      {
          if (fileBytes == null) {
              throw new NullPointerException();
          }
          this.fileout = fileout;
          SetBayerDataFD(fileBytes, fileout.detachFd(), filename,byteBuffer);
          if (opCode != null)
              SetOpCode(byteBuffer,opCode.getByteBuffer());
      }
  
      public void SetBayerDataBufFD(ByteBuffer fileBytes, ParcelFileDescriptor fileout, String filename) throws NullPointerException
      {
          if (fileBytes == null) {
              throw new NullPointerException();
          }
          this.fileout = fileout;
          SetBayerDataBufferFD(fileBytes, fileout.detachFd(), filename,byteBuffer);
          if (opCode != null)
              SetOpCode(byteBuffer,opCode.getByteBuffer());
      }
  
  
      private void SetBayerInfo(ByteBuffer matrix, ByteBuffer dngprofile)
      {
          SetBayerInfo(matrix,dngprofile,byteBuffer);
      }
  
      public void setBaselineExposure(float baselineExposure)
      {
          if (byteBuffer == null)
              return;
          SetBaselineExposure(baselineExposure, byteBuffer);
      }
  
      public void setBaselineExposureOffset(float baselineExposure)
      {
          if (byteBuffer == null)
              return;
          SetBaselineExposureOffset(baselineExposure, byteBuffer);
      }
  
      public void setBayerGreenSplit(int greenSplit)
      {
          if (byteBuffer == null)
              return;
          setBayerGreenSplit(greenSplit,byteBuffer);
      }
  
      public void setCropWidthHeight(int width,int height)
      {
          if (byteBuffer == null)
              return;
          setCropWidthHeight(width,height,byteBuffer);
      }
  
  
      public void WriteDngWithProfile(DngProfile profile)
      {
          if (profile == null)
              return;
          SetModelAndMake(Build.MANUFACTURER);
          if (profile.toneMapProfile != null)
          {
              if (profile.toneMapProfile.getToneCurve() != null)
                  SetToneCurve(profile.toneMapProfile.getToneCurve(),byteBuffer);
              if (profile.toneMapProfile.getHueSatMapData1() != null)
                  SetHueSatMapData1(profile.toneMapProfile.getHueSatMapData1(),byteBuffer);
              if (profile.toneMapProfile.getHueSatMapData2() != null)
                  SetHueSatMapData2(profile.toneMapProfile.getHueSatMapData2(),byteBuffer);
              if (profile.toneMapProfile.getHueSatMapDims() != null)
                  SetHueSatMapDims(profile.toneMapProfile.getHueSatMapDims(),byteBuffer);
              if (profile.toneMapProfile.getBaselineExposure() != null)
                  SetBaselineExposure(profile.toneMapProfile.getBaselineExposure(),byteBuffer);
          }
          SetBayerInfo(profile.matrixes.getByteBuffer(),profile.getByteBuffer(),byteBuffer);
          WriteDNG(byteBuffer);
          recycle(byteBuffer);
          byteBuffer = null;
          if (fileout != null) {
              try {
                  fileout.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
  
      public static byte[] readFile(File file) throws IOException {
          // Open file
          RandomAccessFile f = new RandomAccessFile(file, "r");
          try {
              // Get and check length
              long longlength = f.length();
              int length = (int) longlength;
              if (length != longlength)
                  throw new IOException("File size >= 2 GB");
              // Read file and return data
              byte[] data = new byte[length];
              f.readFully(data);
              return data;
          } finally {
              f.close();
          }
      }
  
      public static MappedByteBuffer readFileToMemoryMap(File file) throws IOException {
          // Open file
          RandomAccessFile f = new RandomAccessFile(file, "rw");
          try {
             return f.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, f.length());
          } finally {
              f.close();
          }
      }
  }
  