summaryrefslogtreecommitdiffstats
path: root/jni/GifTranscoder.h
diff options
context:
space:
mode:
authorMike Dodd <mdodd@google.com>2015-08-11 11:16:59 -0700
committerMike Dodd <mdodd@google.com>2015-08-12 08:58:28 -0700
commit461a34b466cb4b13dbbc2ec6330b31e217b2ac4e (patch)
treebc4b489af52d0e2521e21167d2ad76a47256f348 /jni/GifTranscoder.h
parent8b3e2b9c1b0a09423a7ba5d1091b9192106502f8 (diff)
downloadpackages_apps_Messaging-461a34b466cb4b13dbbc2ec6330b31e217b2ac4e.zip
packages_apps_Messaging-461a34b466cb4b13dbbc2ec6330b31e217b2ac4e.tar.gz
packages_apps_Messaging-461a34b466cb4b13dbbc2ec6330b31e217b2ac4e.tar.bz2
Initial checkin of AOSP Messaging app.
b/23110861 Change-Id: I9aa980d7569247d6b2ca78f5dcb4502e1eaadb8a
Diffstat (limited to 'jni/GifTranscoder.h')
-rw-r--r--jni/GifTranscoder.h122
1 files changed, 122 insertions, 0 deletions
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