diff --git a/jni/Android.bp b/jni/Android.bp
new file mode 100644
index 0000000..22840ea
--- /dev/null
+++ b/jni/Android.bp
@@ -0,0 +1,40 @@
+//  Copyright (C) 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 {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library_shared {
+    name: "libgiftranscode",
+    static_libs: ["libgif"],
+    // Link to Android logging (liblog.so) and dynamic linker (libdl.so) libraries
+    shared_libs: [
+        "liblog",
+        "libdl",
+    ],
+    // for including the jni.h file
+    header_libs: ["jni_headers"],
+    include_dirs: ["external/giflib"],
+    srcs: ["GifTranscoder.cpp"],
+    cflags: [
+        "-Wno-unused-parameter",
+        "-Wno-switch",
+    ],
+    sdk_version: "19",
+    // LLVM libc++
+    stl: "c++_static",
+    product_specific: true,
+}
diff --git a/jni/GifTranscoder.cpp b/jni/GifTranscoder.cpp
new file mode 100644
index 0000000..324d315
--- /dev/null
+++ b/jni/GifTranscoder.cpp
@@ -0,0 +1,583 @@
+/*
+ * Copyright (C) 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 <jni.h>
+#include <time.h>
+#include <stdio.h>
+#include <memory>
+#include <vector>
+
+#include <android/log.h>
+
+#include "GifTranscoder.h"
+
+#define SQUARE(a) ((a)*(a))
+
+// GIF does not support partial transparency, so our alpha channels are always 0x0 or 0xff.
+static const ColorARGB TRANSPARENT = 0x0;
+
+#define ALPHA(color) (((color) >> 24) & 0xff)
+#define RED(color)   (((color) >> 16) & 0xff)
+#define GREEN(color) (((color) >>  8) & 0xff)
+#define BLUE(color)  (((color) >>  0) & 0xff)
+
+#define MAKE_COLOR_ARGB(a, r, g, b) \
+    ((a) << 24 | (r) << 16 | (g) << 8 | (b))
+
+#define MAX_COLOR_DISTANCE (255 * 255 * 255)
+
+#define TAG "GifTranscoder.cpp"
+#define LOGD_ENABLED 0
+#if LOGD_ENABLED
+#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__))
+#else
+#define LOGD(...) ((void)0)
+#endif
+#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__))
+#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__))
+#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__))
+
+// This macro expects the assertion to pass, but logs a FATAL if not.
+#define ASSERT(cond, ...) \
+    ( (__builtin_expect((cond) == 0, 0)) \
+    ? ((void)__android_log_assert(#cond, TAG, ## __VA_ARGS__)) \
+    : (void) 0 )
+#define ASSERT_ENABLED 1
+
+namespace {
+
+// Current time in milliseconds since Unix epoch.
+double now(void) {
+    struct timespec res;
+    clock_gettime(CLOCK_REALTIME, &res);
+    return 1000.0 * res.tv_sec + (double) res.tv_nsec / 1e6;
+}
+
+// Gets the pixel at position (x,y) from a buffer that uses row-major order to store an image with
+// the specified width.
+template <typename T>
+T* getPixel(T* buffer, int width, int x, int y) {
+    return buffer + (y * width + x);
+}
+
+} // namespace
+
+int GifTranscoder::transcode(const char* pathIn, const char* pathOut) {
+    int error;
+    double t0;
+    GifFileType* gifIn;
+    GifFileType* gifOut;
+
+    // Automatically closes the GIF files when this method returns
+    GifFilesCloser closer;
+
+    gifIn = DGifOpenFileName(pathIn, &error);
+    if (gifIn) {
+        closer.setGifIn(gifIn);
+        LOGD("Opened input GIF: %s", pathIn);
+    } else {
+        LOGE("Could not open input GIF: %s, error = %d", pathIn, error);
+        return GIF_ERROR;
+    }
+
+    gifOut = EGifOpenFileName(pathOut, false, &error);
+    if (gifOut) {
+        closer.setGifOut(gifOut);
+        LOGD("Opened output GIF: %s", pathOut);
+    } else {
+        LOGE("Could not open output GIF: %s, error = %d", pathOut, error);
+        return GIF_ERROR;
+    }
+
+    t0 = now();
+    if (resizeBoxFilter(gifIn, gifOut)) {
+        LOGD("Resized GIF in %.2f ms", now() - t0);
+    } else {
+        LOGE("Could not resize GIF");
+        return GIF_ERROR;
+    }
+
+    return GIF_OK;
+}
+
+bool GifTranscoder::resizeBoxFilter(GifFileType* gifIn, GifFileType* gifOut) {
+    ASSERT(gifIn != NULL, "gifIn cannot be NULL");
+    ASSERT(gifOut != NULL, "gifOut cannot be NULL");
+
+    if (gifIn->SWidth < 0 || gifIn->SHeight < 0) {
+        LOGE("Input GIF has invalid size: %d x %d", gifIn->SWidth, gifIn->SHeight);
+        return false;
+    }
+
+    // Output GIF will be 50% the size of the original.
+    if (EGifPutScreenDesc(gifOut,
+                          gifIn->SWidth / 2,
+                          gifIn->SHeight / 2,
+                          gifIn->SColorResolution,
+                          gifIn->SBackGroundColor,
+                          gifIn->SColorMap) == GIF_ERROR) {
+        LOGE("Could not write screen descriptor");
+        return false;
+    }
+    LOGD("Wrote screen descriptor");
+
+    // Index of the current image.
+    int imageIndex = 0;
+
+    // Transparent color of the current image.
+    int transparentColor = NO_TRANSPARENT_COLOR;
+
+    // Buffer for reading raw images from the input GIF.
+    std::vector<GifByteType> srcBuffer(gifIn->SWidth * gifIn->SHeight);
+
+    // Buffer for rendering images from the input GIF.
+    std::unique_ptr<ColorARGB[]> renderBuffer(new ColorARGB[gifIn->SWidth * gifIn->SHeight]);
+
+    // Buffer for writing new images to output GIF (one row at a time).
+    std::unique_ptr<GifByteType[]> dstRowBuffer(new GifByteType[gifOut->SWidth]);
+
+    // Many GIFs use DISPOSE_DO_NOT to make images draw on top of previous images. They can also
+    // use DISPOSE_BACKGROUND to clear the last image region before drawing the next one. We need
+    // to keep track of the disposal mode as we go along to properly render the GIF.
+    int disposalMode = DISPOSAL_UNSPECIFIED;
+    int prevImageDisposalMode = DISPOSAL_UNSPECIFIED;
+    GifImageDesc prevImageDimens;
+
+    // Background color (applies to entire GIF).
+    ColorARGB bgColor = TRANSPARENT;
+
+    GifRecordType recordType;
+    do {
+        if (DGifGetRecordType(gifIn, &recordType) == GIF_ERROR) {
+            LOGE("Could not get record type");
+            return false;
+        }
+        LOGD("Read record type: %d", recordType);
+        switch (recordType) {
+            case IMAGE_DESC_RECORD_TYPE: {
+                if (DGifGetImageDesc(gifIn) == GIF_ERROR) {
+                    LOGE("Could not read image descriptor (%d)", imageIndex);
+                    return false;
+                }
+
+                // Check the current image position.
+                if (gifIn->Image.Left < 0 ||
+                        gifIn->Image.Top < 0 ||
+                        gifIn->Image.Left + gifIn->Image.Width > gifIn->SWidth ||
+                        gifIn->Image.Top + gifIn->Image.Height > gifIn->SHeight) {
+                    LOGE("GIF image extends beyond logical screen");
+                    return false;
+                }
+
+                // Write the new image descriptor.
+                if (EGifPutImageDesc(gifOut,
+                                     0, // Left
+                                     0, // Top
+                                     gifOut->SWidth,
+                                     gifOut->SHeight,
+                                     false, // Interlace
+                                     gifIn->Image.ColorMap) == GIF_ERROR) {
+                    LOGE("Could not write image descriptor (%d)", imageIndex);
+                    return false;
+                }
+
+                // Read the image from the input GIF. The buffer is already initialized to the
+                // size of the GIF, which is usually equal to the size of all the images inside it.
+                // If not, the call to resize below ensures that the buffer is the right size.
+                srcBuffer.resize(gifIn->Image.Width * gifIn->Image.Height);
+                if (readImage(gifIn, srcBuffer.data()) == false) {
+                    LOGE("Could not read image data (%d)", imageIndex);
+                    return false;
+                }
+                LOGD("Read image data (%d)", imageIndex);
+                // Render the image from the input GIF.
+                if (renderImage(gifIn,
+                                srcBuffer.data(),
+                                imageIndex,
+                                transparentColor,
+                                renderBuffer.get(),
+                                bgColor,
+                                prevImageDimens,
+                                prevImageDisposalMode) == false) {
+                    LOGE("Could not render %d", imageIndex);
+                    return false;
+                }
+                LOGD("Rendered image (%d)", imageIndex);
+
+                // Generate the image in the output GIF.
+                for (int y = 0; y < gifOut->SHeight; y++) {
+                    for (int x = 0; x < gifOut->SWidth; x++) {
+                      const GifByteType dstColorIndex = computeNewColorIndex(
+                          gifIn, transparentColor, renderBuffer.get(), x, y);
+                      *(dstRowBuffer.get() + x) = dstColorIndex;
+                    }
+                    if (EGifPutLine(gifOut, dstRowBuffer.get(), gifOut->SWidth) == GIF_ERROR) {
+                        LOGE("Could not write raster data (%d)", imageIndex);
+                        return false;
+                    }
+                }
+                LOGD("Wrote raster data (%d)", imageIndex);
+
+                // Save the disposal mode for rendering the next image.
+                // We only support DISPOSE_DO_NOT and DISPOSE_BACKGROUND.
+                prevImageDisposalMode = disposalMode;
+                if (prevImageDisposalMode == DISPOSAL_UNSPECIFIED) {
+                    prevImageDisposalMode = DISPOSE_DO_NOT;
+                } else if (prevImageDisposalMode == DISPOSE_PREVIOUS) {
+                    prevImageDisposalMode = DISPOSE_BACKGROUND;
+                }
+                if (prevImageDisposalMode == DISPOSE_BACKGROUND) {
+                    prevImageDimens.Left = gifIn->Image.Left;
+                    prevImageDimens.Top = gifIn->Image.Top;
+                    prevImageDimens.Width = gifIn->Image.Width;
+                    prevImageDimens.Height = gifIn->Image.Height;
+                }
+
+                if (gifOut->Image.ColorMap) {
+                    GifFreeMapObject(gifOut->Image.ColorMap);
+                    gifOut->Image.ColorMap = NULL;
+                }
+
+                imageIndex++;
+            } break;
+            case EXTENSION_RECORD_TYPE: {
+                int extCode;
+                GifByteType* ext;
+                if (DGifGetExtension(gifIn, &extCode, &ext) == GIF_ERROR) {
+                    LOGE("Could not read extension block");
+                    return false;
+                }
+                LOGD("Read extension block, code: %d", extCode);
+                if (extCode == GRAPHICS_EXT_FUNC_CODE) {
+                    GraphicsControlBlock gcb;
+                    if (DGifExtensionToGCB(ext[0], ext + 1, &gcb) == GIF_ERROR) {
+                        LOGE("Could not interpret GCB extension");
+                        return false;
+                    }
+                    transparentColor = gcb.TransparentColor;
+
+                    // This logic for setting the background color based on the first GCB
+                    // doesn't quite match the GIF spec, but empirically it seems to work and it
+                    // matches what libframesequence (Rastermill) does.
+                    if (imageIndex == 0 && gifIn->SColorMap) {
+                        if (gcb.TransparentColor == NO_TRANSPARENT_COLOR) {
+                            if (gifIn->SBackGroundColor < 0 ||
+                                gifIn->SBackGroundColor >= gifIn->SColorMap->ColorCount) {
+                                LOGE("SBackGroundColor overflow");
+                                return false;
+                            }
+                            GifColorType bgColorIndex =
+                                    gifIn->SColorMap->Colors[gifIn->SBackGroundColor];
+                            bgColor = gifColorToColorARGB(bgColorIndex);
+                            LOGD("Set background color based on first GCB");
+                        }
+                    }
+
+                    // Record the original disposal mode and then update it.
+                    disposalMode = gcb.DisposalMode;
+                    gcb.DisposalMode = DISPOSE_BACKGROUND;
+                    EGifGCBToExtension(&gcb, ext + 1);
+                }
+                if (EGifPutExtensionLeader(gifOut, extCode) == GIF_ERROR) {
+                    LOGE("Could not write extension leader");
+                    return false;
+                }
+                if (EGifPutExtensionBlock(gifOut, ext[0], ext + 1) == GIF_ERROR) {
+                    LOGE("Could not write extension block");
+                    return false;
+                }
+                LOGD("Wrote extension block");
+                while (ext != NULL) {
+                    if (DGifGetExtensionNext(gifIn, &ext) == GIF_ERROR) {
+                        LOGE("Could not read extension continuation");
+                        return false;
+                    }
+                    if (ext != NULL) {
+                        LOGD("Read extension continuation");
+                        if (EGifPutExtensionBlock(gifOut, ext[0], ext + 1) == GIF_ERROR) {
+                            LOGE("Could not write extension continuation");
+                            return false;
+                        }
+                        LOGD("Wrote extension continuation");
+                    }
+                }
+                if (EGifPutExtensionTrailer(gifOut) == GIF_ERROR) {
+                    LOGE("Could not write extension trailer");
+                    return false;
+                }
+            } break;
+        }
+
+    } while (recordType != TERMINATE_RECORD_TYPE);
+    LOGD("No more records");
+
+    return true;
+}
+
+bool GifTranscoder::readImage(GifFileType* gifIn, GifByteType* rasterBits) {
+    if (gifIn->Image.Interlace) {
+        int interlacedOffset[] = { 0, 4, 2, 1 };
+        int interlacedJumps[] = { 8, 8, 4, 2 };
+
+        // Need to perform 4 passes on the image
+        for (int i = 0; i < 4; i++) {
+            for (int j = interlacedOffset[i]; j < gifIn->Image.Height; j += interlacedJumps[i]) {
+                if (DGifGetLine(gifIn,
+                                rasterBits + j * gifIn->Image.Width,
+                                gifIn->Image.Width) == GIF_ERROR) {
+                    LOGE("Could not read interlaced raster data");
+                    return false;
+                }
+            }
+        }
+    } else {
+        if (DGifGetLine(gifIn, rasterBits, gifIn->Image.Width * gifIn->Image.Height) == GIF_ERROR) {
+            LOGE("Could not read raster data");
+            return false;
+        }
+    }
+    return true;
+}
+
+bool GifTranscoder::renderImage(GifFileType* gifIn,
+                                GifByteType* rasterBits,
+                                int imageIndex,
+                                int transparentColorIndex,
+                                ColorARGB* renderBuffer,
+                                ColorARGB bgColor,
+                                GifImageDesc prevImageDimens,
+                                int prevImageDisposalMode) {
+    ASSERT(imageIndex < gifIn->ImageCount,
+           "Image index %d is out of bounds (count=%d)", imageIndex, gifIn->ImageCount);
+
+    ColorMapObject* colorMap = getColorMap(gifIn);
+    if (colorMap == NULL) {
+        LOGE("No GIF color map found");
+        return false;
+    }
+
+    // Clear all or part of the background, before drawing the first image and maybe before drawing
+    // subsequent images (depending on the DisposalMode).
+    if (imageIndex == 0) {
+        fillRect(renderBuffer, gifIn->SWidth, gifIn->SHeight,
+                 0, 0, gifIn->SWidth, gifIn->SHeight, bgColor);
+    } else if (prevImageDisposalMode == DISPOSE_BACKGROUND) {
+        fillRect(renderBuffer, gifIn->SWidth, gifIn->SHeight,
+                 prevImageDimens.Left, prevImageDimens.Top,
+                 prevImageDimens.Width, prevImageDimens.Height, TRANSPARENT);
+    }
+
+    // Paint this image onto the canvas
+    for (int y = 0; y < gifIn->Image.Height; y++) {
+        for (int x = 0; x < gifIn->Image.Width; x++) {
+            GifByteType colorIndex = *getPixel(rasterBits, gifIn->Image.Width, x, y);
+            if (colorIndex >= colorMap->ColorCount) {
+                LOGE("Color Index %d is out of bounds (count=%d)", colorIndex,
+                    colorMap->ColorCount);
+                return false;
+            }
+
+            // This image may be smaller than the GIF's "logical screen"
+            int renderX = x + gifIn->Image.Left;
+            int renderY = y + gifIn->Image.Top;
+
+            // Skip drawing transparent pixels if this image renders on top of the last one
+            if (imageIndex > 0 && prevImageDisposalMode == DISPOSE_DO_NOT &&
+                colorIndex == transparentColorIndex) {
+                continue;
+            }
+
+            ColorARGB* renderPixel = getPixel(renderBuffer, gifIn->SWidth, renderX, renderY);
+            *renderPixel = getColorARGB(colorMap, transparentColorIndex, colorIndex);
+        }
+    }
+    return true;
+}
+
+void GifTranscoder::fillRect(ColorARGB* renderBuffer,
+                             int imageWidth,
+                             int imageHeight,
+                             int left,
+                             int top,
+                             int width,
+                             int height,
+                             ColorARGB color) {
+    ASSERT(left + width <= imageWidth, "Rectangle is outside image bounds");
+    ASSERT(top + height <= imageHeight, "Rectangle is outside image bounds");
+
+    for (int y = 0; y < height; y++) {
+        for (int x = 0; x < width; x++) {
+            ColorARGB* renderPixel = getPixel(renderBuffer, imageWidth, x + left, y + top);
+            *renderPixel = color;
+        }
+    }
+}
+
+GifByteType GifTranscoder::computeNewColorIndex(GifFileType* gifIn,
+                                                int transparentColorIndex,
+                                                ColorARGB* renderBuffer,
+                                                int x,
+                                                int y) {
+    ColorMapObject* colorMap = getColorMap(gifIn);
+
+    // Compute the average color of 4 adjacent pixels from the input image.
+    ColorARGB c1 = *getPixel(renderBuffer, gifIn->SWidth, x * 2, y * 2);
+    ColorARGB c2 = *getPixel(renderBuffer, gifIn->SWidth, x * 2 + 1, y * 2);
+    ColorARGB c3 = *getPixel(renderBuffer, gifIn->SWidth, x * 2, y * 2 + 1);
+    ColorARGB c4 = *getPixel(renderBuffer, gifIn->SWidth, x * 2 + 1, y * 2 + 1);
+    ColorARGB avgColor = computeAverage(c1, c2, c3, c4);
+
+    // Search the color map for the best match.
+    return findBestColor(colorMap, transparentColorIndex, avgColor);
+}
+
+ColorARGB GifTranscoder::computeAverage(ColorARGB c1, ColorARGB c2, ColorARGB c3, ColorARGB c4) {
+    char avgAlpha = (char)(((int) ALPHA(c1) + (int) ALPHA(c2) +
+                            (int) ALPHA(c3) + (int) ALPHA(c4)) / 4);
+    char avgRed =   (char)(((int) RED(c1) + (int) RED(c2) +
+                            (int) RED(c3) + (int) RED(c4)) / 4);
+    char avgGreen = (char)(((int) GREEN(c1) + (int) GREEN(c2) +
+                            (int) GREEN(c3) + (int) GREEN(c4)) / 4);
+    char avgBlue =  (char)(((int) BLUE(c1) + (int) BLUE(c2) +
+                            (int) BLUE(c3) + (int) BLUE(c4)) / 4);
+    return MAKE_COLOR_ARGB(avgAlpha, avgRed, avgGreen, avgBlue);
+}
+
+GifByteType GifTranscoder::findBestColor(ColorMapObject* colorMap, int transparentColorIndex,
+                                         ColorARGB targetColor) {
+    // Return the transparent color if the average alpha is zero.
+    char alpha = ALPHA(targetColor);
+    if (alpha == 0 && transparentColorIndex != NO_TRANSPARENT_COLOR) {
+        return transparentColorIndex;
+    }
+
+    GifByteType closestColorIndex = 0;
+    int closestColorDistance = MAX_COLOR_DISTANCE;
+    for (int i = 0; i < colorMap->ColorCount; i++) {
+        // Skip the transparent color (we've already eliminated that option).
+        if (i == transparentColorIndex) {
+            continue;
+        }
+        ColorARGB indexedColor = gifColorToColorARGB(colorMap->Colors[i]);
+        int distance = computeDistance(targetColor, indexedColor);
+        if (distance < closestColorDistance) {
+            closestColorIndex = i;
+            closestColorDistance = distance;
+        }
+    }
+    return closestColorIndex;
+}
+
+int GifTranscoder::computeDistance(ColorARGB c1, ColorARGB c2) {
+    return SQUARE(RED(c1) - RED(c2)) +
+           SQUARE(GREEN(c1) - GREEN(c2)) +
+           SQUARE(BLUE(c1) - BLUE(c2));
+}
+
+ColorMapObject* GifTranscoder::getColorMap(GifFileType* gifIn) {
+    if (gifIn->Image.ColorMap) {
+        return gifIn->Image.ColorMap;
+    }
+    return gifIn->SColorMap;
+}
+
+ColorARGB GifTranscoder::getColorARGB(ColorMapObject* colorMap, int transparentColorIndex,
+                                      GifByteType colorIndex) {
+    if (colorIndex == transparentColorIndex) {
+        return TRANSPARENT;
+    }
+    return gifColorToColorARGB(colorMap->Colors[colorIndex]);
+}
+
+ColorARGB GifTranscoder::gifColorToColorARGB(const GifColorType& color) {
+    return MAKE_COLOR_ARGB(0xff, color.Red, color.Green, color.Blue);
+}
+
+GifFilesCloser::~GifFilesCloser() {
+    if (mGifIn) {
+        DGifCloseFile(mGifIn, NULL);
+        mGifIn = NULL;
+    }
+    if (mGifOut) {
+        EGifCloseFile(mGifOut, NULL);
+        mGifOut = NULL;
+    }
+}
+
+void GifFilesCloser::setGifIn(GifFileType* gifIn) {
+    ASSERT(mGifIn == NULL, "mGifIn is already set");
+    mGifIn = gifIn;
+}
+
+void GifFilesCloser::releaseGifIn() {
+    ASSERT(mGifIn != NULL, "mGifIn is already NULL");
+    mGifIn = NULL;
+}
+
+void GifFilesCloser::setGifOut(GifFileType* gifOut) {
+    ASSERT(mGifOut == NULL, "mGifOut is already set");
+    mGifOut = gifOut;
+}
+
+void GifFilesCloser::releaseGifOut() {
+    ASSERT(mGifOut != NULL, "mGifOut is already NULL");
+    mGifOut = NULL;
+}
+
+// JNI stuff
+
+jboolean transcode(JNIEnv* env, jobject clazz, jstring filePath, jstring outFilePath) {
+    const char* pathIn = env->GetStringUTFChars(filePath, JNI_FALSE);
+    const char* pathOut = env->GetStringUTFChars(outFilePath, JNI_FALSE);
+
+    GifTranscoder transcoder;
+    int gifCode = transcoder.transcode(pathIn, pathOut);
+
+    env->ReleaseStringUTFChars(filePath, pathIn);
+    env->ReleaseStringUTFChars(outFilePath, pathOut);
+
+    return (gifCode == GIF_OK);
+}
+
+const char *kClassPathName = "com/android/messaging/util/GifTranscoder";
+
+JNINativeMethod kMethods[] = {
+        { "transcodeInternal", "(Ljava/lang/String;Ljava/lang/String;)Z", (void*)transcode },
+};
+
+int registerNativeMethods(JNIEnv* env, const char* className,
+                          JNINativeMethod* gMethods, int numMethods) {
+    jclass clazz = env->FindClass(className);
+    if (clazz == NULL) {
+        return JNI_FALSE;
+    }
+    if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
+        return JNI_FALSE;
+    }
+    return JNI_TRUE;
+}
+
+jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+    JNIEnv* env;
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        return -1;
+    }
+    if (!registerNativeMethods(env, kClassPathName,
+                               kMethods, sizeof(kMethods) / sizeof(kMethods[0]))) {
+      return -1;
+    }
+    return JNI_VERSION_1_6;
+}
diff --git a/jni/GifTranscoder.h b/jni/GifTranscoder.h
new file mode 100644
index 0000000..39ecc24
--- /dev/null
+++ b/jni/GifTranscoder.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#ifndef GIF_TRANSCODER_H
+#define GIF_TRANSCODER_H
+
+#include <sys/types.h>
+
+#include "gif_lib.h"
+
+// 24-bit color with alpha, stored in order: A, R, G, B.
+// The internal GIF render buffer stores pixels using this format.
+typedef uint32_t ColorARGB;
+
+// Compresses a GIF (probably animated) so it can be sent via MMS, which generally has a 1 MB limit
+// on attachments. GIF image data is already compressed (LZW), so to achieve further reduction in
+// file size, we reduce the image dimensions.
+//
+// Helpful GIF references:
+// GIF89A spec: http://www.w3.org/Graphics/GIF/spec-gif89a.txt
+// What's in a GIF: http://giflib.sourceforge.net/whatsinagif/index.html
+//
+class GifTranscoder {
+public:
+    GifTranscoder() {}
+    ~GifTranscoder() {}
+
+    // Resizes a GIF's width and height to 50% of their original dimensions. The new file is
+    // written to pathOut.
+    //
+    // The image is resized using a box filter, which averages the colors in each 2x2 box of pixels
+    // in the source to generate the color of the pixel in the destination.
+    //
+    // Returns GIF_OK (1) on success, or GIF_ERROR (0) on failure.
+    int transcode(const char* pathIn, const char* pathOut);
+
+private:
+    // Implementation of the box filter algorithm.
+    static bool resizeBoxFilter(GifFileType* gifIn, GifFileType* gifOut);
+
+    // Reads the raster data for the current image of the GIF.
+    static bool readImage(GifFileType* gifIn, GifByteType* rasterBits);
+
+    // Renders the current image of the GIF into the supplied render buffer.
+    static bool renderImage(GifFileType* gifIn,
+                            GifByteType* rasterBits,
+                            int imageIndex,
+                            int transparentColorIndex,
+                            ColorARGB* renderBuffer,
+                            ColorARGB bgColor,
+                            GifImageDesc prevImageDimens,
+                            int prevImageDisposalMode);
+
+    // Fills a rectangle in the buffer with a solid color.
+    static void fillRect(ColorARGB* renderBuffer,
+                         int imageWidth,
+                         int imageHeight,
+                         int left,
+                         int top,
+                         int width,
+                         int height,
+                         ColorARGB color);
+
+    // Computes the color for the pixel (x,y) in the current image in the output GIF.
+    static GifByteType computeNewColorIndex(GifFileType* gifIn,
+                                            int transparentColorIndex,
+                                            ColorARGB* renderBuffer,
+                                            int x,
+                                            int y);
+
+    // Computes the average color (by averaging the per-channel (ARGB) values).
+    static ColorARGB computeAverage(ColorARGB c1, ColorARGB c2, ColorARGB c3, ColorARGB c4);
+
+    // Searches a color map for the color closest (Euclidean distance) to the target color.
+    static GifByteType findBestColor(ColorMapObject* colorMap, int transparentColorIndex,
+                                     ColorARGB targetColor);
+
+    // Computes distance (squared) between 2 colors, considering each channel a separate dimension.
+    static int computeDistance(ColorARGB c1, ColorARGB c2);
+
+    // Returns the local color map of the current image (if any), or else the global color map.
+    static ColorMapObject* getColorMap(GifFileType* gifIn);
+
+    // Returns an indexed color from the color map.
+    static ColorARGB getColorARGB(ColorMapObject* colorMap, int transparentColorIndex,
+                                  GifByteType colorIndex);
+
+    // Converts a 24-bit GIF color (RGB) to a 32-bit ARGB color.
+    static ColorARGB gifColorToColorARGB(const GifColorType& color);
+};
+
+// Wrapper class that automatically closes the GIF files when the wrapper goes out of scope.
+class GifFilesCloser {
+public:
+    GifFilesCloser() {}
+    ~GifFilesCloser();
+
+    void setGifIn(GifFileType* gifIn);
+    void releaseGifIn();
+
+    void setGifOut(GifFileType* gifOut);
+    void releaseGifOut();
+
+private:
+    GifFileType* mGifIn = NULL;
+    GifFileType* mGifOut = NULL;
+};
+
+#endif // GIF_TRANSCODER_H
