/*
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.camera2;

import android.annotation.IntRange;
import android.annotation.NonNull;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.location.Location;
import android.media.ExifInterface;
import android.media.Image;
import android.os.SystemClock;
import android.util.Log;
import android.util.Size;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;

/**
 * The {@link DngCreator} class provides functions to write raw pixel data as a DNG file.
 *
 * <p>
 * This class is designed to be used with the {@link android.graphics.ImageFormat#RAW_SENSOR}
 * buffers available from {@link android.hardware.camera2.CameraDevice}, or with Bayer-type raw
 * pixel data that is otherwise generated by an application.  The DNG metadata tags will be
 * generated from a {@link android.hardware.camera2.CaptureResult} object or set directly.
 * </p>
 *
 * <p>
 * The DNG file format is a cross-platform file format that is used to store pixel data from
 * camera sensors with minimal pre-processing applied.  DNG files allow for pixel data to be
 * defined in a user-defined colorspace, and have associated metadata that allow for this
 * pixel data to be converted to the standard CIE XYZ colorspace during post-processing.
 * </p>
 *
 * <p>
 * For more information on the DNG file format and associated metadata, please refer to the
 * <a href=
 * "https://wwwimages2.adobe.com/content/dam/Adobe/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf">
 * Adobe DNG 1.4.0.0 specification</a>.
 * </p>
 */
public final class DngCreator implements AutoCloseable {

    private static final String TAG = "DngCreator";
    /**
     * Create a new DNG object.
     *
     * <p>
     * It is not necessary to call any set methods to write a well-formatted DNG file.
     * </p>
     * <p>
     * DNG metadata tags will be generated from the corresponding parameters in the
     * {@link android.hardware.camera2.CaptureResult} object.
     * </p>
     * <p>
     * For best quality DNG files, it is strongly recommended that lens shading map output is
     * enabled if supported. See {@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE}.
     * </p>
     * @param characteristics an object containing the static
     *          {@link android.hardware.camera2.CameraCharacteristics}.
     * @param metadata a metadata object to generate tags from.
     */
    public DngCreator(@NonNull CameraCharacteristics characteristics,
            @NonNull CaptureResult metadata) {
        if (characteristics == null || metadata == null) {
            throw new IllegalArgumentException("Null argument to DngCreator constructor");
        }

        // Find current time in milliseconds since 1970
        long currentTime = System.currentTimeMillis();
        // Assume that sensor timestamp has that timebase to start
        long timeOffset = 0;

        int timestampSource = characteristics.get(
                CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE);

        if (timestampSource == CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME) {
            // This means the same timebase as SystemClock.elapsedRealtime(),
            // which is CLOCK_BOOTTIME
            timeOffset = currentTime - SystemClock.elapsedRealtime();
        } else if (timestampSource == CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN) {
            // This means the same timebase as System.currentTimeMillis(),
            // which is CLOCK_MONOTONIC
            timeOffset = currentTime - SystemClock.uptimeMillis();
        } else {
            // Unexpected time source - treat as CLOCK_MONOTONIC
            Log.w(TAG, "Sensor timestamp source is unexpected: " + timestampSource);
            timeOffset = currentTime - SystemClock.uptimeMillis();
        }

        // Find capture time (nanos since boot)
        Long timestamp = metadata.get(CaptureResult.SENSOR_TIMESTAMP);
        long captureTime = currentTime;
        if (timestamp != null) {
            captureTime = timestamp / 1000000 + timeOffset;
        }

        // Create this fresh each time since the time zone may change while a long-running application
        // is active.
        final DateFormat dateTimeStampFormat =
                new SimpleDateFormat(TIFF_DATETIME_FORMAT, Locale.US);
        dateTimeStampFormat.setTimeZone(TimeZone.getDefault());

        // Format for metadata
        String formattedCaptureTime = dateTimeStampFormat.format(captureTime);

        nativeInit(characteristics.getNativeCopy(), metadata.getNativeCopy(),
                formattedCaptureTime);
    }

    /**
     * Set the orientation value to write.
     *
     * <p>
     * This will be written as the TIFF "Orientation" tag {@code (0x0112)}.
     * Calling this will override any prior settings for this tag.
     * </p>
     *
     * @param orientation the orientation value to set, one of:
     *                    <ul>
     *                      <li>{@link android.media.ExifInterface#ORIENTATION_NORMAL}</li>
     *                      <li>{@link android.media.ExifInterface#ORIENTATION_FLIP_HORIZONTAL}</li>
     *                      <li>{@link android.media.ExifInterface#ORIENTATION_ROTATE_180}</li>
     *                      <li>{@link android.media.ExifInterface#ORIENTATION_FLIP_VERTICAL}</li>
     *                      <li>{@link android.media.ExifInterface#ORIENTATION_TRANSPOSE}</li>
     *                      <li>{@link android.media.ExifInterface#ORIENTATION_ROTATE_90}</li>
     *                      <li>{@link android.media.ExifInterface#ORIENTATION_TRANSVERSE}</li>
     *                      <li>{@link android.media.ExifInterface#ORIENTATION_ROTATE_270}</li>
     *                    </ul>
     * @return this {@link #DngCreator} object.
     */
    @NonNull
    public DngCreator setOrientation(int orientation) {
        if (orientation < ExifInterface.ORIENTATION_UNDEFINED ||
                orientation > ExifInterface.ORIENTATION_ROTATE_270) {
            throw new IllegalArgumentException("Orientation " + orientation +
                    " is not a valid EXIF orientation value");
        }
        // ExifInterface and TIFF/EP spec differ on definition of
        // "Unknown" orientation; other values map directly
        if (orientation == ExifInterface.ORIENTATION_UNDEFINED) {
            orientation = TAG_ORIENTATION_UNKNOWN;
        }
        nativeSetOrientation(orientation);
        return this;
    }

    /**
     * Set the thumbnail image.
     *
     * <p>
     * Pixel data will be converted to a Baseline TIFF RGB image, with 8 bits per color channel.
     * The alpha channel will be discarded.  Thumbnail images with a dimension larger than
     * {@link #MAX_THUMBNAIL_DIMENSION} will be rejected.
     * </p>
     *
     * @param pixels a {@link android.graphics.Bitmap} of pixel data.
     * @return this {@link #DngCreator} object.
     * @throws java.lang.IllegalArgumentException if the given thumbnail image has a dimension
     *      larger than {@link #MAX_THUMBNAIL_DIMENSION}.
     */
    @NonNull
    public DngCreator setThumbnail(@NonNull Bitmap pixels) {
        if (pixels == null) {
            throw new IllegalArgumentException("Null argument to setThumbnail");
        }

        int width = pixels.getWidth();
        int height = pixels.getHeight();

        if (width > MAX_THUMBNAIL_DIMENSION || height > MAX_THUMBNAIL_DIMENSION) {
            throw new IllegalArgumentException("Thumbnail dimensions width,height (" + width +
                    "," + height + ") too large, dimensions must be smaller than " +
                    MAX_THUMBNAIL_DIMENSION);
        }

        ByteBuffer rgbBuffer = convertToRGB(pixels);
        nativeSetThumbnail(rgbBuffer, width, height);

        return this;
    }

    /**
     * Set the thumbnail image.
     *
     * <p>
     * Pixel data is interpreted as a {@link android.graphics.ImageFormat#YUV_420_888} image.
     * Thumbnail images with a dimension larger than {@link #MAX_THUMBNAIL_DIMENSION} will be
     * rejected.
     * </p>
     *
     * @param pixels an {@link android.media.Image} object with the format
     *               {@link android.graphics.ImageFormat#YUV_420_888}.
     * @return this {@link #DngCreator} object.
     * @throws java.lang.IllegalArgumentException if the given thumbnail image has a dimension
     *      larger than {@link #MAX_THUMBNAIL_DIMENSION}.
     */
    @NonNull
    public DngCreator setThumbnail(@NonNull Image pixels) {
        if (pixels == null) {
            throw new IllegalArgumentException("Null argument to setThumbnail");
        }

        int format = pixels.getFormat();
        if (format != ImageFormat.YUV_420_888) {
            throw new IllegalArgumentException("Unsupported Image format " + format);
        }

        int width = pixels.getWidth();
        int height = pixels.getHeight();

        if (width > MAX_THUMBNAIL_DIMENSION || height > MAX_THUMBNAIL_DIMENSION) {
            throw new IllegalArgumentException("Thumbnail dimensions width,height (" + width +
                    "," + height + ") too large, dimensions must be smaller than " +
                    MAX_THUMBNAIL_DIMENSION);
        }

        ByteBuffer rgbBuffer = convertToRGB(pixels);
        nativeSetThumbnail(rgbBuffer, width, height);

        return this;
    }

    /**
     * Set image location metadata.
     *
     * <p>
     * The given location object must contain at least a valid time, latitude, and longitude
     * (equivalent to the values returned by {@link android.location.Location#getTime()},
     * {@link android.location.Location#getLatitude()}, and
     * {@link android.location.Location#getLongitude()} methods).
     * </p>
     *
     * @param location an {@link android.location.Location} object to set.
     * @return this {@link #DngCreator} object.
     *
     * @throws java.lang.IllegalArgumentException if the given location object doesn't
     *          contain enough information to set location metadata.
     */
    @NonNull
    public DngCreator setLocation(@NonNull Location location) {
        if (location == null) {
            throw new IllegalArgumentException("Null location passed to setLocation");
        }
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();
        long time = location.getTime();

        int[] latTag = toExifLatLong(latitude);
        int[] longTag = toExifLatLong(longitude);
        String latRef = latitude >= 0 ? GPS_LAT_REF_NORTH : GPS_LAT_REF_SOUTH;
        String longRef = longitude >= 0 ? GPS_LONG_REF_EAST : GPS_LONG_REF_WEST;

        String dateTag = sExifGPSDateStamp.format(time);
        mGPSTimeStampCalendar.setTimeInMillis(time);
        int[] timeTag = new int[] { mGPSTimeStampCalendar.get(Calendar.HOUR_OF_DAY), 1,
                mGPSTimeStampCalendar.get(Calendar.MINUTE), 1,
                mGPSTimeStampCalendar.get(Calendar.SECOND), 1 };
        nativeSetGpsTags(latTag, latRef, longTag, longRef, dateTag, timeTag);
        return this;
    }

    /**
     * Set the user description string to write.
     *
     * <p>
     * This is equivalent to setting the TIFF "ImageDescription" tag {@code (0x010E)}.
     * </p>
     *
     * @param description the user description string.
     * @return this {@link #DngCreator} object.
     */
    @NonNull
    public DngCreator setDescription(@NonNull String description) {
        if (description == null) {
            throw new IllegalArgumentException("Null description passed to setDescription.");
        }
        nativeSetDescription(description);
        return this;
    }

    /**
     * Write the {@link android.graphics.ImageFormat#RAW_SENSOR} pixel data to a DNG file with
     * the currently configured metadata.
     *
     * <p>
     * Raw pixel data must have 16 bits per pixel, and the input must contain at least
     * {@code offset + 2 * width * height)} bytes.  The width and height of
     * the input are taken from the width and height set in the {@link DngCreator} metadata tags,
     * and will typically be equal to the width and height of
     * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE}.  Prior to
     * API level 23, this was always the same as
     * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE}.
     * The pixel layout in the input is determined from the reported color filter arrangement (CFA)
     * set in {@link CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT}.  If insufficient
     * metadata is available to write a well-formatted DNG file, an
     * {@link java.lang.IllegalStateException} will be thrown.
     * </p>
     *
     * @param dngOutput an {@link java.io.OutputStream} to write the DNG file to.
     * @param size the {@link Size} of the image to write, in pixels.
     * @param pixels an {@link java.io.InputStream} of pixel data to write.
     * @param offset the offset of the raw image in bytes.  This indicates how many bytes will
     *               be skipped in the input before any pixel data is read.
     *
     * @throws IOException if an error was encountered in the input or output stream.
     * @throws java.lang.IllegalStateException if not enough metadata information has been
     *          set to write a well-formatted DNG file.
     * @throws java.lang.IllegalArgumentException if the size passed in does not match the
     */
    public void writeInputStream(@NonNull OutputStream dngOutput, @NonNull Size size,
            @NonNull InputStream pixels, @IntRange(from=0) long offset) throws IOException {
        if (dngOutput == null) {
            throw new IllegalArgumentException("Null dngOutput passed to writeInputStream");
        } else if (size == null) {
            throw new IllegalArgumentException("Null size passed to writeInputStream");
        } else if (pixels == null) {
            throw new IllegalArgumentException("Null pixels passed to writeInputStream");
        } else if (offset < 0) {
            throw new IllegalArgumentException("Negative offset passed to writeInputStream");
        }

        int width = size.getWidth();
        int height = size.getHeight();
        if (width <= 0 || height <= 0) {
            throw new IllegalArgumentException("Size with invalid width, height: (" + width + "," +
                    height + ") passed to writeInputStream");
        }
        nativeWriteInputStream(dngOutput, pixels, width, height, offset);
    }

    /**
     * Write the {@link android.graphics.ImageFormat#RAW_SENSOR} pixel data to a DNG file with
     * the currently configured metadata.
     *
     * <p>
     * Raw pixel data must have 16 bits per pixel, and the input must contain at least
     * {@code offset + 2 * width * height)} bytes.  The width and height of
     * the input are taken from the width and height set in the {@link DngCreator} metadata tags,
     * and will typically be equal to the width and height of
     * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE}.  Prior to
     * API level 23, this was always the same as
     * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE}.
     * The pixel layout in the input is determined from the reported color filter arrangement (CFA)
     * set in {@link CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT}.  If insufficient
     * metadata is available to write a well-formatted DNG file, an
     * {@link java.lang.IllegalStateException} will be thrown.
     * </p>
     *
     * <p>
     * Any mark or limit set on this {@link ByteBuffer} is ignored, and will be cleared by this
     * method.
     * </p>
     *
     * @param dngOutput an {@link java.io.OutputStream} to write the DNG file to.
     * @param size the {@link Size} of the image to write, in pixels.
     * @param pixels an {@link java.nio.ByteBuffer} of pixel data to write.
     * @param offset the offset of the raw image in bytes.  This indicates how many bytes will
     *               be skipped in the input before any pixel data is read.
     *
     * @throws IOException if an error was encountered in the input or output stream.
     * @throws java.lang.IllegalStateException if not enough metadata information has been
     *          set to write a well-formatted DNG file.
     */
    public void writeByteBuffer(@NonNull OutputStream dngOutput, @NonNull Size size,
            @NonNull ByteBuffer pixels, @IntRange(from=0) long offset)
            throws IOException {
        if (dngOutput == null) {
            throw new IllegalArgumentException("Null dngOutput passed to writeByteBuffer");
        } else if (size == null) {
            throw new IllegalArgumentException("Null size passed to writeByteBuffer");
        } else if (pixels == null) {
            throw new IllegalArgumentException("Null pixels passed to writeByteBuffer");
        } else if (offset < 0) {
            throw new IllegalArgumentException("Negative offset passed to writeByteBuffer");
        }

        int width = size.getWidth();
        int height = size.getHeight();

        writeByteBuffer(width, height, pixels, dngOutput, DEFAULT_PIXEL_STRIDE,
                width * DEFAULT_PIXEL_STRIDE, offset);
    }

    /**
     * Write the pixel data to a DNG file with the currently configured metadata.
     *
     * <p>
     * For this method to succeed, the {@link android.media.Image} input must contain
     * {@link android.graphics.ImageFormat#RAW_SENSOR} pixel data, otherwise an
     * {@link java.lang.IllegalArgumentException} will be thrown.
     * </p>
     *
     * @param dngOutput an {@link java.io.OutputStream} to write the DNG file to.
     * @param pixels an {@link android.media.Image} to write.
     *
     * @throws java.io.IOException if an error was encountered in the output stream.
     * @throws java.lang.IllegalArgumentException if an image with an unsupported format was used.
     * @throws java.lang.IllegalStateException if not enough metadata information has been
     *          set to write a well-formatted DNG file.
     */
    public void writeImage(@NonNull OutputStream dngOutput, @NonNull Image pixels)
            throws IOException {
        if (dngOutput == null) {
            throw new IllegalArgumentException("Null dngOutput to writeImage");
        } else if (pixels == null) {
            throw new IllegalArgumentException("Null pixels to writeImage");
        }

        int format = pixels.getFormat();
        if (format != ImageFormat.RAW_SENSOR) {
            throw new IllegalArgumentException("Unsupported image format " + format);
        }

        Image.Plane[] planes = pixels.getPlanes();
        if (planes == null || planes.length <= 0) {
            throw new IllegalArgumentException("Image with no planes passed to writeImage");
        }

        ByteBuffer buf = planes[0].getBuffer();
        writeByteBuffer(pixels.getWidth(), pixels.getHeight(), buf, dngOutput,
                planes[0].getPixelStride(), planes[0].getRowStride(), 0);
    }

    @Override
    public void close() {
        nativeDestroy();
    }

    /**
     * Max width or height dimension for thumbnails.
     */
    public static final int MAX_THUMBNAIL_DIMENSION = 256; // max pixel dimension for TIFF/EP

    @Override
    protected void finalize() throws Throwable {
        try {
            close();
        } finally {
            super.finalize();
        }
    }

    private static final String GPS_LAT_REF_NORTH = "N";
    private static final String GPS_LAT_REF_SOUTH = "S";
    private static final String GPS_LONG_REF_EAST = "E";
    private static final String GPS_LONG_REF_WEST = "W";

    private static final String GPS_DATE_FORMAT_STR = "yyyy:MM:dd";
    private static final String TIFF_DATETIME_FORMAT = "yyyy:MM:dd HH:mm:ss";
    private static final DateFormat sExifGPSDateStamp =
            new SimpleDateFormat(GPS_DATE_FORMAT_STR, Locale.US);
    private final Calendar mGPSTimeStampCalendar = Calendar
            .getInstance(TimeZone.getTimeZone("UTC"));

    static {
        sExifGPSDateStamp.setTimeZone(TimeZone.getTimeZone("UTC"));
    }

    private static final int DEFAULT_PIXEL_STRIDE = 2; // bytes per sample
    private static final int BYTES_PER_RGB_PIX = 3; // byts per pixel

    // TIFF tag values needed to map between public API and TIFF spec
    private static final int TAG_ORIENTATION_UNKNOWN = 9;

    /**
     * Offset, rowStride, and pixelStride are given in bytes.  Height and width are given in pixels.
     */
    private void writeByteBuffer(int width, int height, ByteBuffer pixels, OutputStream dngOutput,
                                 int pixelStride, int rowStride, long offset)  throws IOException {
        if (width <= 0 || height <= 0) {
            throw new IllegalArgumentException("Image with invalid width, height: (" + width + "," +
                    height + ") passed to write");
        }
        long capacity = pixels.capacity();
        long totalSize = ((long) rowStride) * height + offset;
        if (capacity < totalSize) {
            throw new IllegalArgumentException("Image size " + capacity +
                    " is too small (must be larger than " + totalSize + ")");
        }
        int minRowStride = pixelStride * width;
        if (minRowStride > rowStride) {
            throw new IllegalArgumentException("Invalid image pixel stride, row byte width " +
                    minRowStride + " is too large, expecting " + rowStride);
        }
        pixels.clear(); // Reset mark and limit
        nativeWriteImage(dngOutput, width, height, pixels, rowStride, pixelStride, offset,
                pixels.isDirect());
        pixels.clear();
    }

    /**
     * Convert a single YUV pixel to RGB.
     */
    private static void yuvToRgb(byte[] yuvData, int outOffset, /*out*/byte[] rgbOut) {
        final int COLOR_MAX = 255;

        float y = yuvData[0] & 0xFF;  // Y channel
        float cb = yuvData[1] & 0xFF; // U channel
        float cr = yuvData[2] & 0xFF; // V channel

        // convert YUV -> RGB (from JFIF's "Conversion to and from RGB" section)
        float r = y + 1.402f * (cr - 128);
        float g = y - 0.34414f * (cb - 128) - 0.71414f * (cr - 128);
        float b = y + 1.772f * (cb - 128);

        // clamp to [0,255]
        rgbOut[outOffset] = (byte) Math.max(0, Math.min(COLOR_MAX, r));
        rgbOut[outOffset + 1] = (byte) Math.max(0, Math.min(COLOR_MAX, g));
        rgbOut[outOffset + 2] = (byte) Math.max(0, Math.min(COLOR_MAX, b));
    }

    /**
     * Convert a single {@link Color} pixel to RGB.
     */
    private static void colorToRgb(int color, int outOffset, /*out*/byte[] rgbOut) {
        rgbOut[outOffset] = (byte) Color.red(color);
        rgbOut[outOffset + 1] = (byte) Color.green(color);
        rgbOut[outOffset + 2] = (byte) Color.blue(color);
        // Discards Alpha
    }

    /**
     * Generate a direct RGB {@link ByteBuffer} from a YUV420_888 {@link Image}.
     */
    private static ByteBuffer convertToRGB(Image yuvImage) {
        // TODO: Optimize this with renderscript intrinsic.
        int width = yuvImage.getWidth();
        int height = yuvImage.getHeight();
        ByteBuffer buf = ByteBuffer.allocateDirect(BYTES_PER_RGB_PIX * width * height);

        Image.Plane yPlane = yuvImage.getPlanes()[0];
        Image.Plane uPlane = yuvImage.getPlanes()[1];
        Image.Plane vPlane = yuvImage.getPlanes()[2];

        ByteBuffer yBuf = yPlane.getBuffer();
        ByteBuffer uBuf = uPlane.getBuffer();
        ByteBuffer vBuf = vPlane.getBuffer();

        yBuf.rewind();
        uBuf.rewind();
        vBuf.rewind();

        int yRowStride = yPlane.getRowStride();
        int vRowStride = vPlane.getRowStride();
        int uRowStride = uPlane.getRowStride();

        int yPixStride = yPlane.getPixelStride();
        int vPixStride = vPlane.getPixelStride();
        int uPixStride = uPlane.getPixelStride();

        byte[] yuvPixel = { 0, 0, 0 };
        byte[] yFullRow = new byte[yPixStride * (width - 1) + 1];
        byte[] uFullRow = new byte[uPixStride * (width / 2 - 1) + 1];
        byte[] vFullRow = new byte[vPixStride * (width / 2 - 1) + 1];
        byte[] finalRow = new byte[BYTES_PER_RGB_PIX * width];
        for (int i = 0; i < height; i++) {
            int halfH = i / 2;
            yBuf.position(yRowStride * i);
            yBuf.get(yFullRow);
            uBuf.position(uRowStride * halfH);
            uBuf.get(uFullRow);
            vBuf.position(vRowStride * halfH);
            vBuf.get(vFullRow);
            for (int j = 0; j < width; j++) {
                int halfW = j / 2;
                yuvPixel[0] = yFullRow[yPixStride * j];
                yuvPixel[1] = uFullRow[uPixStride * halfW];
                yuvPixel[2] = vFullRow[vPixStride * halfW];
                yuvToRgb(yuvPixel, j * BYTES_PER_RGB_PIX, /*out*/finalRow);
            }
            buf.put(finalRow);
        }

        yBuf.rewind();
        uBuf.rewind();
        vBuf.rewind();
        buf.rewind();
        return buf;
    }

    /**
     * Generate a direct RGB {@link ByteBuffer} from a {@link Bitmap}.
     */
    private static ByteBuffer convertToRGB(Bitmap argbBitmap) {
        // TODO: Optimize this.
        int width = argbBitmap.getWidth();
        int height = argbBitmap.getHeight();
        ByteBuffer buf = ByteBuffer.allocateDirect(BYTES_PER_RGB_PIX * width * height);

        int[] pixelRow = new int[width];
        byte[] finalRow = new byte[BYTES_PER_RGB_PIX * width];
        for (int i = 0; i < height; i++) {
            argbBitmap.getPixels(pixelRow, /*offset*/0, /*stride*/width, /*x*/0, /*y*/i,
                    /*width*/width, /*height*/1);
            for (int j = 0; j < width; j++) {
                colorToRgb(pixelRow[j], j * BYTES_PER_RGB_PIX, /*out*/finalRow);
            }
            buf.put(finalRow);
        }

        buf.rewind();
        return buf;
    }

    /**
     * Convert coordinate to EXIF GPS tag format.
     */
    private static int[] toExifLatLong(double value) {
        // convert to the format dd/1 mm/1 ssss/100
        value = Math.abs(value);
        int degrees = (int) value;
        value = (value - degrees) * 60;
        int minutes = (int) value;
        value = (value - minutes) * 6000;
        int seconds = (int) value;
        return new int[] { degrees, 1, minutes, 1, seconds, 100 };
    }

    /**
     * This field is used by native code, do not access or modify.
     */
    private long mNativeContext;

    private static native void nativeClassInit();

    private synchronized native void nativeInit(CameraMetadataNative nativeCharacteristics,
                                                CameraMetadataNative nativeResult,
                                                String captureTime);

    private synchronized native void nativeDestroy();

    private synchronized native void nativeSetOrientation(int orientation);

    private synchronized native void nativeSetDescription(String description);

    private synchronized native void nativeSetGpsTags(int[] latTag, String latRef, int[] longTag,
                                                      String longRef, String dateTag,
                                                      int[] timeTag);

    private synchronized native void nativeSetThumbnail(ByteBuffer buffer, int width, int height);

    private synchronized native void nativeWriteImage(OutputStream out, int width, int height,
                                                      ByteBuffer rawBuffer, int rowStride,
                                                      int pixStride, long offset, boolean isDirect)
                                                      throws IOException;

    private synchronized native void nativeWriteInputStream(OutputStream out, InputStream rawStream,
                                                            int width, int height, long offset)
                                                            throws IOException;

    static {
        nativeClassInit();
    }
}
