diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java
index 9ec649e..d5972e2 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java
@@ -16,15 +16,22 @@
 
 package android.hardware.camera2.cts;
 
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapRegionDecoder;
 import android.graphics.ImageFormat;
 import android.graphics.Rect;
-import android.hardware.camera2.CameraCaptureSession;
+import android.graphics.RectF;
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
 import android.hardware.camera2.DngCreator;
 import android.hardware.camera2.cts.helpers.StaticMetadata;
+import android.hardware.camera2.cts.rs.BitmapUtils;
+import android.hardware.camera2.cts.rs.RawConverter;
+import android.hardware.camera2.cts.rs.RenderScriptSingleton;
 import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
 import android.location.Location;
 import android.media.ExifInterface;
@@ -37,11 +44,14 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.FileOutputStream;
+import java.nio.channels.FileChannel;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
-import static android.hardware.camera2.cts.CameraTestUtils.configureCameraSession;
 import static android.hardware.camera2.cts.helpers.AssertHelpers.*;
+import static junit.framework.Assert.assertTrue;
 
 /**
  * Tests for the DngCreator API.
@@ -51,6 +61,9 @@
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
     private static final String DEBUG_DNG_FILE = "raw16.dng";
 
+    private static final double IMAGE_DIFFERENCE_TOLERANCE = 60;
+    private static final int DEFAULT_PATCH_DIMEN = 512;
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -61,6 +74,13 @@
         super.tearDown();
     }
 
+    @Override
+    public synchronized void setContext(Context context) {
+        super.setContext(context);
+
+        RenderScriptSingleton.setContext(context);
+    }
+
     /**
      * Test basic raw capture and DNG saving functionality for each of the available cameras.
      *
@@ -120,14 +140,15 @@
                 dngCreator.writeImage(outputStream, resultPair.first);
 
                 if (VERBOSE) {
-                    String filePath = DEBUG_FILE_NAME_BASE + "camera_" + deviceId + "_" +
+                    // Write DNG to file
+                    String dngFilePath = DEBUG_FILE_NAME_BASE + "/camera_basic_" + deviceId + "_" +
                             DEBUG_DNG_FILE;
                     // Write out captured DNG file for the first camera device if setprop is enabled
-                    fileStream = new FileOutputStream(filePath);
+                    fileStream = new FileOutputStream(dngFilePath);
                     fileStream.write(outputStream.toByteArray());
                     fileStream.flush();
                     fileStream.close();
-                    Log.v(TAG, "Test DNG file for camera " + deviceId + " saved to " + filePath);
+                    Log.v(TAG, "Test DNG file for camera " + deviceId + " saved to " + dngFilePath);
                 }
             } finally {
                 closeDevice(deviceId);
@@ -231,7 +252,7 @@
                 dngCreator.writeImage(outputStream, resultPair.first.get(0));
 
                 if (VERBOSE) {
-                    String filePath = DEBUG_FILE_NAME_BASE + "camera_" + deviceId + "_" +
+                    String filePath = DEBUG_FILE_NAME_BASE + "/camera_thumb_" + deviceId + "_" +
                             DEBUG_DNG_FILE;
                     // Write out captured DNG file for the first camera device if setprop is enabled
                     fileStream = new FileOutputStream(filePath);
@@ -257,6 +278,222 @@
         }
     }
 
+    /**
+     * Test basic RAW capture, and ensure that the rendered RAW output is similar to the JPEG
+     * created for the same frame.
+     *
+     * <p>
+     * This test renders the RAW buffer into an RGB bitmap using a rendering pipeline
+     * similar to one in the Adobe DNG validation tool.  JPEGs produced by the vendor hardware may
+     * have different tonemapping and saturation applied than the RGB bitmaps produced
+     * from this DNG rendering pipeline, and this test allows for fairly wide variations
+     * between the histograms for the RAW and JPEG buffers to avoid false positives.
+     * </p>
+     *
+     * <p>
+     * To ensure more subtle errors in the colorspace transforms returned for the HAL's RAW
+     * metadata, the DNGs and JPEGs produced here should also be manually compared using external
+     * DNG rendering tools.  The DNG, rendered RGB bitmap, and JPEG buffer for this test can be
+     * dumped to the SD card for further examination by enabling the 'verbose' mode for this test
+     * using:
+     * adb shell setprop log.tag.DngCreatorTest VERBOSE
+     * </p>
+     */
+    public void testRaw16JpegConsistency() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            String deviceId = mCameraIds[i];
+            List<ImageReader> captureReaders = new ArrayList<ImageReader>();
+            List<CameraTestUtils.SimpleImageReaderListener> captureListeners =
+                    new ArrayList<CameraTestUtils.SimpleImageReaderListener>();
+            FileOutputStream fileStream = null;
+            ByteArrayOutputStream outputStream = null;
+            FileChannel fileChannel = null;
+            try {
+                openDevice(deviceId);
+
+                if (!mStaticInfo.isCapabilitySupported(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
+                    Log.i(TAG, "RAW capability is not supported in camera " + mCameraIds[i] +
+                            ". Skip the test.");
+                    continue;
+                }
+
+                Size[] targetCaptureSizes =
+                        mStaticInfo.getAvailableSizesForFormatChecked(ImageFormat.RAW_SENSOR,
+                                StaticMetadata.StreamDirection.Output);
+
+                assertTrue("No capture sizes available for RAW format!",
+                        targetCaptureSizes.length != 0);
+                Rect activeArray = mStaticInfo.getActiveArraySizeChecked();
+                Size activeArraySize = new Size(activeArray.width(), activeArray.height());
+                assertTrue("Active array has invalid size!", activeArray.width() > 0 &&
+                        activeArray.height() > 0);
+                // TODO: Allow PixelArraySize also.
+                assertArrayContains("Available sizes for RAW format must include ActiveArraySize",
+                        targetCaptureSizes, activeArraySize);
+
+                // Get largest jpeg size
+                Size[] targetJpegSizes =
+                        mStaticInfo.getAvailableSizesForFormatChecked(ImageFormat.JPEG,
+                                StaticMetadata.StreamDirection.Output);
+
+                Size largestJpegSize = Collections.max(Arrays.asList(targetJpegSizes),
+                        new CameraTestUtils.SizeComparator());
+
+                // Create raw image reader and capture listener
+                CameraTestUtils.SimpleImageReaderListener rawListener
+                        = new CameraTestUtils.SimpleImageReaderListener();
+                captureReaders.add(createImageReader(activeArraySize, ImageFormat.RAW_SENSOR, 2,
+                        rawListener));
+                captureListeners.add(rawListener);
+
+
+                // Create jpeg image reader and capture listener
+                CameraTestUtils.SimpleImageReaderListener jpegListener
+                        = new CameraTestUtils.SimpleImageReaderListener();
+                captureReaders.add(createImageReader(largestJpegSize, ImageFormat.JPEG, 2,
+                        jpegListener));
+                captureListeners.add(jpegListener);
+
+                Pair<List<Image>, CaptureResult> resultPair = captureSingleRawShot(activeArraySize,
+                        captureReaders, captureListeners);
+                CameraCharacteristics characteristics = mStaticInfo.getCharacteristics();
+                Image raw = resultPair.first.get(0);
+                Image jpeg = resultPair.first.get(1);
+
+                Bitmap rawBitmap = Bitmap.createBitmap(raw.getWidth(), raw.getHeight(),
+                        Bitmap.Config.ARGB_8888);
+                byte[] rawPlane = new byte[raw.getPlanes()[0].getRowStride() * raw.getHeight()];
+
+                // Render RAW image to a bitmap
+                raw.getPlanes()[0].getBuffer().get(rawPlane);
+                raw.getPlanes()[0].getBuffer().rewind();
+                RawConverter.convertToSRGB(RenderScriptSingleton.getRS(), raw.getWidth(),
+                        raw.getHeight(), rawPlane, characteristics,
+                        resultPair.second, /*offsetX*/0, /*offsetY*/0, /*out*/rawBitmap);
+
+                // Decompress JPEG image to a bitmap
+                byte[] compressedJpegData = CameraTestUtils.getDataFromImage(jpeg);
+
+                BitmapFactory.Options opt = new BitmapFactory.Options();
+                opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
+                Bitmap fullSizeJpegBmap = BitmapFactory.decodeByteArray(compressedJpegData,
+                        /*offset*/0, compressedJpegData.length, /*inout*/opt);
+                Rect jpegDimens = new Rect(0, 0, fullSizeJpegBmap.getWidth(),
+                        fullSizeJpegBmap.getHeight());
+
+                if (VERBOSE) {
+                    // Generate DNG file
+                    DngCreator dngCreator = new DngCreator(characteristics, resultPair.second);
+                    outputStream = new ByteArrayOutputStream();
+                    dngCreator.writeImage(outputStream, raw);
+
+                    // Write DNG to file
+                    String dngFilePath = DEBUG_FILE_NAME_BASE + "/camera_" + deviceId + "_" +
+                            DEBUG_DNG_FILE;
+                    // Write out captured DNG file for the first camera device if setprop is enabled
+                    fileStream = new FileOutputStream(dngFilePath);
+                    fileStream.write(outputStream.toByteArray());
+                    fileStream.flush();
+                    fileStream.close();
+                    Log.v(TAG, "Test DNG file for camera " + deviceId + " saved to " + dngFilePath);
+
+                    // Write JPEG to file
+                    String jpegFilePath = DEBUG_FILE_NAME_BASE + "/camera_" + deviceId + "_jpeg.jpg";
+                    // Write out captured DNG file for the first camera device if setprop is enabled
+                    fileChannel = new FileOutputStream(jpegFilePath).getChannel();
+                    fileChannel.write(jpeg.getPlanes()[0].getBuffer());
+                    fileChannel.close();
+                    Log.v(TAG, "Test JPEG file for camera " + deviceId + " saved to " +
+                            jpegFilePath);
+
+                    // Write jpeg generated from demosaiced RAW frame to file
+                    String rawFilePath = DEBUG_FILE_NAME_BASE + "/camera_" + deviceId + "_raw.jpg";
+                    // Write out captured DNG file for the first camera device if setprop is enabled
+                    fileStream = new FileOutputStream(rawFilePath);
+                    rawBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fileStream);
+                    fileStream.flush();
+                    fileStream.close();
+                    Log.v(TAG, "Test converted RAW file for camera " + deviceId + " saved to " +
+                            rawFilePath);
+                }
+
+                Size rawBitmapSize = new Size(rawBitmap.getWidth(), rawBitmap.getHeight());
+                assertTrue("Raw bitmap size must be equal to active array size.",
+                        rawBitmapSize.equals(activeArraySize));
+
+                // Get square center patch from JPEG and RAW bitmaps
+                RectF jpegRect = new RectF(jpegDimens);
+                RectF rawRect = new RectF(0, 0, rawBitmap.getWidth(), rawBitmap.getHeight());
+                int sideDimen = Math.min(Math.min(Math.min(Math.min(DEFAULT_PATCH_DIMEN,
+                        jpegDimens.width()), jpegDimens.height()), rawBitmap.getWidth()),
+                        rawBitmap.getHeight());
+
+                RectF jpegIntermediate = new RectF(0, 0, sideDimen, sideDimen);
+                jpegIntermediate.offset(jpegRect.centerX() - jpegIntermediate.centerX(),
+                        jpegRect.centerY() - jpegIntermediate.centerY());
+                RectF rawIntermediate = new RectF(0, 0, sideDimen, sideDimen);
+                rawIntermediate.offset(rawRect.centerX() - rawIntermediate.centerX(),
+                        rawRect.centerY() - rawIntermediate.centerY());
+                Rect jpegFinal = new Rect();
+                jpegIntermediate.roundOut(jpegFinal);
+                Rect rawFinal = new Rect();
+                rawIntermediate.roundOut(rawFinal);
+
+                Bitmap jpegPatch = Bitmap.createBitmap(fullSizeJpegBmap, jpegFinal.left,
+                        jpegFinal.top, jpegFinal.width(), jpegFinal.height());
+                Bitmap rawPatch = Bitmap.createBitmap(rawBitmap, rawFinal.left, rawFinal.top,
+                        rawFinal.width(), rawFinal.height());
+
+                // Compare center patch from JPEG and rendered RAW bitmap
+                double difference = BitmapUtils.calcDifferenceMetric(jpegPatch, rawPatch);
+                if (difference > IMAGE_DIFFERENCE_TOLERANCE) {
+                    // Write JPEG patch to file
+                    String jpegFilePath = DEBUG_FILE_NAME_BASE + "/camera_" + deviceId +
+                            "_jpeg_patch.jpg";
+                    fileStream = new FileOutputStream(jpegFilePath);
+                    jpegPatch.compress(Bitmap.CompressFormat.JPEG, 90, fileStream);
+                    fileStream.flush();
+                    fileStream.close();
+                    Log.e(TAG, "Failed JPEG patch file for camera " + deviceId + " saved to " +
+                            jpegFilePath);
+
+                    // Write RAW patch to file
+                    String rawFilePath = DEBUG_FILE_NAME_BASE + "/camera_" + deviceId +
+                            "_raw_patch.jpg";
+                    fileStream = new FileOutputStream(rawFilePath);
+                    rawPatch.compress(Bitmap.CompressFormat.JPEG, 90, fileStream);
+                    fileStream.flush();
+                    fileStream.close();
+                    Log.e(TAG, "Failed RAW patch file for camera " + deviceId + " saved to " +
+                            rawFilePath);
+
+                    fail("Camera " + mCamera.getId() + ": RAW and JPEG image at  for the same " +
+                            "frame are not similar, center patches have difference metric of " +
+                            difference);
+                }
+
+            } finally {
+                closeDevice(deviceId);
+                for (ImageReader r : captureReaders) {
+                    closeImageReader(r);
+                }
+
+                if (fileChannel != null) {
+                    fileChannel.close();
+                }
+
+                if (outputStream != null) {
+                    outputStream.close();
+                }
+
+                if (fileStream != null) {
+                    fileStream.close();
+                }
+            }
+        }
+    }
+
     private Pair<Image, CaptureResult> captureSingleRawShot(Size s, ImageReader captureReader,
             CameraTestUtils.SimpleImageReaderListener captureListener) throws Exception {
         List<ImageReader> readers = new ArrayList<ImageReader>();
@@ -268,22 +505,27 @@
         return new Pair<Image, CaptureResult>(res.first.get(0), res.second);
     }
 
+    private Pair<List<Image>, CaptureResult> captureSingleRawShot(Size s, List<ImageReader> captureReaders,
+            List<CameraTestUtils.SimpleImageReaderListener> captureListeners) throws Exception {
+        return captureRawShots(s, captureReaders, captureListeners, 1).get(0);
+    }
+
     /**
-     * Capture a single raw image.
+     * Capture raw images.
      *
-     * <p>Capture an raw image for a given size.</p>
+     * <p>Capture raw images for a given size.</p>
      *
      * @param s The size of the raw image to capture.  Must be one of the available sizes for this
      *          device.
-     * @return a pair containing the {@link Image} and {@link CaptureResult} used for this capture.
+     * @return a list of pairs containing a {@link Image} and {@link CaptureResult} used for
+     *          each capture.
      */
-    private Pair<List<Image>, CaptureResult> captureSingleRawShot(Size s, List<ImageReader> captureReaders,
-            List<CameraTestUtils.SimpleImageReaderListener> captureListeners) throws Exception {
+    private List<Pair<List<Image>, CaptureResult>> captureRawShots(Size s, List<ImageReader> captureReaders,
+            List<CameraTestUtils.SimpleImageReaderListener> captureListeners, int numShots) throws Exception {
         if (VERBOSE) {
             Log.v(TAG, "captureSingleRawShot - Capturing raw image.");
         }
 
-        Size maxYuvSz = mOrderedPreviewSizes.get(0);
         Size[] targetCaptureSizes =
                 mStaticInfo.getAvailableSizesForFormatChecked(ImageFormat.RAW_SENSOR,
                         StaticMetadata.StreamDirection.Output);
@@ -312,23 +554,29 @@
         CameraTestUtils.SimpleCaptureCallback resultListener =
                 new CameraTestUtils.SimpleCaptureCallback();
 
-        startCapture(request.build(), /*repeating*/false, resultListener, mHandler);
+        CaptureRequest request1 = request.build();
+        for (int i = 0; i < numShots; i++) {
+            startCapture(request1, /*repeating*/false, resultListener, mHandler);
+        }
+        List<Pair<List<Image>, CaptureResult>> ret = new ArrayList<>();
+        for (int i = 0; i < numShots; i++) {
+            // Verify capture result and images
+            CaptureResult result = resultListener.getCaptureResult(CAPTURE_WAIT_TIMEOUT_MS);
 
-        // Verify capture result and images
-        CaptureResult result = resultListener.getCaptureResult(CAPTURE_WAIT_TIMEOUT_MS);
-
-        List<Image> resultImages = new ArrayList<Image>();
-        for (CameraTestUtils.SimpleImageReaderListener captureListener : captureListeners) {
-            Image captureImage = captureListener.getImage(CAPTURE_WAIT_TIMEOUT_MS);
+            List<Image> resultImages = new ArrayList<Image>();
+            for (CameraTestUtils.SimpleImageReaderListener captureListener : captureListeners) {
+                Image captureImage = captureListener.getImage(CAPTURE_WAIT_TIMEOUT_MS);
 
             /*CameraTestUtils.validateImage(captureImage, s.getWidth(), s.getHeight(),
                     ImageFormat.RAW_SENSOR, null);*/
-            resultImages.add(captureImage);
+                resultImages.add(captureImage);
+            }
+            ret.add(new Pair<List<Image>, CaptureResult>(resultImages, result));
         }
         // Stop capture, delete the streams.
         stopCapture(/*fast*/false);
 
-        return new Pair<List<Image>, CaptureResult>(resultImages, result);
+        return ret;
     }
 
     private CaptureRequest.Builder prepareCaptureRequestForSurfaces(List<Surface> surfaces)
@@ -336,7 +584,7 @@
         createSession(surfaces);
 
         CaptureRequest.Builder captureBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
         assertNotNull("Fail to get captureRequest", captureBuilder);
         for (Surface surface : surfaces) {
             captureBuilder.addTarget(surface);
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
index 9089a8c..a410775 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
@@ -30,6 +30,7 @@
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
 import android.hardware.camera2.cts.helpers.StaticMetadata;
+import android.hardware.camera2.cts.rs.BitmapUtils;
 import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
 import android.hardware.camera2.params.StreamConfigurationMap;
 import android.media.Image;
@@ -364,7 +365,7 @@
                                     yuvPatch.width(), yuvPatch.height(), /*filter*/true);
 
                             // Compare two patches using average of per-pixel differences
-                            double difference = findDifferenceMetric(yuvBmap, jpegBmap);
+                            double difference = BitmapUtils.calcDifferenceMetric(yuvBmap, jpegBmap);
 
                             Log.i(TAG, "Difference for resolution " + captureSz + " is: " +
                                     difference);
@@ -413,39 +414,6 @@
     }
 
     /**
-     * Find the difference between two bitmaps using average of per-pixel differences.
-     *
-     * @param a first {@link Bitmap}.
-     * @param b second {@link Bitmap}.
-     * @return the difference.
-     */
-    private static double findDifferenceMetric(Bitmap a, Bitmap b) {
-        if (a.getWidth() != b.getWidth() || a.getHeight() != b.getHeight()) {
-            throw new IllegalArgumentException("Bitmap dimensions for arguments do not match a=" +
-                    a.getWidth() + "x" + a.getHeight() + ", b=" + b.getWidth() + "x" +
-                    b.getHeight());
-        }
-        // TODO: Optimize this in renderscript to avoid copy.
-        int[] aPixels = new int[a.getHeight() * a.getWidth()];
-        int[] bPixels = new int[aPixels.length];
-        a.getPixels(aPixels, /*offset*/0, /*stride*/a.getWidth(), /*x*/0, /*y*/0, a.getWidth(),
-                a.getHeight());
-        b.getPixels(bPixels, /*offset*/0, /*stride*/b.getWidth(), /*x*/0, /*y*/0, b.getWidth(),
-                b.getHeight());
-        double diff = 0;
-        for (int i = 0; i < aPixels.length; i++) {
-            int aPix = aPixels[i];
-            int bPix = bPixels[i];
-
-            diff += Math.abs(Color.red(aPix) - Color.red(bPix)); // red
-            diff += Math.abs(Color.green(aPix) - Color.green(bPix)); // green
-            diff += Math.abs(Color.blue(aPix) - Color.blue(bPix)); // blue
-        }
-        diff /= (aPixels.length * 3);
-        return diff;
-    }
-
-    /**
      * Convert a rectangular patch in a YUV image to an ARGB color array.
      *
      * @param w width of the patch.
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/BitmapUtils.java b/tests/tests/hardware/src/android/hardware/camera2/cts/rs/BitmapUtils.java
new file mode 100644
index 0000000..744d2c7
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/rs/BitmapUtils.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2015 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.cts.rs;
+
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.ScriptIntrinsicHistogram;
+
+/**
+ * Utility class providing methods for various pixel-wise ARGB bitmap operations.
+ */
+public class BitmapUtils {
+    private static final String TAG = "BitmapUtils";
+    private static final int COLOR_BIT_DEPTH = 256;
+
+    public static int A = 3;
+    public static int R = 0;
+    public static int G = 1;
+    public static int B = 2;
+    public static int NUM_CHANNELS = 4;
+
+    /**
+     * Return the histograms for each color channel (interleaved).
+     *
+     * @param rs a {@link RenderScript} context to use.
+     * @param bmap a {@link Bitmap} to generate the histograms for.
+     * @return an array containing NUM_CHANNELS * COLOR_BIT_DEPTH histogram bucket values, with
+     * the color channels interleaved.
+     */
+    public static int[] calcHistograms(RenderScript rs, Bitmap bmap) {
+        ScriptIntrinsicHistogram hist = ScriptIntrinsicHistogram.create(rs, Element.U8_4(rs));
+        Allocation sums = Allocation.createSized(rs, Element.I32_4(rs), COLOR_BIT_DEPTH);
+
+        // Setup input allocation (ARGB 8888 bitmap).
+        Allocation input = Allocation.createFromBitmap(rs, bmap);
+
+        hist.setOutput(sums);
+        hist.forEach(input);
+        int[] output = new int[COLOR_BIT_DEPTH * NUM_CHANNELS];
+        sums.copyTo(output);
+        return output;
+    }
+
+    /**
+     * Find the difference between two bitmaps using average of per-pixel differences.
+     *
+     * @param a first {@link android.graphics.Bitmap}.
+     * @param b second {@link android.graphics.Bitmap}.
+     * @return the difference.
+     */
+    public static double calcDifferenceMetric(Bitmap a, Bitmap b) {
+        if (a.getWidth() != b.getWidth() || a.getHeight() != b.getHeight()) {
+            throw new IllegalArgumentException("Bitmap dimensions for arguments do not match a=" +
+                    a.getWidth() + "x" + a.getHeight() + ", b=" + b.getWidth() + "x" +
+                    b.getHeight());
+        }
+        // TODO: Optimize this in renderscript to avoid copy.
+        int[] aPixels = new int[a.getHeight() * a.getWidth()];
+        int[] bPixels = new int[aPixels.length];
+        a.getPixels(aPixels, /*offset*/0, /*stride*/a.getWidth(), /*x*/0, /*y*/0, a.getWidth(),
+                a.getHeight());
+        b.getPixels(bPixels, /*offset*/0, /*stride*/b.getWidth(), /*x*/0, /*y*/0, b.getWidth(),
+                b.getHeight());
+        double diff = 0;
+        for (int i = 0; i < aPixels.length; i++) {
+            int aPix = aPixels[i];
+            int bPix = bPixels[i];
+
+            diff += Math.abs(Color.red(aPix) - Color.red(bPix)); // red
+            diff += Math.abs(Color.green(aPix) - Color.green(bPix)); // green
+            diff += Math.abs(Color.blue(aPix) - Color.blue(bPix)); // blue
+        }
+        diff /= (aPixels.length * 3);
+        return diff;
+    }
+
+}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/RawConverter.java b/tests/tests/hardware/src/android/hardware/camera2/cts/rs/RawConverter.java
new file mode 100644
index 0000000..2cd2469
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/rs/RawConverter.java
@@ -0,0 +1,786 @@
+/*
+ * Copyright 2015 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.cts.rs;
+
+import android.graphics.Bitmap;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.params.ColorSpaceTransform;
+import android.hardware.camera2.params.LensShadingMap;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Float3;
+import android.renderscript.Float4;
+import android.renderscript.Int4;
+import android.renderscript.Matrix3f;
+import android.renderscript.RenderScript;
+import android.renderscript.Type;
+
+import android.hardware.camera2.cts.ScriptC_raw_converter;
+import android.util.Log;
+import android.util.Rational;
+import android.util.SparseIntArray;
+
+import java.util.Arrays;
+
+/**
+ * Utility class providing methods for rendering RAW16 images into other colorspaces.
+ */
+public class RawConverter {
+    private static final String TAG = "RawConverter";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    /**
+     * Matrix to convert from CIE XYZ colorspace to sRGB, Bradford-adapted to D65.
+     */
+    private static final float[] sXYZtoRGBBradford = new float[] {
+            3.1338561f, -1.6168667f, -0.4906146f,
+            -0.9787684f, 1.9161415f, 0.0334540f,
+            0.0719453f, -0.2289914f, 1.4052427f
+    };
+
+    /**
+     * Matrix to convert from the ProPhoto RGB colorspace to CIE XYZ colorspace.
+     */
+    private static final float[] sProPhotoToXYZ = new float[] {
+            0.797779f, 0.135213f, 0.031303f,
+            0.288000f, 0.711900f, 0.000100f,
+            0.000000f, 0.000000f, 0.825105f
+    };
+
+    /**
+     * Matrix to convert from CIE XYZ colorspace to ProPhoto RGB colorspace.
+     */
+    private static final float[] sXYZtoProPhoto = new float[] {
+            1.345753f, -0.255603f, -0.051025f,
+            -0.544426f, 1.508096f, 0.020472f,
+            0.000000f, 0.000000f, 1.211968f
+    };
+
+    /**
+     * Coefficients for a 3rd order polynomial, ordered from highest to lowest power.  This
+     * polynomial approximates the default tonemapping curve used for ACR3.
+     */
+    private static final float[] DEFAULT_ACR3_TONEMAP_CURVE_COEFFS = new float[] {
+            1.041f, -2.973f, 2.932f, 0f
+    };
+
+    /**
+     * The D50 whitepoint coordinates in CIE XYZ colorspace.
+     */
+    private static final float[] D50_XYZ = new float[] { 0.9642f, 1, 0.8249f };
+
+    /**
+     * An array containing the color temperatures for standard reference illuminants.
+     */
+    private static final SparseIntArray sStandardIlluminants = new SparseIntArray();
+    private static final int NO_ILLUMINANT = -1;
+    static {
+        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT, 6504);
+        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_D65, 6504);
+        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_D50, 5003);
+        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_D55, 5503);
+        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_D75, 7504);
+        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_STANDARD_A, 2856);
+        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_STANDARD_B, 4874);
+        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_STANDARD_C, 6774);
+        sStandardIlluminants.append(
+                CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT_FLUORESCENT, 6430);
+        sStandardIlluminants.append(
+                CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_COOL_WHITE_FLUORESCENT, 4230);
+        sStandardIlluminants.append(
+                CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_WHITE_FLUORESCENT, 3450);
+        // TODO: Add the rest of the illuminants included in the LightSource EXIF tag.
+    }
+
+    /**
+     * Convert a RAW16 buffer into an sRGB buffer, and write the result into a bitmap.
+     *
+     * <p> This function applies the operations roughly outlined in the Adobe DNG specification
+     * using the provided metadata about the image sensor.  Sensor data for Android devices is
+     * assumed to be relatively linear, and no extra linearization step is applied here.  The
+     * following operations are applied in the given order:</p>
+     *
+     * <ul>
+     *     <li>
+     *         Black level subtraction - the black levels given in the SENSOR_BLACK_LEVEL_PATTERN
+     *         tag are subtracted from the corresponding raw pixels.
+     *     </li>
+     *     <li>
+     *         Rescaling - each raw pixel is scaled by 1/(white level - black level).
+     *     </li>
+     *     <li>
+     *         Lens shading correction - the interpolated gains from the gain map defined in the
+     *         STATISTICS_LENS_SHADING_CORRECTION_MAP are applied to each raw pixel.
+     *     </li>
+     *     <li>
+     *         Clipping - each raw pixel is clipped to a range of [0.0, 1.0].
+     *     </li>
+     *     <li>
+     *         Demosaic - the RGB channels for each pixel are retrieved from the Bayer mosaic
+     *         of raw pixels using a simple bilinear-interpolation demosaicing algorithm.
+     *     </li>
+     *     <li>
+     *         Colorspace transform to wide-gamut RGB - each pixel is mapped into a
+     *         wide-gamut colorspace (in this case ProPhoto RGB is used) from the sensor
+     *         colorspace.
+     *     </li>
+     *     <li>
+     *         Tonemapping - A basic tonemapping curve using the default from ACR3 is applied
+     *         (no further exposure compensation is applied here, though this could be improved).
+     *     </li>
+     *     <li>
+     *         Colorspace transform to final RGB - each pixel is mapped into linear sRGB colorspace.
+     *     </li>
+     *     <li>
+     *         Gamma correction - each pixel is gamma corrected using γ=2.2 to map into sRGB
+     *         colorspace for viewing.
+     *     </li>
+     *     <li>
+     *         Packing - each pixel is scaled so that each color channel has a range of [0, 255],
+     *         and is packed into an Android bitmap.
+     *     </li>
+     * </ul>
+     *
+     * <p> Arguments given here are assumed to come from the values for the corresponding
+     * {@link CameraCharacteristics.Key}s defined for the camera that produced this RAW16 buffer.
+     * </p>
+     * @param rs a {@link RenderScript} context to use.
+     * @param inputWidth width of the input RAW16 image in pixels.
+     * @param inputHeight height of the input RAW16 image in pixels.
+     * @param rawImageInput a byte array containing a RAW16 image.
+     * @param staticMetadata the {@link CameraCharacteristics} for this RAW capture.
+     * @param dynamicMetadata the {@link CaptureResult} for this RAW capture.
+     * @param outputOffsetX the offset width into the raw image of the left side of the output
+     *                      rectangle.
+     * @param outputOffsetY the offset height into the raw image of the top side of the output
+     *                      rectangle.
+     * @param argbOutput a {@link Bitmap} to output the rendered RAW image into.  The height and
+     *                   width of this bitmap along with the output offsets are used to determine
+     *                   the dimensions and offset of the output rectangle contained in the RAW
+     *                   image to be rendered.
+     */
+    public static void convertToSRGB(RenderScript rs, int inputWidth, int inputHeight,
+            byte[] rawImageInput, CameraCharacteristics staticMetadata,
+            CaptureResult dynamicMetadata, int outputOffsetX, int outputOffsetY,
+            /*out*/Bitmap argbOutput) {
+        int cfa = staticMetadata.get(CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT);
+        int[] blackLevelPattern = new int[4];
+        staticMetadata.get(CameraCharacteristics.SENSOR_BLACK_LEVEL_PATTERN).
+                copyTo(blackLevelPattern, /*offset*/0);
+        int whiteLevel = staticMetadata.get(CameraCharacteristics.SENSOR_INFO_WHITE_LEVEL);
+        int ref1 = staticMetadata.get(CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1);
+        int ref2 = staticMetadata.get(CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT2);
+        float[] calib1 = new float[9];
+        float[] calib2 = new float[9];
+        convertColorspaceTransform(
+                staticMetadata.get(CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM1), calib1);
+        convertColorspaceTransform(
+                staticMetadata.get(CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM2), calib2);
+        float[] color1 = new float[9];
+        float[] color2 = new float[9];
+        convertColorspaceTransform(
+                staticMetadata.get(CameraCharacteristics.SENSOR_COLOR_TRANSFORM1), color1);
+        convertColorspaceTransform(
+                staticMetadata.get(CameraCharacteristics.SENSOR_COLOR_TRANSFORM2), color2);
+        float[] forward1 = new float[9];
+        float[] forward2 = new float[9];
+        convertColorspaceTransform(
+                staticMetadata.get(CameraCharacteristics.SENSOR_FORWARD_MATRIX1), forward1);
+        convertColorspaceTransform(
+                staticMetadata.get(CameraCharacteristics.SENSOR_FORWARD_MATRIX2), forward2);
+
+        Rational[] neutral = dynamicMetadata.get(CaptureResult.SENSOR_NEUTRAL_COLOR_POINT);
+
+        LensShadingMap shadingMap = dynamicMetadata.get(CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP);
+
+        convertToSRGB(rs, inputWidth, inputHeight, cfa, blackLevelPattern, whiteLevel,
+                rawImageInput, ref1, ref2, calib1, calib2, color1, color2,
+                forward1, forward2, neutral, shadingMap, outputOffsetX, outputOffsetY, argbOutput);
+    }
+
+    /**
+     * Convert a RAW16 buffer into an sRGB buffer, and write the result into a bitmap.
+     *
+     * @see #convertToSRGB
+     */
+    private static void convertToSRGB(RenderScript rs, int inputWidth, int inputHeight, int cfa,
+            int[] blackLevelPattern, int whiteLevel, byte[] rawImageInput,
+            int referenceIlluminant1, int referenceIlluminant2, float[] calibrationTransform1,
+            float[] calibrationTransform2, float[] colorMatrix1, float[] colorMatrix2,
+            float[] forwardTransform1, float[] forwardTransform2, Rational[/*3*/] neutralColorPoint,
+            LensShadingMap lensShadingMap, int outputOffsetX, int outputOffsetY,
+            /*out*/Bitmap argbOutput) {
+
+        // Validate arguments
+        if (argbOutput == null || rs == null || rawImageInput == null) {
+            throw new IllegalArgumentException("Null argument to convertToSRGB");
+        }
+        if (argbOutput.getConfig() != Bitmap.Config.ARGB_8888) {
+            throw new IllegalArgumentException(
+                    "Output bitmap passed to convertToSRGB is not ARGB_8888 format");
+        }
+        if (outputOffsetX < 0 || outputOffsetY < 0) {
+            throw new IllegalArgumentException("Negative offset passed to convertToSRGB");
+        }
+        int outWidth = argbOutput.getWidth();
+        int outHeight = argbOutput.getHeight();
+        if (outWidth + outputOffsetX > inputWidth || outHeight + outputOffsetY > inputHeight) {
+            throw new IllegalArgumentException("Raw image with dimensions (w=" + inputWidth +
+                    ", h=" + inputHeight + "), cannot converted into sRGB image with dimensions (w="
+                    + outWidth + ", h=" + outHeight + ").");
+        }
+        if (cfa < 0 || cfa > 3) {
+            throw new IllegalArgumentException("Unsupported cfa pattern " + cfa + " used.");
+        }
+        if (DEBUG) {
+            Log.d(TAG, "Metadata Used:");
+            Log.d(TAG, "Input width,height: " + inputWidth + "," + inputHeight);
+            Log.d(TAG, "Output offset x,y: " + outputOffsetX + "," + outputOffsetY);
+            Log.d(TAG, "Output width,height: " + outWidth + "," + outHeight);
+            Log.d(TAG, "CFA: " + cfa);
+            Log.d(TAG, "BlackLevelPattern: " + Arrays.toString(blackLevelPattern));
+            Log.d(TAG, "WhiteLevel: " + whiteLevel);
+            Log.d(TAG, "ReferenceIlluminant1: " + referenceIlluminant1);
+            Log.d(TAG, "ReferenceIlluminant2: " + referenceIlluminant2);
+            Log.d(TAG, "CalibrationTransform1: " + Arrays.toString(calibrationTransform1));
+            Log.d(TAG, "CalibrationTransform2: " + Arrays.toString(calibrationTransform2));
+            Log.d(TAG, "ColorMatrix1: " + Arrays.toString(colorMatrix1));
+            Log.d(TAG, "ColorMatrix2: " + Arrays.toString(colorMatrix2));
+            Log.d(TAG, "ForwardTransform1: " + Arrays.toString(forwardTransform1));
+            Log.d(TAG, "ForwardTransform2: " + Arrays.toString(forwardTransform2));
+            Log.d(TAG, "NeutralColorPoint: " + Arrays.toString(neutralColorPoint));
+        }
+
+        Allocation gainMap = null;
+        if (lensShadingMap != null) {
+            float[] lsm = new float[lensShadingMap.getGainFactorCount()];
+            lensShadingMap.copyGainFactors(/*inout*/lsm, /*offset*/0);
+            gainMap = createFloat4Allocation(rs, lsm, lensShadingMap.getColumnCount(),
+                    lensShadingMap.getRowCount());
+        }
+
+        float[] normalizedForwardTransform1 = Arrays.copyOf(forwardTransform1,
+                forwardTransform1.length);
+        normalizeFM(normalizedForwardTransform1);
+        float[] normalizedForwardTransform2 = Arrays.copyOf(forwardTransform2,
+                forwardTransform2.length);
+        normalizeFM(normalizedForwardTransform2);
+
+        float[] normalizedColorMatrix1 = Arrays.copyOf(colorMatrix1, colorMatrix1.length);
+        normalizeCM(normalizedColorMatrix1);
+        float[] normalizedColorMatrix2 = Arrays.copyOf(colorMatrix2, colorMatrix2.length);
+        normalizeCM(normalizedColorMatrix2);
+
+        if (DEBUG) {
+            Log.d(TAG, "Normalized ForwardTransform1: " + Arrays.toString(normalizedForwardTransform1));
+            Log.d(TAG, "Normalized ForwardTransform2: " + Arrays.toString(normalizedForwardTransform2));
+            Log.d(TAG, "Normalized ColorMatrix1: " + Arrays.toString(normalizedColorMatrix1));
+            Log.d(TAG, "Normalized ColorMatrix2: " + Arrays.toString(normalizedColorMatrix2));
+        }
+
+        // Calculate full sensor colorspace to sRGB colorspace transform.
+        double interpolationFactor = findDngInterpolationFactor(referenceIlluminant1,
+                referenceIlluminant2, calibrationTransform1, calibrationTransform2,
+                normalizedColorMatrix1, normalizedColorMatrix2, neutralColorPoint);
+        if (DEBUG) Log.d(TAG, "Interpolation factor used: " + interpolationFactor);
+        float[] sensorToXYZ = new float[9];
+        calculateCameraToXYZD50Transform(normalizedForwardTransform1, normalizedForwardTransform2,
+                calibrationTransform1, calibrationTransform2, neutralColorPoint,
+                interpolationFactor, /*out*/sensorToXYZ);
+        if (DEBUG) Log.d(TAG, "CameraToXYZ xform used: " + Arrays.toString(sensorToXYZ));
+        float[] sensorToProPhoto = new float[9];
+        multiply(sXYZtoProPhoto, sensorToXYZ, /*out*/sensorToProPhoto);
+        if (DEBUG) Log.d(TAG, "CameraToIntemediate xform used: " + Arrays.toString(sensorToProPhoto));
+        Allocation output = Allocation.createFromBitmap(rs, argbOutput);
+
+        float[] proPhotoToSRGB = new float[9];
+        multiply(sXYZtoRGBBradford, sProPhotoToXYZ, /*out*/proPhotoToSRGB);
+
+        // Setup input allocation (16-bit raw pixels)
+        Type.Builder typeBuilder = new Type.Builder(rs, Element.U16(rs));
+        typeBuilder.setX(inputWidth);
+        typeBuilder.setY(inputHeight);
+        Type inputType = typeBuilder.create();
+        Allocation input = Allocation.createTyped(rs, inputType);
+        input.copyFromUnchecked(rawImageInput);
+
+        // Setup RS kernel globals
+        ScriptC_raw_converter converterKernel = new ScriptC_raw_converter(rs);
+        converterKernel.set_inputRawBuffer(input);
+        converterKernel.set_whiteLevel(whiteLevel);
+        converterKernel.set_sensorToIntermediate(new Matrix3f(transpose(sensorToProPhoto)));
+        converterKernel.set_intermediateToSRGB(new Matrix3f(transpose(proPhotoToSRGB)));
+        converterKernel.set_offsetX(outputOffsetX);
+        converterKernel.set_offsetY(outputOffsetY);
+        converterKernel.set_rawHeight(inputHeight);
+        converterKernel.set_rawWidth(inputWidth);
+        converterKernel.set_neutralPoint(new Float3(neutralColorPoint[0].floatValue(),
+                neutralColorPoint[1].floatValue(), neutralColorPoint[2].floatValue()));
+        converterKernel.set_toneMapCoeffs(new Float4(DEFAULT_ACR3_TONEMAP_CURVE_COEFFS[0],
+                DEFAULT_ACR3_TONEMAP_CURVE_COEFFS[1], DEFAULT_ACR3_TONEMAP_CURVE_COEFFS[2],
+                DEFAULT_ACR3_TONEMAP_CURVE_COEFFS[3]));
+        converterKernel.set_hasGainMap(gainMap != null);
+        if (gainMap != null) {
+            converterKernel.set_gainMap(gainMap);
+            converterKernel.set_gainMapWidth(lensShadingMap.getColumnCount());
+            converterKernel.set_gainMapHeight(lensShadingMap.getRowCount());
+        }
+
+        converterKernel.set_cfaPattern(cfa);
+        converterKernel.set_blackLevelPattern(new Int4(blackLevelPattern[0],
+                blackLevelPattern[1], blackLevelPattern[2], blackLevelPattern[3]));
+        converterKernel.forEach_convert_RAW_To_ARGB(output);
+        output.copyTo(argbOutput);  // Force RS sync with bitmap (does not do an extra copy).
+    }
+
+    /**
+     * Create a float-backed renderscript {@link Allocation} with the given dimensions, containing
+     * the contents of the given float array.
+     *
+     * @param rs a {@link RenderScript} context to use.
+     * @param fArray the float array to copy into the {@link Allocation}.
+     * @param width the width of the {@link Allocation}.
+     * @param height the height of the {@link Allocation}.
+     * @return an {@link Allocation} containing the given floats.
+     */
+    private static Allocation createFloat4Allocation(RenderScript rs, float[] fArray,
+                                                    int width, int height) {
+        if (fArray.length != width * height * 4) {
+            throw new IllegalArgumentException("Invalid float array of length " + fArray.length +
+                    ", must be correct size for Allocation of dimensions " + width + "x" + height);
+        }
+        Type.Builder builder = new Type.Builder(rs, Element.F32_4(rs));
+        builder.setX(width);
+        builder.setY(height);
+        Allocation fAlloc = Allocation.createTyped(rs, builder.create());
+        fAlloc.copyFrom(fArray);
+        return fAlloc;
+    }
+
+    /**
+     * Calculate the correlated color temperature (CCT) for a given x,y chromaticity in CIE 1931 x,y
+     * chromaticity space using McCamy's cubic approximation algorithm given in:
+     *
+     * McCamy, Calvin S. (April 1992).
+     * "Correlated color temperature as an explicit function of chromaticity coordinates".
+     * Color Research & Application 17 (2): 142–144
+     *
+     * @param x x chromaticity component.
+     * @param y y chromaticity component.
+     *
+     * @return the CCT associated with this chromaticity coordinate.
+     */
+    private static double calculateColorTemperature(double x, double y) {
+        double n = (x - 0.332) / (y - 0.1858);
+        return -449 * Math.pow(n, 3) + 3525 * Math.pow(n, 2) - 6823.3 * n + 5520.33;
+    }
+
+    /**
+     * Calculate the x,y chromaticity coordinates in CIE 1931 x,y chromaticity space from the given
+     * CIE XYZ coordinates.
+     *
+     * @param X the CIE XYZ X coordinate.
+     * @param Y the CIE XYZ Y coordinate.
+     * @param Z the CIE XYZ Z coordinate.
+     *
+     * @return the [x, y] chromaticity coordinates as doubles.
+     */
+    private static double[] calculateCIExyCoordinates(double X, double Y, double Z) {
+        double[] ret = new double[] { 0, 0 };
+        ret[0] = X / (X + Y + Z);
+        ret[1] = Y / (X + Y + Z);
+        return ret;
+    }
+
+    /**
+     * Linearly interpolate between a and b given fraction f.
+     *
+     * @param a first term to interpolate between, a will be returned when f == 0.
+     * @param b second term to interpolate between, b will be returned when f == 1.
+     * @param f the fraction to interpolate by.
+     *
+     * @return interpolated result as double.
+     */
+    private static double lerp(double a, double b, double f) {
+        return (a * (1.0f - f)) + (b * f);
+    }
+
+    /**
+     * Linearly interpolate between 3x3 matrices a and b given fraction f.
+     *
+     * @param a first 3x3 matrix to interpolate between, a will be returned when f == 0.
+     * @param b second 3x3 matrix to interpolate between, b will be returned when f == 1.
+     * @param f the fraction to interpolate by.
+     * @param result will be set to contain the interpolated matrix.
+     */
+    private static void lerp(float[] a, float[] b, double f, /*out*/float[] result) {
+        for (int i = 0; i < 9; i++) {
+            result[i] = (float) lerp(a[i], b[i], f);
+        }
+    }
+
+    /**
+     * Convert a 9x9 {@link ColorSpaceTransform} to a matrix and write the matrix into the
+     * output.
+     *
+     * @param xform a {@link ColorSpaceTransform} to transform.
+     * @param output the 3x3 matrix to overwrite.
+     */
+    private static void convertColorspaceTransform(ColorSpaceTransform xform, /*out*/float[] output) {
+        for (int i = 0; i < 3; i++) {
+            for (int j = 0; j < 3; j++) {
+                output[i * 3 + j] = xform.getElement(j, i).floatValue();
+            }
+        }
+    }
+
+    /**
+     * Find the interpolation factor to use with the RAW matrices given a neutral color point.
+     *
+     * @param referenceIlluminant1 first reference illuminant.
+     * @param referenceIlluminant2 second reference illuminant.
+     * @param calibrationTransform1 calibration matrix corresponding to the first reference
+     *                              illuminant.
+     * @param calibrationTransform2 calibration matrix corresponding to the second reference
+     *                              illuminant.
+     * @param colorMatrix1 color matrix corresponding to the first reference illuminant.
+     * @param colorMatrix2 color matrix corresponding to the second reference illuminant.
+     * @param neutralColorPoint the neutral color point used to calculate the interpolation factor.
+     *
+     * @return the interpolation factor corresponding to the given neutral color point.
+     */
+    private static double findDngInterpolationFactor(int referenceIlluminant1,
+            int referenceIlluminant2, float[] calibrationTransform1, float[] calibrationTransform2,
+            float[] colorMatrix1, float[] colorMatrix2, Rational[/*3*/] neutralColorPoint) {
+
+        int colorTemperature1 = sStandardIlluminants.get(referenceIlluminant1, NO_ILLUMINANT);
+        if (colorTemperature1 == NO_ILLUMINANT) {
+            throw new IllegalArgumentException("No such illuminant for reference illuminant 1: " +
+                    referenceIlluminant1);
+        }
+
+        int colorTemperature2 = sStandardIlluminants.get(referenceIlluminant2, NO_ILLUMINANT);
+        if (colorTemperature2 == NO_ILLUMINANT) {
+            throw new IllegalArgumentException("No such illuminant for reference illuminant 2: " +
+                    referenceIlluminant2);
+        }
+
+        if (DEBUG) Log.d(TAG, "ColorTemperature1: " + colorTemperature1);
+        if (DEBUG) Log.d(TAG, "ColorTemperature2: " + colorTemperature2);
+
+        double interpFactor = 0.5; // Initial guess for interpolation factor
+        double oldInterpFactor = interpFactor;
+
+        double lastDiff = Double.MAX_VALUE;
+        double tolerance = 0.0001;
+        float[] XYZToCamera1 = new float[9];
+        float[] XYZToCamera2 = new float[9];
+        multiply(calibrationTransform1, colorMatrix1, /*out*/XYZToCamera1);
+        multiply(calibrationTransform2, colorMatrix2, /*out*/XYZToCamera2);
+
+        float[] cameraNeutral = new float[] { neutralColorPoint[0].floatValue(),
+                neutralColorPoint[1].floatValue(), neutralColorPoint[2].floatValue()};
+
+        float[] neutralGuess = new float[3];
+        float[] interpXYZToCamera = new float[9];
+        float[] interpXYZToCameraInverse = new float[9];
+
+
+        double lower = Math.min(colorTemperature1, colorTemperature2);
+        double upper = Math.max(colorTemperature1, colorTemperature2);
+
+        if(DEBUG) {
+            Log.d(TAG, "XYZtoCamera1: " + Arrays.toString(XYZToCamera1));
+            Log.d(TAG, "XYZtoCamera2: " + Arrays.toString(XYZToCamera2));
+            Log.d(TAG, "Finding interpolation factor, initial guess 0.5...");
+        }
+        // Iteratively guess xy value, find new CCT, and update interpolation factor.
+        int loopLimit = 30;
+        int count = 0;
+        while (lastDiff > tolerance && loopLimit > 0) {
+            if (DEBUG) Log.d(TAG, "Loop count " + count);
+            lerp(XYZToCamera1, XYZToCamera2, interpFactor, interpXYZToCamera);
+            if (!invert(interpXYZToCamera, /*out*/interpXYZToCameraInverse)) {
+                throw new IllegalArgumentException(
+                        "Cannot invert XYZ to Camera matrix, input matrices are invalid.");
+            }
+
+            map(interpXYZToCameraInverse, cameraNeutral, /*out*/neutralGuess);
+            double[] xy = calculateCIExyCoordinates(neutralGuess[0], neutralGuess[1],
+                    neutralGuess[2]);
+
+            double colorTemperature = calculateColorTemperature(xy[0], xy[1]);
+
+            if (colorTemperature <= lower) {
+                interpFactor = 1;
+            } else if (colorTemperature >= upper) {
+                interpFactor = 0;
+            } else {
+                double invCT = 1.0 / colorTemperature;
+                interpFactor = (invCT - 1.0 / upper) / ( 1.0 / lower - 1.0 / upper);
+            }
+
+            if (lower == colorTemperature1) {
+                interpFactor = 1.0 - interpFactor;
+            }
+
+            interpFactor = (interpFactor + oldInterpFactor) / 2;
+            lastDiff = Math.abs(oldInterpFactor - interpFactor);
+            oldInterpFactor = interpFactor;
+            loopLimit--;
+            count++;
+
+            if (DEBUG) {
+                Log.d(TAG, "CameraToXYZ chosen: " + Arrays.toString(interpXYZToCameraInverse));
+                Log.d(TAG, "XYZ neutral color guess: " + Arrays.toString(neutralGuess));
+                Log.d(TAG, "xy coordinate: " + Arrays.toString(xy));
+                Log.d(TAG, "xy color temperature: " + colorTemperature);
+                Log.d(TAG, "New interpolation factor: " + interpFactor);
+            }
+        }
+
+        if (loopLimit == 0) {
+            Log.w(TAG, "Could not converge on interpolation factor, using factor " + interpFactor +
+                    " with remaining error factor of " + lastDiff);
+        }
+        return interpFactor;
+    }
+
+    /**
+     * Calculate the transform from the raw camera sensor colorspace to CIE XYZ colorspace with a
+     * D50 whitepoint.
+     *
+     * @param forwardTransform1 forward transform matrix corresponding to the first reference
+     *                          illuminant.
+     * @param forwardTransform2 forward transform matrix corresponding to the second reference
+     *                          illuminant.
+     * @param calibrationTransform1 calibration transform matrix corresponding to the first
+     *                              reference illuminant.
+     * @param calibrationTransform2 calibration transform matrix corresponding to the second
+     *                              reference illuminant.
+     * @param neutralColorPoint the neutral color point used to calculate the interpolation factor.
+     * @param interpolationFactor the interpolation factor to use for the forward and
+     *                            calibration transforms.
+     * @param outputTransform set to the full sensor to XYZ colorspace transform.
+     */
+    private static void calculateCameraToXYZD50Transform(float[] forwardTransform1,
+            float[] forwardTransform2, float[] calibrationTransform1, float[] calibrationTransform2,
+            Rational[/*3*/] neutralColorPoint, double interpolationFactor,
+            /*out*/float[] outputTransform) {
+        float[] cameraNeutral = new float[] { neutralColorPoint[0].floatValue(),
+                neutralColorPoint[1].floatValue(), neutralColorPoint[2].floatValue()};
+        if (DEBUG) Log.d(TAG, "Camera neutral: " + Arrays.toString(cameraNeutral));
+
+        float[] interpolatedCC = new float[9];
+        lerp(calibrationTransform1, calibrationTransform2, interpolationFactor,
+                interpolatedCC);
+        float[] inverseInterpolatedCC = new float[9];
+        if (!invert(interpolatedCC, /*out*/inverseInterpolatedCC)) {
+            throw new IllegalArgumentException( "Cannot invert interpolated calibration transform" +
+                    ", input matrices are invalid.");
+        }
+        if (DEBUG) Log.d(TAG, "Inverted interpolated CalibrationTransform: " +
+                Arrays.toString(inverseInterpolatedCC));
+
+        float[] referenceNeutral = new float[3];
+        map(inverseInterpolatedCC, cameraNeutral, /*out*/referenceNeutral);
+        if (DEBUG) Log.d(TAG, "Reference neutral: " + Arrays.toString(referenceNeutral));
+        float[] D = new float[] { 1/referenceNeutral[0], 0, 0,  0, 1/referenceNeutral[1], 0, 0, 0,
+                1/referenceNeutral[2] };
+        if (DEBUG) Log.d(TAG, "Reference Neutral Diagonal: " + Arrays.toString(D));
+
+        float[] intermediate = new float[9];
+        float[] intermediate2 = new float[9];
+
+        lerp(forwardTransform1, forwardTransform2, interpolationFactor, /*out*/intermediate);
+        if (DEBUG) Log.d(TAG, "Interpolated ForwardTransform: " + Arrays.toString(intermediate));
+
+        multiply(D, inverseInterpolatedCC, /*out*/intermediate2);
+        multiply(intermediate, intermediate2, /*out*/outputTransform);
+    }
+
+    /**
+     * Map a 3d column vector using the given matrix.
+     *
+     * @param matrix float array containing 3x3 matrix to map vector by.
+     * @param input 3 dimensional vector to map.
+     * @param output 3 dimensional vector result.
+     */
+    private static void map(float[] matrix, float[] input, /*out*/float[] output) {
+        output[0] = input[0] * matrix[0] + input[1] * matrix[1] + input[2] * matrix[2];
+        output[1] = input[0] * matrix[3] + input[1] * matrix[4] + input[2] * matrix[5];
+        output[2] = input[0] * matrix[6] + input[1] * matrix[7] + input[2] * matrix[8];
+    }
+
+    /**
+     * Multiply two 3x3 matrices together: A * B
+     *
+     * @param a left matrix.
+     * @param b right matrix.
+     */
+    private static void multiply(float[] a, float[] b, /*out*/float[] output) {
+        output[0] = a[0] * b[0] + a[1] * b[3] + a[2] * b[6];
+        output[3] = a[3] * b[0] + a[4] * b[3] + a[5] * b[6];
+        output[6] = a[6] * b[0] + a[7] * b[3] + a[8] * b[6];
+        output[1] = a[0] * b[1] + a[1] * b[4] + a[2] * b[7];
+        output[4] = a[3] * b[1] + a[4] * b[4] + a[5] * b[7];
+        output[7] = a[6] * b[1] + a[7] * b[4] + a[8] * b[7];
+        output[2] = a[0] * b[2] + a[1] * b[5] + a[2] * b[8];
+        output[5] = a[3] * b[2] + a[4] * b[5] + a[5] * b[8];
+        output[8] = a[6] * b[2] + a[7] * b[5] + a[8] * b[8];
+    }
+
+    /**
+     * Transpose a 3x3 matrix in-place.
+     *
+     * @param m the matrix to transpose.
+     * @return the transposed matrix.
+     */
+    private static float[] transpose(/*inout*/float[/*9*/] m) {
+        float t = m[1];
+        m[1] = m[3];
+        m[3] = t;
+        t = m[2];
+        m[2] = m[6];
+        m[6] = t;
+        t = m[5];
+        m[5] = m[7];
+        m[7] = t;
+        return m;
+    }
+
+    /**
+     * Invert a 3x3 matrix, or return false if the matrix is singular.
+     *
+     * @param m matrix to invert.
+     * @param output set the output to be the inverse of m.
+     */
+    private static boolean invert(float[] m, /*out*/float[] output) {
+        double a00 = m[0];
+        double a01 = m[1];
+        double a02 = m[2];
+        double a10 = m[3];
+        double a11 = m[4];
+        double a12 = m[5];
+        double a20 = m[6];
+        double a21 = m[7];
+        double a22 = m[8];
+
+        double t00 = a11 * a22 - a21 * a12;
+        double t01 = a21 * a02 - a01 * a22;
+        double t02 = a01 * a12 - a11 * a02;
+        double t10 = a20 * a12 - a10 * a22;
+        double t11 = a00 * a22 - a20 * a02;
+        double t12 = a10 * a02 - a00 * a12;
+        double t20 = a10 * a21 - a20 * a11;
+        double t21 = a20 * a01 - a00 * a21;
+        double t22 = a00 * a11 - a10 * a01;
+
+        double det = a00 * t00 + a01 * t10 + a02 * t20;
+        if (Math.abs(det) < 1e-9) {
+            return false; // Inverse too close to zero, not invertible.
+        }
+
+        output[0] = (float) (t00 / det);
+        output[1] = (float) (t01 / det);
+        output[2] = (float) (t02 / det);
+        output[3] = (float) (t10 / det);
+        output[4] = (float) (t11 / det);
+        output[5] = (float) (t12 / det);
+        output[6] = (float) (t20 / det);
+        output[7] = (float) (t21 / det);
+        output[8] = (float) (t22 / det);
+        return true;
+    }
+
+    /**
+     * Scale each element in a matrix by the given scaling factor.
+     *
+     * @param factor factor to scale by.
+     * @param matrix the float array containing a 3x3 matrix to scale.
+     */
+    private static void scale(float factor, /*inout*/float[] matrix) {
+        for (int i = 0; i < 9; i++) {
+            matrix[i] *= factor;
+        }
+    }
+
+    /**
+     * Clamp a value to a given range.
+     *
+     * @param low lower bound to clamp to.
+     * @param high higher bound to clamp to.
+     * @param value the value to clamp.
+     * @return the clamped value.
+     */
+    private static double clamp(double low, double high, double value) {
+        return Math.max(low, Math.min(high, value));
+    }
+
+    /**
+     * Return the max float in the array.
+     *
+     * @param array array of floats to search.
+     * @return max float in the array.
+     */
+    private static float max(float[] array) {
+        float val = array[0];
+        for (float f : array) {
+            val = (f > val) ? f : val;
+        }
+        return val;
+    }
+
+    /**
+     * Normalize ColorMatrix to eliminate headroom for input space scaled to [0, 1] using
+     * the D50 whitepoint.  This maps the D50 whitepoint into the colorspace used by the
+     * ColorMatrix, then uses the resulting whitepoint to renormalize the ColorMatrix so
+     * that the channel values in the resulting whitepoint for this operation are clamped
+     * to the range [0, 1].
+     *
+     * @param colorMatrix a 3x3 matrix containing a DNG ColorMatrix to be normalized.
+     */
+    private static void normalizeCM(/*inout*/float[] colorMatrix) {
+        float[] tmp = new float[3];
+        map(colorMatrix, D50_XYZ, /*out*/tmp);
+        float maxVal = max(tmp);
+        if (maxVal > 0) {
+            scale(1.0f / maxVal, colorMatrix);
+        }
+    }
+
+    /**
+     * Normalize ForwardMatrix to ensure that sensor whitepoint [1, 1, 1] maps to D50 in CIE XYZ
+     * colorspace.
+     *
+     * @param forwardMatrix a 3x3 matrix containing a DNG ForwardTransform to be normalized.
+     */
+    private static void normalizeFM(/*inout*/float[] forwardMatrix) {
+        float[] tmp = new float[] {1, 1, 1};
+        float[] xyz = new float[3];
+        map(forwardMatrix, tmp, /*out*/xyz);
+
+        float[] intermediate = new float[9];
+        float[] m = new float[] {1.0f / xyz[0], 0, 0, 0, 1.0f / xyz[1], 0, 0, 0, 1.0f / xyz[2]};
+
+        multiply(m, forwardMatrix, /*out*/ intermediate);
+        float[] m2 = new float[] {D50_XYZ[0], 0, 0, 0, D50_XYZ[1], 0, 0, 0, D50_XYZ[2]};
+        multiply(m2, intermediate, /*out*/forwardMatrix);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/raw_converter.rs b/tests/tests/hardware/src/android/hardware/camera2/cts/rs/raw_converter.rs
new file mode 100644
index 0000000..c8b353e
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/rs/raw_converter.rs
@@ -0,0 +1,369 @@
+/*
+ * Copyright 2015 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.
+ */
+
+#include "../common.rs"
+
+// This file includes a conversion kernel for RGGB, GRBG, GBRG, and BGGR Bayer patterns.
+// Applying this script also will apply black-level subtraction, rescaling, clipping, tonemapping,
+// and color space transforms along with the Bayer demosaic.  See RawConverter.java
+// for more information.
+
+// Input globals
+
+rs_allocation inputRawBuffer; // RAW16 buffer of dimensions (raw image stride) * (raw image height)
+rs_allocation gainMap; // Gainmap to apply to linearized raw sensor data.
+uint cfaPattern; // The Color Filter Arrangement pattern used
+uint gainMapWidth;  // The width of the gain map
+uint gainMapHeight;  // The height of the gain map
+bool hasGainMap; // Does gainmap exist?
+rs_matrix3x3 sensorToIntermediate; // Color transform from sensor to a wide-gamut colorspace
+rs_matrix3x3 intermediateToSRGB; // Color transform from wide-gamut colorspace to sRGB
+ushort4 blackLevelPattern; // Blacklevel to subtract for each channel, given in CFA order
+int whiteLevel;  // Whitelevel of sensor
+uint offsetX; // X offset into inputRawBuffer
+uint offsetY; // Y offset into inputRawBuffer
+uint rawWidth; // Width of raw buffer
+uint rawHeight; // Height of raw buffer
+float3 neutralPoint; // The camera neutral
+float4 toneMapCoeffs; // Coefficients for a polynomial tonemapping curve
+
+// Interpolate gain map to find per-channel gains at a given pixel
+static float4 getGain(uint x, uint y) {
+    float interpX = (((float) x) / rawWidth) * gainMapWidth;
+    float interpY = (((float) y) / rawHeight) * gainMapHeight;
+    uint gX = (uint) interpX;
+    uint gY = (uint) interpY;
+    uint gXNext = (gX + 1 < gainMapWidth) ? gX + 1 : gX;
+    uint gYNext = (gY + 1 < gainMapHeight) ? gY + 1 : gY;
+
+    float4 tl = *((float4 *) rsGetElementAt(gainMap, gX, gY));
+    float4 tr = *((float4 *) rsGetElementAt(gainMap, gXNext, gY));
+    float4 bl = *((float4 *) rsGetElementAt(gainMap, gX, gYNext));
+    float4 br = *((float4 *) rsGetElementAt(gainMap, gXNext, gYNext));
+
+    float fracX = interpX - (float) gX;
+    float fracY = interpY - (float) gY;
+    float invFracX = 1.f - fracX;
+    float invFracY = 1.f - fracY;
+
+    return tl * invFracX * invFracY + tr * fracX * invFracY +
+            bl * invFracX * fracY + br * fracX * fracY;
+}
+
+// Apply gamma correction using sRGB gamma curve
+static float gammaEncode(float x) {
+    return (x <= 0.0031308f) ? x * 12.92f : 1.055f * pow(x, 0.4166667f) - 0.055f;
+}
+
+// Apply gamma correction to each color channel in RGB pixel
+static float3 gammaCorrectPixel(float3 rgb) {
+    float3 ret;
+    ret.x = gammaEncode(rgb.x);
+    ret.y = gammaEncode(rgb.y);
+    ret.z = gammaEncode(rgb.z);
+    return ret;
+}
+
+// Apply polynomial tonemapping curve to each color channel in RGB pixel.
+// This attempts to apply tonemapping without changing the hue of each pixel,
+// i.e.:
+//
+// For some RGB values:
+// M = max(R, G, B)
+// m = min(R, G, B)
+// m' = mid(R, G, B)
+// chroma = M - m
+// H = m' - m / chroma
+//
+// The relationship H=H' should be preserved, where H and H' are calculated from
+// the RGB and RGB' value at this pixel before and after this tonemapping
+// operation has been applied, respectively.
+static float3 tonemap(float3 rgb) {
+    float3 sorted = clamp(rgb, 0.f, 1.f);
+    float tmp;
+    int permutation = 0;
+
+    // Sort the RGB channels by value
+    if (sorted.z < sorted.y) {
+        tmp = sorted.z;
+        sorted.z = sorted.y;
+        sorted.y = tmp;
+        permutation |= 1;
+    }
+    if (sorted.y < sorted.x) {
+        tmp = sorted.y;
+        sorted.y = sorted.x;
+        sorted.x = tmp;
+        permutation |= 2;
+    }
+    if (sorted.z < sorted.y) {
+        tmp = sorted.z;
+        sorted.z = sorted.y;
+        sorted.y = tmp;
+        permutation |= 4;
+    }
+
+    float2 minmax;
+    minmax.x = sorted.x;
+    minmax.y = sorted.z;
+
+    // Apply tonemapping curve to min, max RGB channel values
+    minmax = native_powr(minmax, 3.f) * toneMapCoeffs.x +
+            native_powr(minmax, 2.f) * toneMapCoeffs.y +
+            minmax * toneMapCoeffs.z + toneMapCoeffs.w;
+
+    // Rescale middle value
+    float newMid;
+    if (sorted.z == sorted.x) {
+        newMid = minmax.y;
+    } else {
+        newMid = minmax.x + ((minmax.y - minmax.x) * (sorted.y - sorted.x) /
+                (sorted.z - sorted.x));
+    }
+
+    float3 finalRGB;
+    switch (permutation) {
+        case 0: // b >= g >= r
+            finalRGB.x = minmax.x;
+            finalRGB.y = newMid;
+            finalRGB.z = minmax.y;
+            break;
+        case 1: // g >= b >= r
+            finalRGB.x = minmax.x;
+            finalRGB.z = newMid;
+            finalRGB.y = minmax.y;
+            break;
+        case 2: // b >= r >= g
+            finalRGB.y = minmax.x;
+            finalRGB.x = newMid;
+            finalRGB.z = minmax.y;
+            break;
+        case 3: // g >= r >= b
+            finalRGB.z = minmax.x;
+            finalRGB.x = newMid;
+            finalRGB.y = minmax.y;
+            break;
+        case 6: // r >= b >= g
+            finalRGB.y = minmax.x;
+            finalRGB.z = newMid;
+            finalRGB.x = minmax.y;
+            break;
+        case 7: // r >= g >= b
+            finalRGB.z = minmax.x;
+            finalRGB.y = newMid;
+            finalRGB.x = minmax.y;
+            break;
+        case 4: // impossible
+        case 5: // impossible
+        default:
+            LOGD("raw_converter.rs: Logic error in tonemap.", 0);
+            break;
+    }
+    return clamp(finalRGB, 0.f, 1.f);
+}
+
+// Apply a colorspace transform to the intermediate colorspace, apply
+// a tonemapping curve, apply a colorspace transform to a final colorspace,
+// and apply a gamma correction curve.
+static float3 applyColorspace(float3 pRGB) {
+    pRGB.x = clamp(pRGB.x, 0.f, neutralPoint.x);
+    pRGB.y = clamp(pRGB.y, 0.f, neutralPoint.y);
+    pRGB.z = clamp(pRGB.z, 0.f, neutralPoint.z);
+
+    float3 intermediate = rsMatrixMultiply(&sensorToIntermediate, pRGB);
+    intermediate = tonemap(intermediate);
+    return gammaCorrectPixel(clamp(rsMatrixMultiply(&intermediateToSRGB, intermediate), 0.f, 1.f));
+}
+
+// Load a 3x3 patch of pixels into the output.
+static void load3x3(uint x, uint y, rs_allocation buf, /*out*/float* outputArray) {
+    outputArray[0] = *((ushort *) rsGetElementAt(buf, x - 1, y - 1));
+    outputArray[1] = *((ushort *) rsGetElementAt(buf, x, y - 1));
+    outputArray[2] = *((ushort *) rsGetElementAt(buf, x + 1, y - 1));
+    outputArray[3] = *((ushort *) rsGetElementAt(buf, x - 1, y));
+    outputArray[4] = *((ushort *) rsGetElementAt(buf, x, y));
+    outputArray[5] = *((ushort *) rsGetElementAt(buf, x + 1, y));
+    outputArray[6] = *((ushort *) rsGetElementAt(buf, x - 1, y + 1));
+    outputArray[7] = *((ushort *) rsGetElementAt(buf, x, y + 1));
+    outputArray[8] = *((ushort *) rsGetElementAt(buf, x + 1, y + 1));
+}
+
+// Blacklevel subtract, and normalize each pixel in the outputArray, and apply the
+// gain map.
+static void linearizeAndGainmap(uint x, uint y, ushort4 blackLevel, int whiteLevel,
+        uint cfa, /*inout*/float* outputArray) {
+    uint kk = 0;
+    for (uint j = y - 1; j <= y + 1; j++) {
+        for (uint i = x - 1; i <= x + 1; i++) {
+            uint index = (i & 1) | ((j & 1) << 1);  // bits [0,1] are blacklevel offset
+            index |= (cfa << 2);  // bits [2,3] are cfa
+            float bl = 0.f;
+            float g = 1.f;
+            float4 gains = 1.f;
+            if (hasGainMap) {
+                gains = getGain(i, j);
+            }
+            switch (index) {
+                // RGGB
+                case 0:
+                    bl = blackLevel.x;
+                    g = gains.x;
+                    break;
+                case 1:
+                    bl = blackLevel.y;
+                    g = gains.y;
+                    break;
+                case 2:
+                    bl = blackLevel.z;
+                    g = gains.z;
+                    break;
+                case 3:
+                    bl = blackLevel.w;
+                    g = gains.w;
+                    break;
+                // GRBG
+                case 4:
+                    bl = blackLevel.x;
+                    g = gains.y;
+                    break;
+                case 5:
+                    bl = blackLevel.y;
+                    g = gains.x;
+                    break;
+                case 6:
+                    bl = blackLevel.z;
+                    g = gains.w;
+                    break;
+                case 7:
+                    bl = blackLevel.w;
+                    g = gains.z;
+                    break;
+                // GBRG
+                case 8:
+                    bl = blackLevel.x;
+                    g = gains.y;
+                    break;
+                case 9:
+                    bl = blackLevel.y;
+                    g = gains.w;
+                    break;
+                case 10:
+                    bl = blackLevel.z;
+                    g = gains.x;
+                    break;
+                case 11:
+                    bl = blackLevel.w;
+                    g = gains.z;
+                    break;
+                // BGGR
+                case 12:
+                    bl = blackLevel.x;
+                    g = gains.w;
+                    break;
+                case 13:
+                    bl = blackLevel.y;
+                    g = gains.y;
+                    break;
+                case 14:
+                    bl = blackLevel.z;
+                    g = gains.z;
+                    break;
+                case 15:
+                    bl = blackLevel.w;
+                    g = gains.x;
+                    break;
+            }
+            outputArray[kk] = clamp(g * (outputArray[kk] - bl) / (whiteLevel - bl), 0.f, 1.f);
+            kk++;
+        }
+    }
+}
+
+// Apply bilinear-interpolation to demosaic
+static float3 demosaic(uint x, uint y, uint cfa, float* inputArray) {
+    uint index = (x & 1) | ((y & 1) << 1);
+    index |= (cfa << 2);
+    float3 pRGB;
+    switch (index) {
+        case 0:
+        case 5:
+        case 10:
+        case 15:  // Red centered
+                  // B G B
+                  // G R G
+                  // B G B
+            pRGB.x = inputArray[4];
+            pRGB.y = (inputArray[1] + inputArray[3] + inputArray[5] + inputArray[7]) / 4;
+            pRGB.z = (inputArray[0] + inputArray[2] + inputArray[6] + inputArray[8]) / 4;
+            break;
+        case 1:
+        case 4:
+        case 11:
+        case 14: // Green centered w/ horizontally adjacent Red
+                 // G B G
+                 // R G R
+                 // G B G
+            pRGB.x = (inputArray[3] + inputArray[5]) / 2;
+            pRGB.y = inputArray[4];
+            pRGB.z = (inputArray[1] + inputArray[7]) / 2;
+            break;
+        case 2:
+        case 7:
+        case 8:
+        case 13: // Green centered w/ horizontally adjacent Blue
+                 // G R G
+                 // B G B
+                 // G R G
+            pRGB.x = (inputArray[1] + inputArray[7]) / 2;
+            pRGB.y = inputArray[4];
+            pRGB.z = (inputArray[3] + inputArray[5]) / 2;
+            break;
+        case 3:
+        case 6:
+        case 9:
+        case 12: // Blue centered
+                 // R G R
+                 // G B G
+                 // R G R
+            pRGB.x = (inputArray[0] + inputArray[2] + inputArray[6] + inputArray[8]) / 4;
+            pRGB.y = (inputArray[1] + inputArray[3] + inputArray[5] + inputArray[7]) / 4;
+            pRGB.z = inputArray[4];
+            break;
+    }
+
+    return pRGB;
+}
+
+// Full RAW->ARGB bitmap conversion kernel
+uchar4 RS_KERNEL convert_RAW_To_ARGB(uint x, uint y) {
+    float3 pRGB;
+    uint xP = x + offsetX;
+    uint yP = y + offsetY;
+    if (xP == 0) xP = 1;
+    if (yP == 0) yP = 1;
+    if (xP == rawWidth - 1) xP = rawWidth - 2;
+    if (yP == rawHeight - 1) yP = rawHeight  - 2;
+
+    float patch[9];
+    // TODO: Once ScriptGroup and RS kernels have been updated to allow for iteration over 3x3 pixel
+    // patches, this can be optimized to avoid re-applying the pre-demosaic steps for each pixel,
+    // potentially achieving a 9x speedup here.
+    load3x3(xP, yP, inputRawBuffer, /*out*/ patch);
+    linearizeAndGainmap(xP, yP, blackLevelPattern, whiteLevel, cfaPattern, /*inout*/patch);
+    pRGB = demosaic(xP, yP, cfaPattern, patch);
+
+    return rsPackColorTo8888(applyColorspace(pRGB));
+}
