/*
* Artcodes recognises a different marker scheme that allows the
* creation of aesthetically pleasing, even beautiful, codes.
* Copyright (C) 2013-2016 The University of Nottingham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package uk.ac.horizon.artcodes.account;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import com.google.common.hash.Hashing;
import com.google.common.hash.HashingInputStream;
import com.google.common.hash.HashingOutputStream;
import com.google.common.io.ByteStreams;
import java.io.IOException;
import java.io.InputStream;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.internal.Util;
import okio.BufferedSink;
import okio.Okio;
import okio.Source;
class RequestBodyUtil
{
public static class ImageRequestBody extends RequestBody
{
private final Context context;
private final Uri uri;
private final int maxSize = 500;
private Bitmap bitmap;
private ImageRequestBody(Context context, Uri uri)
{
this.context = context;
this.uri = uri;
}
public String getHash() throws IOException
{
bitmap = resizedBitmap();
if (bitmap == null)
{
HashingInputStream inputStream = new HashingInputStream(Hashing.sha256(), getInputStream());
ByteStreams.copy(inputStream, ByteStreams.nullOutputStream());
inputStream.close();
return inputStream.hash().toString();
}
else
{
HashingOutputStream outputStream = new HashingOutputStream(Hashing.sha256(), ByteStreams.nullOutputStream());
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
outputStream.close();
return outputStream.hash().toString();
}
}
@Override
public MediaType contentType()
{
if (bitmap == null)
{
return MediaType.parse("image/jpeg");
}
else
{
return MediaType.parse(context.getContentResolver().getType(uri));
}
}
@Override
public void writeTo(BufferedSink sink) throws IOException
{
if (bitmap != null)
{
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, sink.outputStream());
}
else
{
Source source = null;
try
{
source = Okio.source(getInputStream());
sink.writeAll(source);
}
finally
{
Util.closeQuietly(source);
}
}
}
private InputStream getInputStream() throws IOException
{
return context.getContentResolver().openInputStream(uri);
}
private Bitmap resizedBitmap() throws IOException
{
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getInputStream(), null, o);
int width_tmp = o.outWidth;
int height_tmp = o.outHeight;
int scale = 1;
while (width_tmp > maxSize && height_tmp > maxSize)
{
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
if (scale != 1)
{
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(getInputStream(), null, o2);
}
return null;
}
}
public static ImageRequestBody createImageBody(Context context, String uri)
{
return new ImageRequestBody(context, Uri.parse(uri));
}
public static RequestBody create(final MediaType mediaType, final InputStream inputStream)
{
return new RequestBody()
{
@Override
public MediaType contentType()
{
return mediaType;
}
@Override
public long contentLength()
{
try
{
return inputStream.available();
}
catch (IOException e)
{
return 0;
}
}
@Override
public void writeTo(BufferedSink sink) throws IOException
{
Source source = null;
try
{
source = Okio.source(inputStream);
sink.writeAll(source);
}
finally
{
Util.closeQuietly(source);
}
}
};
}
}