@@ -165,18 +165,31 @@ void nsGIFDecoder2::BeginImageFrame(uint16_t aDepth)
165165 else
166166 format = gfxASurface::ImageFormatRGB24;
167167
168+ MOZ_ASSERT (HasSize ());
169+
168170 // Use correct format, RGB for first frame, PAL for following frames
169171 // and include transparency to allow for optimization of opaque images
170172 if (mGIFStruct .images_decoded ) {
171173 // Image data is stored with original depth and palette
172174 NeedNewFrame (mGIFStruct .images_decoded , mGIFStruct .x_offset ,
173175 mGIFStruct .y_offset , mGIFStruct .width , mGIFStruct .height ,
174176 format, aDepth);
175- } else {
177+ }
178+
179+ // Our first full frame is automatically created by the image decoding
180+ // infrastructure. Just use it as long as we're not creating a subframe.
181+ else if (mGIFStruct .x_offset != 0 || mGIFStruct .y_offset != 0 ||
182+ int32_t (mGIFStruct .width ) != mImageMetadata .GetWidth () ||
183+ int32_t (mGIFStruct .height ) != mImageMetadata .GetHeight ()) {
176184 // Regardless of depth of input, image is decoded into 24bit RGB
177185 NeedNewFrame (mGIFStruct .images_decoded , mGIFStruct .x_offset ,
178186 mGIFStruct .y_offset , mGIFStruct .width , mGIFStruct .height ,
179187 format);
188+ } else {
189+ // Our preallocated frame matches up, with the possible exception of alpha.
190+ if (format == gfxASurface::ImageFormatRGB24) {
191+ GetCurrentFrame ()->SetHasNoAlpha ();
192+ }
180193 }
181194
182195 mCurrentFrame = mGIFStruct .images_decoded ;
@@ -893,19 +906,23 @@ nsGIFDecoder2::WriteInternal(const char *aBuffer, uint32_t aCount)
893906 mColorMask = 0xFF >> (8 - realDepth);
894907 BeginImageFrame (realDepth);
895908
896- // We now need a new frame from the decoder framework. We leave all our
897- // data in the buffer as if it wasn't consumed, copy to our hold and return
898- // to the decoder framework.
899- uint32_t size = len + mGIFStruct .bytes_to_consume + mGIFStruct .bytes_in_hold ;
900- if (size) {
901- if (SetHold (q, mGIFStruct .bytes_to_consume + mGIFStruct .bytes_in_hold , buf, len)) {
902- // Back into the decoder infrastructure so we can get called again.
903- GETN (9 , gif_image_header_continue);
904- return ;
909+ if (NeedsNewFrame ()) {
910+ // We now need a new frame from the decoder framework. We leave all our
911+ // data in the buffer as if it wasn't consumed, copy to our hold and return
912+ // to the decoder framework.
913+ uint32_t size = len + mGIFStruct .bytes_to_consume + mGIFStruct .bytes_in_hold ;
914+ if (size) {
915+ if (SetHold (q, mGIFStruct .bytes_to_consume + mGIFStruct .bytes_in_hold , buf, len)) {
916+ // Back into the decoder infrastructure so we can get called again.
917+ GETN (9 , gif_image_header_continue);
918+ return ;
919+ }
905920 }
921+ break ;
922+ } else {
923+ // FALL THROUGH
906924 }
907925 }
908- break ;
909926
910927 case gif_image_header_continue:
911928 {
0 commit comments