That fuck shit the fascists are using
at master 113 lines 4.1 kB view raw
1/** 2 * Source: https://github.com/woltapp/blurhash 3 * 4 * Copyright (c) 2018 Wolt Enterprises 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 7 * associated documentation files (the "Software"), to deal in the Software without restriction, 8 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 9 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in all copies or 13 * substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 16 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 */ 21package org.tm.archive.blurhash; 22 23import android.graphics.Bitmap; 24import android.graphics.Color; 25 26import androidx.annotation.Nullable; 27 28import static org.tm.archive.blurhash.BlurHashUtil.linearTosRGB; 29import static org.tm.archive.blurhash.BlurHashUtil.sRGBToLinear; 30import static org.tm.archive.blurhash.BlurHashUtil.signPow; 31 32class BlurHashDecoder { 33 34 static @Nullable Bitmap decode(@Nullable String blurHash, int width, int height) { 35 return decode(blurHash, width, height, 1f); 36 } 37 38 static @Nullable Bitmap decode(@Nullable String blurHash, int width, int height, double punch) { 39 40 if (blurHash == null || blurHash.length() < 6) { 41 return null; 42 } 43 44 int numCompEnc = Base83.decode(blurHash, 0, 1); 45 int numCompX = (numCompEnc % 9) + 1; 46 int numCompY = (numCompEnc / 9) + 1; 47 48 if (blurHash.length() != 4 + 2 * numCompX * numCompY) { 49 return null; 50 } 51 52 int maxAcEnc = Base83.decode(blurHash, 1, 2); 53 double maxAc = (maxAcEnc + 1) / 166f; 54 double[][] colors = new double[numCompX * numCompY][]; 55 for (int i = 0; i < colors.length; i++) { 56 if (i == 0) { 57 int colorEnc = Base83.decode(blurHash, 2, 6); 58 colors[i] = decodeDc(colorEnc); 59 } else { 60 int from = 4 + i * 2; 61 int colorEnc = Base83.decode(blurHash, from, from + 2); 62 colors[i] = decodeAc(colorEnc, maxAc * punch); 63 } 64 } 65 66 return composeBitmap(width, height, numCompX, numCompY, colors); 67 } 68 69 private static double[] decodeDc(int colorEnc) { 70 int r = colorEnc >> 16; 71 int g = (colorEnc >> 8) & 255; 72 int b = colorEnc & 255; 73 return new double[] {sRGBToLinear(r), 74 sRGBToLinear(g), 75 sRGBToLinear(b)}; 76 } 77 78 private static double[] decodeAc(int value, double maxAc) { 79 int r = value / (19 * 19); 80 int g = (value / 19) % 19; 81 int b = value % 19; 82 return new double[]{ 83 signPow((r - 9) / 9.0f, 2f) * maxAc, 84 signPow((g - 9) / 9.0f, 2f) * maxAc, 85 signPow((b - 9) / 9.0f, 2f) * maxAc 86 }; 87 } 88 89 private static Bitmap composeBitmap(int width, int height, int numCompX, int numCompY, double[][] colors) { 90 Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 91 for (int y = 0; y < height; y++) { 92 for (int x = 0; x < width; x++) { 93 94 double r = 0f; 95 double g = 0f; 96 double b = 0f; 97 98 for (int j = 0; j < numCompY; j++) { 99 for (int i = 0; i < numCompX; i++) { 100 double basis = (Math.cos(Math.PI * x * i / width) * Math.cos(Math.PI * y * j / height)); 101 double[] color = colors[j * numCompX + i]; 102 r += color[0] * basis; 103 g += color[1] * basis; 104 b += color[2] * basis; 105 } 106 } 107 bitmap.setPixel(x, y, Color.rgb((int) linearTosRGB(r), (int) linearTosRGB(g), (int) linearTosRGB(b))); 108 } 109 } 110 111 return bitmap; 112 } 113}