diff options
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.java | 197 |
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."); - } - } -} |