Skip to content

Commit

Permalink
koral--#150 finished
Browse files Browse the repository at this point in the history
  • Loading branch information
koral-- committed Apr 20, 2015
1 parent 3468553 commit f1bed87
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 34 deletions.
29 changes: 22 additions & 7 deletions src/main/java/pl/droidsonroids/gif/GifDrawable.java
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,7 @@ public int getCurrentPosition() {
* It may take a lot of time if number of such frames is large.
* Method is thread-safe. Decoding is performed in background thread and drawable is invalidated automatically
* afterwards.
* If position exceeds animation duration, seek stops at the end, no exception is thrown.
*
* @param position position to seek to in milliseconds
* @throws IllegalArgumentException if position<0
Expand All @@ -473,15 +474,15 @@ public void doWork() {
}

/**
* Like {@link #seekTo(int)}
* but uses index of the frame instead of time.
* Like {@link #seekTo(int)} but uses index of the frame instead of time.
* If frameIndex exceeds number of frames, seek stops at the end, no exception is thrown.
*
* @param frameIndex index of the frame to seek to (zero based)
* @throws IllegalArgumentException if frameIndex<0
* @throws IndexOutOfBoundsException if frameIndex<0
*/
public void seekToFrame(final int frameIndex) {
if (frameIndex < 0) {
throw new IllegalArgumentException("frameIndex is not positive");
throw new IndexOutOfBoundsException("Frame index is not positive");
}
mExecutor.execute(new SafeRunnable(this) {
@Override
Expand All @@ -492,9 +493,16 @@ public void doWork() {
});
}

public Bitmap goToFrame(final int frameIndex) {
/**
* Like {@link #seekToFrame(int)} but performs operation synchronously and returns that frame.
*
* @param frameIndex index of the frame to seek to (zero based)
* @return frame at desired index
* @throws IndexOutOfBoundsException if frameIndex&lt;0
*/
public Bitmap seekToFrameAndGet(final int frameIndex) {
if (frameIndex < 0) {
throw new IllegalArgumentException("frameIndex is not positive");
throw new IndexOutOfBoundsException("Frame index is not positive");
}
final Bitmap bitmap;
synchronized (mNativeInfoHandle) {
Expand All @@ -505,7 +513,14 @@ public Bitmap goToFrame(final int frameIndex) {
return bitmap;
}

public Bitmap goToPosition(final int position) {
/**
* Like {@link #seekTo(int)} but performs operation synchronously and returns that frame.
*
* @param position position to seek to in milliseconds
* @return frame at desired position
* @throws IndexOutOfBoundsException if position&lt;0
*/
public Bitmap seekToPositionAndGet(final int position) {
if (position < 0) {
throw new IllegalArgumentException("Position is not positive");
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/jni/control.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ Java_pl_droidsonroids_gif_GifInfoHandle_seekToTime(JNIEnv *env, jclass __unused

unsigned long sum = 0;
int desiredIndex;
for (desiredIndex = 0; desiredIndex < info->gifFilePtr->ImageCount; desiredIndex++) {
for (desiredIndex = 0; desiredIndex < info->gifFilePtr->ImageCount-1; desiredIndex++) {
unsigned long newSum = sum + info->controlBlock[desiredIndex].DelayTime;
if (newSum >= desiredPos)
if (newSum > desiredPos)
break;
sum = newSum;
}
Expand Down
53 changes: 28 additions & 25 deletions src/main/jni/surface.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,21 +117,26 @@ Java_pl_droidsonroids_gif_GifInfoHandle_bindSurface(JNIEnv *env, jclass __unused
const size_t bufferSize = buffer.stride * buffer.height * sizeof(argb);

info->stride = buffer.stride;

long invalidationDelayMillis;
if (info->surfaceDescriptor->surfaceBackupPtr) {
memcpy(buffer.bits, info->surfaceDescriptor->surfaceBackupPtr, bufferSize);
info->lastFrameRemainder = -1;
invalidationDelayMillis = 0;
info->surfaceDescriptor->renderHelper = 1;
info->surfaceDescriptor->slurpHelper = 0;
}
else {
if (savedState != NULL)
info->lastFrameRemainder = restoreSavedState(info, env, savedState, buffer.bits);
if (savedState != NULL){
invalidationDelayMillis = restoreSavedState(info, env, savedState, buffer.bits);
if (invalidationDelayMillis <0)
invalidationDelayMillis =0;
}
else
info->lastFrameRemainder = -1;
invalidationDelayMillis = 0;
info->surfaceDescriptor->renderHelper = 0;
info->surfaceDescriptor->slurpHelper = 1;
}

info->lastFrameRemainder = -1;
ANativeWindow_unlockAndPost(window);

if (info->loopCount != 0 && info->currentLoop == info->loopCount) {
Expand All @@ -151,8 +156,24 @@ Java_pl_droidsonroids_gif_GifInfoHandle_bindSurface(JNIEnv *env, jclass __unused
}

while (1) {
pollResult = poll(&info->surfaceDescriptor->eventPollFd, 1, (int) invalidationDelayMillis);
long renderingStartTime = getRealTime();

if (pollResult < 0) {
throwException(env, ILLEGAL_STATE_EXCEPTION_ERRNO, "Poll failed");
break;
}
else if (pollResult > 0) {
if (info->surfaceDescriptor->surfaceBackupPtr == NULL) {
info->surfaceDescriptor->surfaceBackupPtr = malloc(bufferSize);
if (info->surfaceDescriptor->surfaceBackupPtr == NULL) {
throwException(env, OUT_OF_MEMORY_ERROR, OOME_MESSAGE);
break;
}
}
memcpy(info->surfaceDescriptor->surfaceBackupPtr, buffer.bits, bufferSize);
break;
}
oldBufferBits = buffer.bits;
THROW_AND_BREAK_ON_NONZERO_RESULT(ANativeWindow_lock(window, &buffer, NULL), "Window lock failed");

Expand All @@ -176,31 +197,13 @@ Java_pl_droidsonroids_gif_GifInfoHandle_bindSurface(JNIEnv *env, jclass __unused
pthread_mutex_unlock(&info->surfaceDescriptor->slurpMutex);

ANativeWindow_unlockAndPost(window);
// if (info->gifFilePtr->Error == D_GIF_ERR_NOT_ENOUGH_MEM)
// break;
long invalidationDelayMillis = calculateInvalidationDelay(info, renderingStartTime, frameDuration);

invalidationDelayMillis = calculateInvalidationDelay(info, renderingStartTime, frameDuration);

if (info->lastFrameRemainder >= 0) {
invalidationDelayMillis = info->lastFrameRemainder;
info->lastFrameRemainder = -1;
}

pollResult = poll(&info->surfaceDescriptor->eventPollFd, 1, (int) invalidationDelayMillis);
if (pollResult < 0) {
throwException(env, ILLEGAL_STATE_EXCEPTION_ERRNO, "Poll failed");
break;
}
else if (pollResult > 0) {
if (info->surfaceDescriptor->surfaceBackupPtr == NULL) {
info->surfaceDescriptor->surfaceBackupPtr = malloc(bufferSize);
if (info->surfaceDescriptor->surfaceBackupPtr == NULL) {
throwException(env, OUT_OF_MEMORY_ERROR, OOME_MESSAGE);
break;
}
}
memcpy(info->surfaceDescriptor->surfaceBackupPtr, buffer.bits, bufferSize);
break;
}
}

ANativeWindow_release(window);
Expand Down

0 comments on commit f1bed87

Please sign in to comment.