Browse Source

Somehow this was reverted!

af/merge-core
James Jackson-South 10 years ago
parent
commit
3d299e60df
  1. 109
      src/ImageSharp/Formats/Gif/GifDecoderCore.cs

109
src/ImageSharp/Formats/Gif/GifDecoderCore.cs

@ -42,9 +42,9 @@ namespace ImageSharp.Formats
private int globalColorTableLength; private int globalColorTableLength;
/// <summary> /// <summary>
/// The previous frame. /// The next frame.
/// </summary> /// </summary>
private ImageFrame<TColor> previousFrame; private ImageFrame<TColor> nextFrame;
/// <summary> /// <summary>
/// The area to restore. /// The area to restore.
@ -319,7 +319,7 @@ namespace ImageSharp.Formats
ImageBase<TColor> image; ImageBase<TColor> image;
if (this.previousFrame == null) if (this.nextFrame == null)
{ {
image = this.decodedImage; image = this.decodedImage;
@ -333,10 +333,10 @@ namespace ImageSharp.Formats
if (this.graphicsControlExtension != null && if (this.graphicsControlExtension != null &&
this.graphicsControlExtension.DisposalMethod == DisposalMethod.RestoreToPrevious) this.graphicsControlExtension.DisposalMethod == DisposalMethod.RestoreToPrevious)
{ {
previousFrame = this.previousFrame; previousFrame = this.nextFrame;
} }
currentFrame = this.previousFrame.Clone(); currentFrame = this.nextFrame.Clone();
image = currentFrame; image = currentFrame;
@ -357,70 +357,85 @@ namespace ImageSharp.Formats
using (PixelAccessor<TColor> pixelAccessor = image.Lock()) using (PixelAccessor<TColor> pixelAccessor = image.Lock())
{ {
for (int y = descriptor.Top; y < descriptor.Top + descriptor.Height; y++) using (PixelArea<TColor> pixelRow = new PixelArea<TColor>(imageWidth, ComponentOrder.XYZW))
{ {
// Check if this image is interlaced. for (int y = descriptor.Top; y < descriptor.Top + descriptor.Height; y++)
int writeY; // the target y offset to write to
if (descriptor.InterlaceFlag)
{ {
// If so then we read lines at predetermined offsets. // Check if this image is interlaced.
// When an entire image height worth of offset lines has been read we consider this a pass. int writeY; // the target y offset to write to
// With each pass the number of offset lines changes and the starting line changes. if (descriptor.InterlaceFlag)
if (interlaceY >= descriptor.Height)
{ {
interlacePass++; // If so then we read lines at predetermined offsets.
switch (interlacePass) // When an entire image height worth of offset lines has been read we consider this a pass.
// With each pass the number of offset lines changes and the starting line changes.
if (interlaceY >= descriptor.Height)
{ {
case 1: interlacePass++;
interlaceY = 4; switch (interlacePass)
break; {
case 2: case 1:
interlaceY = 2; interlaceY = 4;
interlaceIncrement = 4; break;
break; case 2:
case 3: interlaceY = 2;
interlaceY = 1; interlaceIncrement = 4;
interlaceIncrement = 2; break;
break; case 3:
interlaceY = 1;
interlaceIncrement = 2;
break;
}
} }
}
writeY = interlaceY + descriptor.Top; writeY = interlaceY + descriptor.Top;
interlaceY += interlaceIncrement; interlaceY += interlaceIncrement;
} }
else else
{ {
writeY = y; writeY = y;
} }
for (int x = descriptor.Left; x < descriptor.Left + descriptor.Width; x++) pixelAccessor.CopyTo(pixelRow, writeY, descriptor.Left);
{
int index = indices[i];
if (this.graphicsControlExtension == null || byte* pixelBase = pixelRow.PixelBase;
this.graphicsControlExtension.TransparencyFlag == false || for (int x = 0; x < descriptor.Width; x++)
this.graphicsControlExtension.TransparencyIndex != index)
{ {
int indexOffset = index * 3; int index = indices[i];
if (this.graphicsControlExtension == null ||
this.graphicsControlExtension.TransparencyFlag == false ||
this.graphicsControlExtension.TransparencyIndex != index)
{
int indexOffset = index * 3;
*(pixelBase + 0) = colorTable[indexOffset];
*(pixelBase + 1) = colorTable[indexOffset + 1];
*(pixelBase + 2) = colorTable[indexOffset + 2];
*(pixelBase + 3) = 255;
// TODO: This is actually 200us faster in benchmarking.
// int indexOffset = index * 3;
// TColor pixel = default(TColor);
// pixel.PackFromBytes(colorTable[indexOffset], colorTable[indexOffset + 1], colorTable[indexOffset + 2], 255);
// currentPixels[x, writeY] = pixel;
}
TColor pixel = default(TColor); i++;
pixel.PackFromBytes(colorTable[indexOffset], colorTable[indexOffset + 1], colorTable[indexOffset + 2], 255); pixelBase += 4;
pixelAccessor[x, writeY] = pixel;
} }
i++; pixelAccessor.CopyFrom(pixelRow, writeY, descriptor.Left);
} }
} }
} }
if (previousFrame != null) if (previousFrame != null)
{ {
this.previousFrame = previousFrame; this.nextFrame = previousFrame;
return; return;
} }
this.previousFrame = currentFrame == null ? this.decodedImage.ToFrame() : currentFrame; this.nextFrame = currentFrame == null ? this.decodedImage.ToFrame() : currentFrame.Clone();
if (this.graphicsControlExtension != null && if (this.graphicsControlExtension != null &&
this.graphicsControlExtension.DisposalMethod == DisposalMethod.RestoreToBackground) this.graphicsControlExtension.DisposalMethod == DisposalMethod.RestoreToBackground)

Loading…
Cancel
Save