Related
I'm trying to set up an MLKit detection project on Android using Tensorflow library, I have got false values on the output using Tensorflow lite ( different values than Frozen model inference ).
I doubt that the problem is with the input ( image ), So I want to compare the two same images that I have.
To do this task, I have used PIL image and numpy libraries on python to get bytes arrays, and I have converted the drawable image to bitmap and from bitmap to bytes arrays.
I don't know if the function np.asarray should give the same value as those two functions below:
Java code:
private float[][][][] bitmapToInputArray() {
// [START mlkit_bitmap_input]
Bitmap bitmap= getYourInputImage();
int batchNum = 0;
float[][][][] input = new float[1][112][112][3];
for (int x = 0; x < 112; x++) {
for (int y = 0; y < 112; y++) {
int pixel = bitmap.getPixel(x, y);
// Normalize channel values to [-1.0, 1.0]. This requirement varies by
// model. For example, some models might require values to be normalized
// to the range [0.0, 1.0] instead.
input[batchNum][x][y][0] = (Color.red(pixel))/ 255.0f;
input[batchNum][x][y][1] = (Color.green(pixel)) / 255.0f;
input[batchNum][x][y][2] = (Color.blue(pixel))/ 255.0f;
Log.i("Input","input"+input[batchNum][x][y][0]);
Log.i("input","input"+input[batchNum][x][y][1]);
}
}
// [END mlkit_bitmap_input]
return input;
}
public byte[] convertBitmapToByteArray(Bitmap bitmap) {
ByteArrayOutputStream stream = null;
try {
stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
return stream.toByteArray();
}finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
Log.e(ThemedSpinnerAdapter.Helper.class.getSimpleName(), "ByteArrayOutputStream was not closed");
}
}
}
}
private Bitmap getYourInputImage() {
// This method is just for show
BitmapDrawable drawable = (BitmapDrawable) image2.getDrawable();
Bitmap bitmap = drawable.getBitmap();
Bitmap bitmapp=Bitmap.createScaledBitmap(bitmap,112,112,true);
Bitmap bitmap2= bitmapp.copy(Bitmap.Config.ARGB_8888, true);
return bitmap2;
}
byte[] bytes=convertBitmapToByteArray(bitmap1);
Log.i("byte",""+ Arrays.toString(bytes));
float[][][][] inp = new float[1][112][112][3];
inp=bitmapToInputArray();
Log.i("byte2",""+Arrays.toString(inp[0]));
Python script:
img = Image.open("irisdata-300VW_Dataset_2015_12_14-017-000880.jpg")
img.load()
img = img.resize((112, 112), PIL.Image.ANTIALIAS)
print(str(image_to_byte_array(img)))
# Normalize to [0, 1]
data = np.asarray( img, dtype="float32")
print(data)
Output of java code:
2019-08-20 19:01:13.589 1513-1513/com.example.irisdetection I/byte: [-1, -40, -1, -32, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, -1, -37, 0, 67, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -37, 0, 67, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -64, 0, 17, 8, 0, 112, 0, 112, 3, 1, 34, 0, 2, 17, 1, 3, 17, 1, -1, -60, 0, 29, 0, 0, 2, 2, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 6, 9, 4, 5, 10, 3, 2, 1, -1, -60, 0, 69, 16, 0, 1, 3, 3, 1, 5, 5, 4, 7, 5, 6, 5, 5, 0, 0, 0, 3, 1, 2, 4, 5, 6, 17, 33, 0, 7, 18, 19, 49, 8, 34, 65, 81, 97, 20, 35, 113, -127, 9, 21, 50, 51, -111, -95, -79, 36, 66, -63, -47, -16, 22, 23, 67, 82, 83, -31, 37, 52, 98, 114, -15, 99, 115, -126, -125, -94, -1, -60, 0, 28, 1, 0, 2, 2, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 4, 5, 2, 3, 8, 0, 1, -1, -60, 0, 55, 17, 0, 0, 4, 3, 6, 3, 8, 1, 3, 4, 3, 1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 17, 33, 0, 6, 49, 65, 81, 97, 18, 19, 113, 7, 20, 35, -127, -111, -95, -79, -16, -47, 34, -63, -31, 21, 36, 67, -15, 8, 22, 50, 51, -1, -38, 0, 12, 3, 1, 0, 2, 17, 3, 17, 0, 63, 0, -28, -105, 115, 116, 26, 45, 98, -97, 117, 74, -71, -31, -57, -88, 40, -73, 93, 88, -83, 83, 89, 39, 41, -20, -43, 40, -7, 28, 115, 12, -100, -52, -116, -88, 78, 53, -45, 84, -49, -53, 102, 114, 124, 34, -52, -20, -3, -72, 91, -115, 6, -58, -120, -76, -5, -102, -126, 71, 36, -107, 43, -97, -11, 61, 93, -17, 78, 96, 63, 115, -35, -52, 8, -3, -30, -89, -40, -26, 117, -40, 29, -70, 107, 106, 21, 112, 86, -36, 7, 73, 36, 120, -9, 30, -19, -18, -48, -56, 86, -79, -88, -31, -106, -105, 36, -53, -53, 103, 30, -92, 121, 24, -120, 76, 47, -7, -15, -99, 54, 103, 44, -88, -107, 42, -57, 98, 107, 90, 83, -98, 105, 20, -21, 43, 126, 53, -117, 106, 58, -71, -116, 84, -114, 58, -11, 22, 53, 77, -84, 119, 47, -34, -14, -52, 72, 102, 127, -68, -57, -61, 77, -78, 126, -35, 18, -79, 112, 9, 38, 41, 40, 50, 3, 104, 63, -7, -64, 66, 97, -100, -66, -115, -115, 59, 43, -119, 21, 43, -50, -111, 79, 62, 82, -55, -72, 64, 70, -76, -92, -6, 5, 119, -54, -42, 15, -40, -126, -36, -81, 86, 109, 8, 55, 69, -62, 114, 31, -39, -30, 125, 65, 65, 9, 120, -47, -111, -24, -48, 36, -55, 56, -58, 49, -12, 103, 52, -14, 77, -24, -68, 12, -41, 24, -38, -49, 45, -6, 122, -80, -104, -106, -88, 32, -76, 92, 72, -67, 51, -13, 95, 92, -2, 105, -90, 112, -85, -1, 0, 101, -21, 110, -105, 72, -35, 117, -93, 21, -22, -48, 56, 84, 56, 50, 9, -62, -33, -74, 105, 35, -25, -99, 126, 42, 71, -89, -126, -86, -2, 91, 77, 119, -59, -67, 56, 86, 101, 29, -50, -116, -41, 28, -83, 78, 1, 2, 59, 85, 78, 103, -82, -120, -120, -119, -16, 84, -8, -81, -82, -43, -119, 2, 73, -74, -32, 34, 124, -95, -91, 103, -120, -56, 48, -108, -3, 55, 10, -128, 72, 44, 54, -11, 68, -43, -117, 63, 85, 41, 75, -67, -81, -115, 104, 11, -128, 98, 30, 84, -99, -90, 117, -103, -47, 13, 32, -111, 99, 59, 8, -30, 120, -85, 59, -38, -8, 42, 116, -50, -67, 51, -25, -116, 109, -17, 6, -128, 85, 123, 72, 34, 46, 60, 28, -72, -8, 39, 69, -49, -97, -13, -38, -77, -28, -17, 107, 125, -75, -103, -113, -97, 108, 110, -34, -19, -88, 0, 69, -53, 80, 84, -87, 74, -114, 69, 34, -82, -124, 81, -94, 97, 124, -4, -70, 109, 40, -94, 118, -112, -19, 67, 109, 76, -114, -54, -2, -25, 36, -118, -104, -30, 35, -122, -39, -111, -90, 10, 79, 39, 61, 73, -53, 69, -41, 25, 93, 116, -12, -38, -87, 70, -4, -59, 84, -83, 100, 30, 67, 47, -65, 103, 51, 120, 107, -94, 36, 68, -124, -63, -31, -56, 39, 44, -58, -127, -112, -53, 110, -125, -106, 118, 97, 30, -117, 46, 58, 100, -68, 46, 110, 123, -51, -41, -89, 84, -4, -4, -68, 126, 91, 123, -44, -30, 3, -39, -107, 80, 92, 92, 89, -18, -89, -34, 105, -29, -4, 83, -11, -38, 47, -70, -19, -17, 10, -4, -89, 8, -43, 90, 49, 40, -14, -36, 1, -72, -111, -56, -113, 86, 101, 90, -103, 31, 125, 62, -13, -29, -32, -102, -90, -60, -55, -43, 90, 28, 126, 23, 56, 106, -118, -115, -30, 114, 47, -106, 5
2019-08-20 19:01:13.590 1513-1513/com.example.irisdetection I/byte2: [[[F#8bc81c1, [[F#4123d66, [[F#d5d68a7, [[F#ed2a154, [[F#7ce78fd, [[F#c74c9f2, [[F#66de843, [[F#627ec0, [[F#50ea7f9, [[F#201933e, [[F#57cc59f, [[F#250c6ec, [[F#f88cab5, [[F#7ffa54a, [[F#d721cbb, [[F#1f965d8,
Output of python code:
How can I get the same output of the python code with Java code using bitmap as an input?
I have generated the following Public Key in Android.
fun createCipher(): Cipher
{
val posKey = posPublicKey
posKey.publicKey.modulus
var spec = RSAPublicKeySpec(BigInteger(posPublicKey.publicKey.modulus), BigInteger(posPublicKey.publicKey.exponent))
var fact = KeyFactory.getInstance(KeyProperties.KEY_ALGORITHM_RSA)
publicKey = fact.generatePublic(spec)
var cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding")
cipher.init(Cipher.ENCRYPT_MODE, publicKey)
return cipher
}
The RSA key size that I have selected is 4096 bytes
The exponent is 3 bytes and the modulus is 512 bytes
The Modulus Byte Array is as follows:
[-32, -28, -121, 32, 109, -82, 43, 115, 43, -117, 20, 35, 122, 33, -2, 23, 23, -22, 75, 0, 91, 10, -89, 48, 33, -89, 57, 1, 57, -13, 9, -127, 90, 121, -96, -94, 106, -16, -105, -112, -74, 30, -12, 74, -74, 104, -26, 15, 99, -22, -55, -75, 14, -45, 56, 20, 85, 90, 83, -50, 68, -114, 5, -10, -109, 79, 44, 81, 68, -98, -45, -51, -97, 71, 90, -13, -78, 118, -21, -47, 66, 104, -83, 56, -72, -27, 45, 16, 70, 32, -76, -125, -11, 108, 126, -61, -126, 16, 6, -49, -106, -114, 18, 49, 121, -39, -109, 115, 111, -128, 83, 8, -110, -10, -4, 51, -67, 49, 66, 103, -76, -88, -110, 122, 56, 29, -101, 22, 3, 117, -104, -54, -64, -71, 23, 58, 87, 37, 96, 25, -114, 38, 1, -126, 33, -91, -4, 89, -28, 10, 95, -104, -24, -38, 17, 47, -122, 24, -89, 123, 100, 12, -10, -57, -44, 45, 25, 39, -80, -101, -6, -99, -95, -5, 70, 32, 37, -57, -52, -47, -66, 85, 10, -48, 75, 4, -114, 104, -7, -112, -128, 4, 114, 77, -40, 96, 66, 83, -54, 10, 111, 102, -39, -63, 2, -75, 38, 36, 24, 13, -51, 96, 89, -60, -40, 99, 65, 123, 52, -114, 122, 75, 32, -121, 80, -76, -11, -1, -31, -118, -51, -21, 13, 109, 111, -102, 120, -56, 62, -19, -79, 86, -41, -81, 67, -80, -63, 37, 35, 47, 109, -32, 47, -128, 95, -48, -53, -1, -125, -19, -9, -10, 15, -116, -50, 53, -86, -102, -24, 107, 122, -43, -125, 51, 14, 101, 67, 57, 116, 97, -40, -98, -82, -118, -83, 120, -107, -14, 19, -49, -27, 10, 25, 40, 43, -27, 31, 59, -57, 58, 33, -98, 1, -45, -118, 76, -21, -13, -123, 67, 42, -37, -96, -32, 33, 124, 1, 44, -99, 74, 18, 32, 10, -107, -121, 86, -115, -70, -107, 109, 17, -92, 109, -47, 60, -49, -91, 7, -125, 47, 78, 86, 81, -2, -35, 17, 124, 94, -26, -80, -84, 120, 110, 38, -55, -90, -11, 107, 73, 71, 44, 69, -58, 56, -59, 2, 94, 27, 88, 29, -57, 95, -99, 5, 102, -66, 118, -82, 126, 20, -104, -95, 47, -2, 77, -33, 89, -66, -92, 121, -5, 78, 68, -1, -82, -95, -121, 117, -29, 70, 11, -72, 54, -99, -13, -87, 9, 77, -113, 51, -124, -56, -8, 126, -114, -31, 90, -125, -11, 41, -85, 74, 3, 90, -95, 85, 121, 61, 14, 116, 51, -40, -57, -124, -69, -51, -76, -119, -80, 95, 95, 17, -34, 80, -36, 66, -51, 14, -69, -113, 35, -109, -115, -16, -3, -118, 114, -20, -81, 57, -65, 40, -8, -67, -85, 110, 50, -128, 44, -78, 93, -44, -93, 89, -76, 13, 98, -38, -55, -120, 11, 127, 84, -2, 101, 57, -121, -111, 91, -102, -118, 85, -124, -90, 91, -84, 28, 120, -28, -105, 88, -73, 6, 89, 33, 8, 9, 30, 9, -6, 17, 25]
The Exponent Byte Array is as Follows:
[1, 0, 1]
The test Key is as follows:
val stringKey = "8D-F7-5B-15-0F-2A-E5-3E-FD-44-5A-63-50-AC-62-D6-06-2D-59-5C-F1-C3-9A-DB-45-25-0D-7A-72-AE-DF-87"
val stringIV = "FA-94-FD-74-2E-AC-2C-90-79-98-AF-A3-D7-12-5D-A2"
var aeskey = AesKeyBuilder()
val key = (stringKey.replace("-", "")).toByteArray(Charsets.US_ASCII)
val iv = (stringIV.replace("-", "")).toByteArray(Charsets.US_ASCII)
aeskey.key = key
aeskey.iv = iv
val encryptedKey = cipher.doFinal(aesKey.Key)
The item that I am trying to encrypt is 64 bytes. Using this public key.
However, I get the following error:
Process: com.touchsides.rewards.debug, PID: 19470
com.android.org.bouncycastle.crypto.DataLengthException: input too large for RSA cipher.
at com.android.org.bouncycastle.crypto.engines.RSACoreEngine.convertInput(RSACoreEngine.java:115)
at com.android.org.bouncycastle.crypto.engines.RSABlindedEngine.processBlock(RSABlindedEngine.java:95)
at com.android.org.bouncycastle.crypto.encodings.OAEPEncoding.encodeBlock(OAEPEncoding.java:199)
at com.android.org.bouncycastle.crypto.encodings.OAEPEncoding.processBlock(OAEPEncoding.java:131)
I believe the modulus size is large enough to allow for the encryption of this byte array.
You get the com.android.org.bouncycastle.crypto.DataLengthException error because RSA key was created with negative Modulus. So it can't be used to encrypt even one byte.
BigInteger default constructor uses the most significant bit of provided byte array payload as sign bit for the number. So you have to explicitly specify that you want a positive number using another constructor where the first argument is a sign indicator:
BigInteger(1, posPublicKey.publicKey.modulus), BigInteger(1, posPublicKey.publicKey.exponent)
There's also a C# approach to add a zero-byte in front of the byte array (so the sign bit will be always zero):
BigInteger(byteArrayOf(0) + posPublicKey.publicKey.modulus), BigInteger(byteArrayOf(0) + posPublicKey.publicKey.exponent)
And finally, if you already have your BigInteger created the wrong way, it's possible to convert it:
var modulus = BigInteger(posPublicKey.publicKey.modulus)
if (modulus.compareTo(BigInteger.ZERO) < 0)
modulus = modulus.add(BigInteger.ONE.shiftLeft(4096))
Please also look at this answer and answers of this question.
I have following compressed text given as a byte Array:
byte[] compressed = [97, 2, 10, 28, 72, -80, -96, -63, -125, 8, 19, 42, 92, -56, -80, -95, -61, -121, 16, 35, 74, -100, 72, -79, -94, -59, -117, 24, 51, 106, -36, -56, -79, -93, -57, -113, 32, 67, -118, 28, 73, -78, -92, -55, -109, 40, 83, -86, 92, -55, -78, -91, -53, -105, 48, 99, -54, -100, 73, -77, -90, -51, -101, 56, 115, -22, -36, -55, -77, -89, -49, -97, 64, -125, 10, 29, 74, -76, -88, -47, -93, 72, -109, 42, 93, -54, -76, -87, -45, -89, 80, -93, 74, -99, 74, -75, -86, -43, -85, 88, -77, 106, -35, -54, -75, -85, -41, -81, 96, -61, -118, 29, 75, -74, -84, -39, -77, 104, -45, -86, 93, -53, -74, -83, -37, -73, 112, -29, -54, -99, 75, -73, -82, -35, -69, 120, -13, -22, -35, -53, -73, -81, -33, -65, -128, 3, 11, 30, 76, -72, -80, -31, -61, -120, 19, 43, 94, -52, -72, -79, -29, -57, -112, 35, 75, -98, 76, -71, -78, -27, -53, -104, 51, 107, -34, -52, -71, -77, -25, -49, -96, 67, -117, 30, 77, -70, -76, -23, -45, -88, 83, -85, 94, -51, -70, -75, -21, -41, -80, 99, -53, -98, 77, -69, -74, -19, -37, -72, 115, -21, -34, -51, -69, -73, -17, -33, -64, -125, 11, 31, 78, -68, -72, -15, -29, -56, -109, 43, 95, -50, -68, -71, -13, -25, -48, -93, 75, -97, 78, -67, -70, -11, -21, -40, -77, 107, -33, -50, -67, -69, -9, -17, -32, -61, -117, 31, 79, -66, -68, -7, -13, -24, -45, -85, 95, -49, -66, -67, -5, -9, -16, -29, -53, -97, 79, -65, -66, -3, -5, -8, -13, -21, -33, -49, -65, -65, -1, -1, 0, -61, 4, 20, 56, -112, 96, 65, -125, 7, 17, 38, 84, -72, -112, 97, 67, -121, 15, 33, 70, -108, 56, -111, 98, 69, -117, 23, 49, 102, -44, -72, -111, 99, 71, -113, 31, 65, -122, 20, 57, -110, 100, 73, -109, 39, 81, -90, 84, -71, -110, 101, 75, -105, 47, 97, -58, -108, 57, -109, 102, 77, -101, 55, 113, -26, -44, -71, -109, 103, 79, -97, 63, -127, 6, 21, 58, -108, 104, 81, -93, 71, -111, 38, 85, -70, -108, 105, 83, -89, 79, -95, 70, -107, 58, -107, 106, 85, -85, 87, -79, 102, -43, -70, -107, 107, 87, -81, 95, -63, -122, 21, 59, -106, 108, 89, -77, 103, -47, -90, 85, -69, -106, 109, 91, -73, 111, 91, 2];
and a given codeword length of 9 bits.
The resulting string should be aaaaaaaaaaaaaaaaaaaaaaaaa... with a total length of 39270 of all *a*s.
I want to write a decompress function which decompresses the compressed byte array and returns the resulting string of *a*s.
I tried the normal LZW implementations but this didn't work very well. The given codeword length of 9 bit and the negative values in the byte array gives me some headache.
My understanding is I have to convert the whole byte array to one binary string and read each value every 9 bits (codeword length)?
Has anyone a hint or a suggestion how this can be done? Thanks, I really appreciate your support.
Edit:
Here is some code, I tried so far, which works with
byte[] compressed = [68, 0, 97, 0, 115, 0, 32, 0, 105, 0, 115, 0, 116, 0, 32, 0, 101, 0, 105, 0, 110, 0, 32, 0, 107, 0, 117, 0, 114, 0, 122, 0, 101, 0, 114, 0, 32, 0, 84, 0, 101, 0, 120, 0, 116, 0]
and a given codeword length of 16 bits.
The resulting string is Das ist ein kurzer Text.
public static List<String> convertByteArrayToBinaryStringList(byte[]compressedData,int codeWordLength){
StringBuilder sb=new StringBuilder();
List<String> binaryCompressedValues=new ArrayList<String>();
for(int i=0;i<compressedData.length;i++){
sb.append(byteToBinaryString(compressedData[i]));
}
char[]binaryCharArray=sb.toString().toCharArray();
int j=0;
while(j<binaryCharArray.length){
StringBuilder binStringBuilder=new StringBuilder();
for(int i=j;i<j+codeWordLength;i++){
if(j+codeWordLength>binaryCharArray.length){
System.out.println("End reached!");
binStringBuilder.append("0");
}else{
binStringBuilder.append(binaryCharArray[i]);
}
}
j+=codeWordLength;
binaryCompressedValues.add(binStringBuilder.toString());
}
return binaryCompressedValues;
}
public String incrementDictSize(String currentDictSize) {
String incrementedString = Integer.toBinaryString(Integer.valueOf(currentDictSize, 2) + 1);
int lengthDistance = currentDictSize.length() - incrementedString.length();
String padding = "";
if (lengthDistance > 0) {
for (int i = 0; i < lengthDistance; i++) {
padding += "0";
}
}
return padding + incrementedString;
}
public byte[]uncompress(byte[]compressedData){
int codeWordLength=16;
List<String> binaryCompressedValues=new ArrayList<String>();
binaryCompressedValues=convertByteArrayToBinaryStringList(compressedData,codeWordLength);
//int dictSize = 256;
String dictSize="1111111100000000";
Map<String, String> dictionary=new HashMap<String, String>();
String s="00000000";
String padString="00000000";
for(int i=0;i< 256;i++){
s=String.format("%8s",Integer.toBinaryString(i)).replace(' ','0');
dictionary.put(s+padString,""+(char)i);
System.out.println("dictionary.get("+i+") "+s+padString+" "+dictionary.get(s+padString));
}
//String w = "" + (char)(byte)compressedData[0];
String w="";
StringBuffer result=new StringBuffer(w);
for(String k:binaryCompressedValues){
String entry;
if(dictionary.containsKey(k)){
entry=dictionary.get(k);
dictionary.put(incrementDictSize(currentDictSize),w+entry.charAt(0));
result.append(entry);
w=entry;
}else{
entry=w+w.charAt(0);
result.append(entry);
dictionary.put(incrementDictSize(currentDictSize),w+w.charAt(0));
w=entry;
}
}
return result.toString().getBytes();
}
Example code for reading n-bit-codes LSB first.
Beware dirty details like alignment on code size change.
/** An <code>NBitsInputStream</code> reads its <code>InputStream</code>
* as codes of n bits, least significant bits first.
*/// extend with set/increaseCodeLength() as needed
class NBitsInputStream extends java.io.FilterInputStream {
int buffer, validBits;
int codeLength, codeMask;
protected NBitsInputStream(InputStream in, int n) {
super(in);
codeLength = n;
codeMask = (1 << n) - 1;
}
/** Reads a code of n bits, least significant bits first.
* #return the code, or -1 if -1 is read. */
#Override
public int read() throws IOException {
while (validBits < codeLength) {
int high = super.read();
if (high < 0) // EOF
return high;
buffer |= high << validBits;
validBits += 8;
}
int code = buffer & codeMask;
validBits -= codeLength;
buffer >>= codeLength;
return code;
}
}
(Tried
for (int code ; 0 <= (code = codes.read()) ; ) {
String entry = (String) dictionary.get(code);
w += (null != entry ? entry : w).charAt(0);
dictionary.put(++currentDictSize, w);
result.append(w = entry);
}
without unexpected observations.)
Note that your dictionary will contain not just the longest strings, but each of their prefixes, for up to about 2130641537 characters using 16 bit codes (in addition to a result of almost that length).
Here's my test code, the problem is resultLength != original.length, and result array is same as original array, shouldn't it be after compression and decompression?
public static void main(String[] args) {
// generateTyreAlarmEvent()
byte[] original = {10, 17, 97, 98, 99, 100, 101, 102, 103, 104, 105, 103, 107, 108, 109, 110, 111, 112, 113, 16, 2, 24, -50, -1, -113, -59, 5, 34, 20, 8, -35, 1, 16, 40, 24, -34, 1, 32, 60, 40, -33, 1, 48, 80, 56, -32, 1, 64, 100, 42, 16, 8, 2, 16, 1, 24, 3, 32, 0, 40, 1, 48, 1, 56, 1, 64, 0};
byte[] buffer = new byte[original.length];
Deflater compresser = new Deflater();
compresser.setInput(original);
compresser.finish();
int compressedLen = compresser.deflate(buffer);
compresser.end();
Inflater decompressor = new Inflater();
decompressor.setInput(buffer, 0, compressedLen);
byte[] result = new byte[original.length];
int resultLength = 0;
try {
resultLength = decompressor.inflate(result);
} catch (DataFormatException e) {
}
decompressor.end();
// the problem is resultLength(63) != original.length(67), and result array is same as original array
}
The original byte array is (len is 67) :
{10, 17, 97, 98, 99, 100, 101, 102, 103, 104, 105, 103, 107, 108, 109, 110, 111, 112, 113, 16, 2, 24, -50, -1, -113, -59, 5, 34, 20, 8, -35, 1, 16, 40, 24, -34, 1, 32, 60, 40, -33, 1, 48, 80, 56, -32, 1, 64, 100, 42, 16, 8, 2, 16, 1, 24, 3, 32, 0, 40, 1, 48, 1, 56, 1, 64, 0}
and the result is (len is 63) :
{10, 17, 97, 98, 99, 100, 101, 102, 103, 104, 105, 103, 107, 108, 109, 110, 111, 112, 113, 16, 2, 24, -50, -1, -113, -59, 5, 34, 20, 8, -35, 1, 16, 40, 24, -34, 1, 32, 60, 40, -33, 1, 48, 80, 56, -32, 1, 64, 100, 42, 16, 8, 2, 16, 1, 24, 3, 32, 0, 40, 1, 48, 1}
Thanks!
You did not make the output buffer big enough. Just to test, I replaced byte[] buffer = new byte[original.length]; with byte[] buffer = new byte[1000];, and it worked fine.
If the data is not compressible, as this is, then the output will be larger than the input.
I use javafx WebView in my project and it began crash at one website.
Through debug i understood, that when page receives part of js-code server uses header "Content-Encoding:deflate", ignoring my request headers.
Main problem in inflate method of InflaterInputStream.
java.util.zip.ZipException: incorrect header check
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:164)
I reproduced this error in simple method:
public byte[] makeTestRequest(String url) throws Exception {
InputStreamResponseListener listener = new InputStreamResponseListener();
Request request = httpClient
.newRequest(url);
request.send(listener);
Response response = listener.get(5, TimeUnit.SECONDS);
byte[] uncompressedData = new byte[65536];
if (response.getStatus() == 200) {
try(InputStream responseContent = listener.getInputStream()){
InputStream stream = new InflaterInputStream(responseContent);
int len, offset = 0;
while ((len = stream.read(uncompressedData , offset, uncompressedData.length-offset))>0) {
offset += len;
}
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return uncompressedData;
}
Error occurs in this method.
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/zip/Inflater.java#247
Inflator's buffer in this moment contains data:
[-52, 93, 105, 115, 19, -57, -70, -2, 43, 42, 127, -54, -87, -63, -55, 116, -49, -98, 111, 22, 96, 98, -57, -40, -114, 23, -74, -101, -5, -63, 24, -127, 29, -37, -40, 120, 97, 75, -91, -54, 24, 8, -71, 5, 9, 107, 78, 40, 3, 33, 108, 39, 124, 57, 39, 62, 24, -127, -15, 34, -2, -62, -24, 31, -35, 126, -33, 30, 75, -45, -45, 61, 51, 26, 105, 20, 83, -87, 20, -42, 72, -74, -34, -18, -89, -33, 125, -23, -17, 59, -26, -58, -58, -89, 74, -117, 71, 74, -13, 11, -109, -77, 103, 59, -66, 116, 40, -47, 109, 87, -73, -68, 125, 29, -89, -25, 103, 103, 106, -49, 117, -10, 122, 108, 124, 113, 118, 126, -95, -10, -56, -78, 108, -41, -13, 8, -75, -10, 117, 44, -52, -51, -50, 47, 46, 116, 124, -7, 63, -33, 119, 76, -98, -22, -8, -110, 24, -122, 109, -17, 99, 127, 122, -66, 116, 118, -79, 7, 30, -20, -21, -104, -102, 60, -53, 126, -24, 88, 40, -99, -103, 97, 15, 59, -40, -17, -80, 95, 25, -104, 63, 85, -102, 103, 79, 53, -83, 83, -45, 14, -112, -2, 18, 123, 126, 118, 108, -90, -60, 30, -7, 47, -85, 87, -85, 43, -2, 127, -3, -118, -65, -11, 121, -63, 95, -83, 94, -59, -97, 55, 11, -2, 29, -1, -91, -65, -38, -15, -61, -66, -32, -69, -22, 127, 26, -120, -112, -1, -80, -6, 79, -42, 126, -97, -102, 54, -11, -62, -76, -102, -87, -76, -114, 107, -102, 123, -48, -103, 10, -3, -31, -25, 126, -39, -33, 97, -1, 109, 84, -81, 48, 90, 31, 51, 90, -33, -79, 127, 95, 86, 111, 85, 127, -87, -34, -16, -53, -43, 101, 124, -2, -112, 125, -7, -102, -65, -59, 62, 117, -69, -10, -11, 102, 10, -7, -29, -22, 111, -87, 47, -33, 51, 28, 51, 59, -7, 93, 90, 118, -14, -1, -12, 55, -128, -8, -6, 87, 59, -60, -10, -78, -94, 60, 114, -48, -42, 15, -57, -94, -4, 79, 32, -124, -3, -5, -100, -67, 126, -29, -81, 85, -105, 25, 73, -1, -57, 8, -72, -30, 111, -78, 47, 47, 23, -4, 109, -10, 112, -123, -47, 20, -94, -62, -16, 44, 43, 76, -123, -95, -96, 98, -66, 116, -122, 29, 89, 120, -41, 54, -115, 40, 81, 68, -45, 102, -12, -119, -109, 33, -94, -18, -78, 111, -127, -81, 44, -121, 72, -5, -61, -81, 84, -81, -80, -89, 12, 60, -10, -22, 25, -37, -93, -113, -80, 51, -80, 35, -2, -70, -65, 86, -93, -57, 72, 1, -108, 36, 125, 79, 125, 85, -90, 103, -89, -82, 74, 90, -58, 56, -79, -10, -89, 44, -29, 87, -1, 13, 35, -70, 2, -80, 50, -46, -73, 16, -8, -73, 8, 55, -20, -7, -57, 78, 98, -121, 118, -106, -70, 70, -104, 6, -102, 74, -125, -50, -74, 82, 100, -71, 87, -64, -77, 64, -125, -1, 1, -72, -104, -67, 126, 84, 103]
I'm surprised, but my that page successfully displayed in Chrome and Safari, but don't work in javafx WebView.
Is it a bug in inflate method or i'm doing something wrong?
It didn't solve the problem with javafx WebView, but using Inflator constructor with nowrap option helped with incorrect header check" error:
Inflator inf = new Inflator(true);
InputStream stream = new InflaterInputStream(responseContent, inf);