/*******************************************************************************
* This file is part of RedReader.
*
* RedReader is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RedReader 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RedReader. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package org.quantumbadger.redreader.views.imageview;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.Log;
import org.quantumbadger.redreader.common.General;
import java.io.IOException;
public class ImageTileSourceWholeBitmap implements ImageTileSource {
private final byte[] mData;
private Bitmap mBitmap = null;
private final int mWidth, mHeight;
private static final int TILE_SIZE = 512;
public ImageTileSourceWholeBitmap(final byte[] data) throws IOException {
mData = data;
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
mWidth = bitmap.getWidth();
mHeight = bitmap.getHeight();
bitmap.recycle();
}
@Override
public int getWidth() {
return mWidth;
}
@Override
public int getHeight() {
return mHeight;
}
@Override
public int getTileSize() {
return TILE_SIZE;
}
@Override
public int getHTileCount() {
return General.divideCeil(getWidth(), TILE_SIZE);
}
@Override
public int getVTileCount() {
return General.divideCeil(getHeight(), TILE_SIZE);
}
@Override
public synchronized Bitmap getTile(final int sampleSize, final int tileX, final int tileY) {
if(mBitmap == null) {
Log.i("ImageTileSourceWholeBitmap", "Loading bitmap.");
mBitmap = BitmapFactory.decodeByteArray(mData, 0, mData.length);
}
final int tileStartX = tileX * TILE_SIZE;
final int tileStartY = tileY * TILE_SIZE;
final int tileEndX = (tileX + 1) * TILE_SIZE;
final int tileEndY = (tileY + 1) * TILE_SIZE;
final int outputTileSize = TILE_SIZE / sampleSize;
if(tileEndX <= getWidth() && tileEndY <= getHeight()) {
final Bitmap region = Bitmap.createBitmap(
mBitmap,
tileStartX,
tileStartY,
tileEndX - tileStartX,
tileEndY - tileStartY);
return Bitmap.createScaledBitmap(region, outputTileSize, outputTileSize, true);
} else {
final Bitmap tile = Bitmap.createBitmap(outputTileSize, outputTileSize, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(tile);
final int tileLimitedEndX = Math.min(tileEndX, getWidth());
final int tileLimitedEndY = Math.min(tileEndY, getHeight());
final Rect srcRect = new Rect(
tileStartX,
tileStartY,
tileLimitedEndX,
tileLimitedEndY
);
final int srcTileWidth = tileLimitedEndX - tileStartX;
final int srcTileHeight = tileLimitedEndY - tileStartY;
final Rect dstRect = new Rect(
0,
0,
srcTileWidth / sampleSize,
srcTileHeight / sampleSize
);
canvas.drawBitmap(mBitmap, srcRect, dstRect, null);
return tile;
}
}
@Override
public synchronized void dispose() {
if(mBitmap != null && !mBitmap.isRecycled()) {
mBitmap.recycle();
}
mBitmap = null;
}
}