123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- /////////////////////////////////////////////////////////////////////////////////
- //
- // Photoshop PSD FileType Plugin for Paint.NET
- // http://psdplugin.codeplex.com/
- //
- // This software is provided under the MIT License:
- // Copyright (c) 2006-2007 Frank Blumenberg
- // Copyright (c) 2010-2013 Tao Yue
- //
- // Portions of this file are provided under the BSD 3-clause License:
- // Copyright (c) 2006, Jonas Beckeman
- //
- // See LICENSE.txt for complete licensing and attribution information.
- //
- /////////////////////////////////////////////////////////////////////////////////
-
- using System;
- using System.Diagnostics;
- using System.IO;
-
-
- namespace PhotoshopFile
- {
- internal class RleReader
- {
- private Stream stream;
-
- public RleReader(Stream stream)
- {
- this.stream = stream;
- }
-
- /// <summary>
- /// Decodes a PackBits RLE stream.
- /// </summary>
- /// <param name="buffer">Output buffer for decoded data.</param>
- /// <param name="offset">Offset at which to begin writing.</param>
- /// <param name="count">Number of bytes to decode from the stream.</param>
- public int Read(byte[] buffer, int offset, int count)
- {
- if (!Util.CheckBufferBounds(buffer, offset, count))
- throw new ArgumentOutOfRangeException();
-
- // Pin the entire buffer now, so that we don't keep pinning and unpinning
- // for each RLE packet.
- var ptrBuffer = buffer;
- //fixed (byte* ptrBuffer = &buffer[0])
- {
- int bytesLeft = count;
- int bufferIdx = offset;
- while (bytesLeft > 0)
- {
- // ReadByte returns an unsigned byte, but we want a signed byte.
- var flagCounter = unchecked((sbyte)stream.ReadByte());
-
- // Raw packet
- if (flagCounter > 0)
- {
- var readLength = flagCounter + 1;
- if (bytesLeft < readLength)
- throw new RleException("Raw packet overruns the decode window.");
-
- stream.Read(buffer, bufferIdx, readLength);
-
- bufferIdx += readLength;
- bytesLeft -= readLength;
- }
- // RLE packet
- else if (flagCounter > -128)
- {
- var runLength = 1 - flagCounter;
- var byteValue = (byte)stream.ReadByte();
- if (runLength > bytesLeft)
- throw new RleException("RLE packet overruns the decode window.");
-
- //byte* ptr = ptrBuffer + bufferIdx;
- //byte* ptrEnd = ptr + runLength;
- //while (ptr < ptrEnd)
- //{
- // *ptr = byteValue;
- // ptr++;
- //}
-
- int start = 0;
- while (start < runLength)
- {
- ptrBuffer[bufferIdx + start] = byteValue;
- start++;
- }
-
- bufferIdx += runLength;
- bytesLeft -= runLength;
- }
- else
- {
- // The canonical PackBits algorithm will never emit 0x80 (-128), but
- // some programs do. Simply skip over the byte.
- }
- }
-
- Debug.Assert(bytesLeft == 0);
- return count - bytesLeft;
- }
- }
- }
- }
|