summaryrefslogtreecommitdiffstats
path: root/mobile/android/base/java/org/mozilla/gecko/icons/decoders/FaviconDecoder.java
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/base/java/org/mozilla/gecko/icons/decoders/FaviconDecoder.java')
-rw-r--r--mobile/android/base/java/org/mozilla/gecko/icons/decoders/FaviconDecoder.java197
1 files changed, 0 insertions, 197 deletions
diff --git a/mobile/android/base/java/org/mozilla/gecko/icons/decoders/FaviconDecoder.java b/mobile/android/base/java/org/mozilla/gecko/icons/decoders/FaviconDecoder.java
deleted file mode 100644
index 43f5d0ac6..000000000
--- a/mobile/android/base/java/org/mozilla/gecko/icons/decoders/FaviconDecoder.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.icons.decoders;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.util.Base64;
-import android.util.Log;
-
-import org.mozilla.gecko.gfx.BitmapUtils;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * Class providing static utility methods for decoding favicons.
- */
-public class FaviconDecoder {
- private static final String LOG_TAG = "GeckoFaviconDecoder";
-
- static enum ImageMagicNumbers {
- // It is irritating that Java bytes are signed...
- PNG(new byte[] {(byte) (0x89 & 0xFF), 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a}),
- GIF(new byte[] {0x47, 0x49, 0x46, 0x38}),
- JPEG(new byte[] {-0x1, -0x28, -0x1, -0x20}),
- BMP(new byte[] {0x42, 0x4d}),
- WEB(new byte[] {0x57, 0x45, 0x42, 0x50, 0x0a});
-
- public byte[] value;
-
- private ImageMagicNumbers(byte[] value) {
- this.value = value;
- }
- }
-
- /**
- * Check for image format magic numbers of formats supported by Android.
- * @param buffer Byte buffer to check for magic numbers
- * @param offset Offset at which to look for magic numbers.
- * @return true if the buffer contains a bitmap decodable by Android (Or at least, a sequence
- * starting with the magic numbers thereof). false otherwise.
- */
- private static boolean isDecodableByAndroid(byte[] buffer, int offset) {
- for (ImageMagicNumbers m : ImageMagicNumbers.values()) {
- if (bufferStartsWith(buffer, m.value, offset)) {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Utility function to check for the existence of a test byte sequence at a given offset in a
- * buffer.
- *
- * @param buffer Byte buffer to search.
- * @param test Byte sequence to search for.
- * @param bufferOffset Index in input buffer to expect test sequence.
- * @return true if buffer contains the byte sequence given in test at offset bufferOffset, false
- * otherwise.
- */
- static boolean bufferStartsWith(byte[] buffer, byte[] test, int bufferOffset) {
- if (buffer.length < test.length) {
- return false;
- }
-
- for (int i = 0; i < test.length; ++i) {
- if (buffer[bufferOffset + i] != test[i]) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Decode the favicon present in the region of the provided byte[] starting at offset and
- * proceeding for length bytes, if any. Returns either the resulting LoadFaviconResult or null if the
- * given range does not contain a bitmap we know how to decode.
- *
- * @param buffer Byte array containing the favicon to decode.
- * @param offset The index of the first byte in the array of the region of interest.
- * @param length The length of the region in the array to decode.
- * @return The decoded version of the bitmap in the described region, or null if none can be
- * decoded.
- */
- public static LoadFaviconResult decodeFavicon(Context context, byte[] buffer, int offset, int length) {
- LoadFaviconResult result;
- if (isDecodableByAndroid(buffer, offset)) {
- result = new LoadFaviconResult();
- result.offset = offset;
- result.length = length;
- result.isICO = false;
-
- Bitmap decodedImage = BitmapUtils.decodeByteArray(buffer, offset, length);
- if (decodedImage == null) {
- // What we got wasn't decodable after all. Probably corrupted image, or we got a muffled OOM.
- return null;
- }
-
- // We assume here that decodeByteArray doesn't hold on to the entire supplied
- // buffer -- worst case, each of our buffers will be twice the necessary size.
- result.bitmapsDecoded = new SingleBitmapIterator(decodedImage);
- result.faviconBytes = buffer;
-
- return result;
- }
-
- // If it's not decodable by Android, it might be an ICO. Let's try.
- ICODecoder decoder = new ICODecoder(context, buffer, offset, length);
-
- result = decoder.decode();
-
- if (result == null) {
- return null;
- }
-
- return result;
- }
-
- public static LoadFaviconResult decodeDataURI(Context context, String uri) {
- if (uri == null) {
- Log.w(LOG_TAG, "Can't decode null data: URI.");
- return null;
- }
-
- if (!uri.startsWith("data:image/")) {
- // Can't decode non-image data: URI.
- return null;
- }
-
- // Otherwise, let's attack this blindly. Strictly we should be parsing.
- int offset = uri.indexOf(',') + 1;
- if (offset == 0) {
- Log.w(LOG_TAG, "No ',' in data: URI; malformed?");
- return null;
- }
-
- try {
- String base64 = uri.substring(offset);
- byte[] raw = Base64.decode(base64, Base64.DEFAULT);
- return decodeFavicon(context, raw);
- } catch (Exception e) {
- Log.w(LOG_TAG, "Couldn't decode data: URI.", e);
- return null;
- }
- }
-
- public static LoadFaviconResult decodeFavicon(Context context, byte[] buffer) {
- return decodeFavicon(context, buffer, 0, buffer.length);
- }
-
- /**
- * Iterator to hold a single bitmap.
- */
- static class SingleBitmapIterator implements Iterator<Bitmap> {
- private Bitmap bitmap;
-
- public SingleBitmapIterator(Bitmap b) {
- bitmap = b;
- }
-
- /**
- * Slightly cheating here - this iterator supports peeking (Handy in a couple of obscure
- * places where the runtime type of the Iterator under consideration is known and
- * destruction of it is discouraged.
- *
- * @return The bitmap carried by this SingleBitmapIterator.
- */
- public Bitmap peek() {
- return bitmap;
- }
-
- @Override
- public boolean hasNext() {
- return bitmap != null;
- }
-
- @Override
- public Bitmap next() {
- if (bitmap == null) {
- throw new NoSuchElementException("Element already returned from SingleBitmapIterator.");
- }
-
- Bitmap ret = bitmap;
- bitmap = null;
- return ret;
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException("remove() not supported on SingleBitmapIterator.");
- }
- }
-}