+ if( !thisFrame->data )
+ {
+ LOADERR("LOAD_ERROR_RESOURCE_ALLOCATION_FAILED");
+ }
+
+ // if we have no prior frame OR prior frame data... empty
+ if( (!previousFrame) || (!previousFrame->data) )
+ {
+ first = true;
+ frameInfo = &(thisFrame->info);
+ memset( thisFrame->data, 0, prop.w * prop.h * sizeof(uint32_t) );
+ }
+ // we have a prior frame to copy data from...
+ else
+ {
+ frameInfo = &( previousFrame->info );
+
+ // fix coords of sub image in case it goes out...
+ ClipCoordinates( prop.w, prop.h, &xin, &yin,
+ frameInfo->x, frameInfo->y, frameInfo->w, frameInfo->h,
+ &x, &y, &w, &h );
+
+ // if dispose mode is not restore - then copy pre frame
+ if( frameInfo->dispose != DISPOSE_PREVIOUS )
+ {
+ memcpy( thisFrame->data, previousFrame->data, prop.w * prop.h * sizeof(uint32_t) );
+ }
+
+ // if dispose mode is "background" then fill with bg
+ if( frameInfo->dispose == DISPOSE_BACKGROUND )
+ {
+ FillFrame( thisFrame->data, prop.w, gif, frameInfo, x, y, w, h );
+ }
+
+ else if( frameInfo->dispose == DISPOSE_PREVIOUS ) // GIF_DISPOSE_RESTORE
+ {
+ int prevIndex = 2;
+ do
+ {
+ // Find last preserved frame.
+ lastPreservedFrame = FindFrame( animated, imageNumber - prevIndex );
+ prevIndex++;
+ } while( lastPreservedFrame && lastPreservedFrame->info.dispose == DISPOSE_PREVIOUS );
+
+ if ( lastPreservedFrame )
+ {
+ memcpy( thisFrame->data, lastPreservedFrame->data, prop.w * prop.h * sizeof(uint32_t) );
+ }
+ }
+ }
+ // now draw this frame on top
+ frameInfo = &( thisFrame->info );
+ ClipCoordinates( prop.w, prop.h, &xin, &yin,
+ frameInfo->x, frameInfo->y, frameInfo->w, frameInfo->h,
+ &x, &y, &w, &h );
+ if( !DecodeImage( gif, thisFrame->data, prop.w,
+ xin, yin, frameInfo->transparent,
+ x, y, w, h, first) )
+ {
+ LOADERR("LOAD_ERROR_CORRUPT_FILE");
+ }
+
+ // mark as loaded and done
+ thisFrame->loaded = true;
+
+ FlushFrames( animated, prop.w, prop.h, thisFrame, previousFrame, lastPreservedFrame );
+ }
+ // if we hve a frame BUT the image is not animated... different
+ // path
+ else if( (thisFrame) && (!thisFrame->data) && (!animated.animated) )
+ {
+ // if we don't have the data decoded yet - decode it
+ if( (!thisFrame->loaded) || (!thisFrame->data) )
+ {
+ // use frame info but we WONT allocate frame pixels
+ frameInfo = &( thisFrame->info );
+ ClipCoordinates( prop.w, prop.h, &xin, &yin,
+ frameInfo->x, frameInfo->y, frameInfo->w, frameInfo->h,
+ &x, &y, &w, &h );
+
+ // clear out all pixels
+ FillFrame( reinterpret_cast<uint32_t *>(pixels), prop.w, gif, frameInfo, 0, 0, prop.w, prop.h );
+
+ // and decode the gif with overwriting
+ if( !DecodeImage( gif, reinterpret_cast<uint32_t *>(pixels), prop.w,
+ xin, yin, frameInfo->transparent, x, y, w, h, true) )
+ {
+ LOADERR("LOAD_ERROR_CORRUPT_FILE");
+ }
+
+ // mark as loaded and done
+ thisFrame->loaded = true;
+ }
+ // flush mem we don't need (at expense of decode cpu)
+ }
+ else
+ {
+ // skip decoding and just walk image to next
+ if( DGifGetCode( gif, &img_code, &img ) == GIF_ERROR )
+ {
+ LOADERR("LOAD_ERROR_UNKNOWN_FORMAT");
+ }
+
+ while( img )
+ {
+ img = NULL;
+ DGifGetCodeNext( gif, &img );
+ }
+ }
+
+ imageNumber++;
+ // if we found the image we wanted - get out of here
+ if( imageNumber > index )
+ {
+ break;
+ }
+ }
+ } while( rec != TERMINATE_RECORD_TYPE );
+
+ // if we are at the end of the animation or not animated, close file
+ loaderInfo.imageNumber = imageNumber;
+ if( (animated.frameCount <= 1) || (rec == TERMINATE_RECORD_TYPE) )
+ {
+#if (GIFLIB_MAJOR > 5) || ((GIFLIB_MAJOR == 5) && (GIFLIB_MINOR >= 1))
+ if( loaderInfo.gif )
+ {
+ DGifCloseFile( loaderInfo.gif, NULL );
+ }
+#else
+ if( loaderInfo.gif )
+ {
+ DGifCloseFile( loaderInfo.gif );
+ }
+#endif
+
+ loaderInfo.gif = NULL;
+ loaderInfo.imageNumber = 0;
+ }
+
+on_ok:
+ // no errors in header scan etc. so set err and return value
+ *error = 0;
+ ret = true;
+
+ // if it was an animated image we need to copy the data to the
+ // pixels for the image from the frame holding the data
+ if( animated.animated && frame->data )