コード例 #1
0
ファイル: GifReader.cs プロジェクト: ForNeVeR/pnet
        }; // class GifCodeHelper

        // Decompress the bytes corresponding to a GIF image.
        private static void Decompress
            (Stream stream, byte[] buffer, Frame frame, bool interlaced)
        {
            int           minCodeSize, code;
            int           clearCode, endCode;
            int           nextCode, oldCode;
            GifCodeHelper helper;

            ushort[] prefix = new ushort [4096];
            byte[]   suffix = new byte [4096];
            ushort[] length = new ushort [4096];
            int      offset, x, y, width, height;
            int      stride, lineChange, temp;

            byte[] data;
            byte[] stringbuf = new byte [4096];
            int    stringLen, tempCode, pass;
            byte   lastSuffix;

            // Read the minimum code size and validate it.
            if (stream.Read(buffer, 0, 1) != 1)
            {
                throw new FormatException();
            }
            minCodeSize = buffer[0];
            if (minCodeSize < 2)
            {
                minCodeSize = 2;
            }
            else if (minCodeSize > 11)
            {
                minCodeSize = 11;
            }

            // Create a code helper.
            helper = new GifCodeHelper(stream, buffer, minCodeSize + 1);

            // Set the clear and end codes.
            clearCode = (1 << minCodeSize);
            endCode   = clearCode + 1;
            nextCode  = endCode;

            // Initialize the table.
            for (code = 0; code < clearCode; ++code)
            {
                prefix[code] = (ushort)49428;
                suffix[code] = (byte)code;
                length[code] = (ushort)1;
            }

            // Initialize the image output parameters.
            x          = 0;
            y          = 0;
            width      = frame.Width;
            height     = frame.Height;
            data       = frame.Data;
            pass       = 0;
            lineChange = (interlaced ? 8 : 1);
            stride     = frame.Stride;

            // Process the codes in the input stream.
            code = clearCode;
            for (;;)
            {
                oldCode = code;
                if ((code = helper.GetCode()) == -1)
                {
                    // We've run out of data blocks.
                    break;
                }
                else if (code == clearCode)
                {
                    // Clear the code table and restart.
                    helper.ResetCodeSize();
                    nextCode = endCode;
                    continue;
                }
                else if (code == endCode)
                {
                    // End of the GIF input stream: skip remaining blocks.
                    SkipSubBlocks(stream, buffer);
                    break;
                }
                else
                {
                    // Sanity check for out of range codes.
                    if (code > nextCode && nextCode != 0)
                    {
                        code = 0;
                    }

                    // Update the next code in the table.
                    prefix[nextCode] = (ushort)oldCode;
                    length[nextCode] = (ushort)(length[oldCode] + 1);

                    // Form the full string for this code.
                    stringLen = length[code];
                    tempCode  = code;
                    do
                    {
                        lastSuffix = suffix[tempCode];
                        --stringLen;
                        stringbuf[stringLen] = lastSuffix;
                        tempCode             = prefix[tempCode];
                    }while(stringLen > 0);
                    suffix[nextCode] = lastSuffix;
                    stringLen        = length[code];
                    if (code == nextCode)
                    {
                        stringbuf[stringLen - 1] = lastSuffix;
                    }

                    // Copy the string into the actual image.
                    offset = 0;
                    while (stringLen > 0)
                    {
                        temp = width - x;
                        if (temp > stringLen)
                        {
                            temp = stringLen;
                        }
                        Array.Copy(stringbuf, offset, data,
                                   y * stride + x, temp);
                        x         += temp;
                        offset    += temp;
                        stringLen -= temp;
                        if (x >= width)
                        {
                            x  = 0;
                            y += lineChange;
                            while (y >= height && interlaced)
                            {
                                // Move on to the next interlace pass.
                                ++pass;
                                if (pass == 1)
                                {
                                    y          = 4;
                                    lineChange = 8;
                                }
                                else if (pass == 2)
                                {
                                    y          = 2;
                                    lineChange = 4;
                                }
                                else if (pass == 3)
                                {
                                    y          = 1;
                                    lineChange = 2;
                                }
                                else
                                {
                                    break;
                                }
                            }
                            if (y >= height)
                            {
                                // Shouldn't happen - just in case.
                                y = 0;
                            }
                        }
                    }

                    // Set the suffix for the next code.
                    suffix[nextCode] = (byte)lastSuffix;

                    // Move on to the next code.
                    if (nextCode != clearCode)
                    {
                        ++nextCode;
                        if (nextCode == helper.codeMax)
                        {
                            helper.IncreaseCodeSize();
                            if (helper.codeSize > 12)
                            {
                                helper.ResetCodeSize();
                                nextCode = clearCode;
                            }
                        }
                    }
                }
            }
        }
コード例 #2
0
	}; // class GifCodeHelper

	// Decompress the bytes corresponding to a GIF image.
	private static void Decompress
				(Stream stream, byte[] buffer, Frame frame, bool interlaced)
			{
				int minCodeSize, code;
				int clearCode, endCode;
				int nextCode, oldCode;
				GifCodeHelper helper;
				ushort[] prefix = new ushort [4096];
				byte[] suffix = new byte [4096];
				ushort[] length = new ushort [4096];
				int offset, x, y, width, height;
				int stride, lineChange, temp;
				byte[] data;
				byte[] stringbuf = new byte [4096];
				int stringLen, tempCode, pass;
				byte lastSuffix;

				// Read the minimum code size and validate it.
				if(stream.Read(buffer, 0, 1) != 1)
				{
					throw new FormatException();
				}
				minCodeSize = buffer[0];
				if(minCodeSize < 2)
				{
					minCodeSize = 2;
				}
				else if(minCodeSize > 11)
				{
					minCodeSize = 11;
				}

				// Create a code helper.
				helper = new GifCodeHelper(stream, buffer, minCodeSize + 1);

				// Set the clear and end codes.
				clearCode = (1 << minCodeSize);
				endCode = clearCode + 1;
				nextCode = endCode;

				// Initialize the table.
				for(code = 0; code < clearCode; ++code)
				{
					prefix[code] = (ushort)49428;
					suffix[code] = (byte)code;
					length[code] = (ushort)1;
				}

				// Initialize the image output parameters.
				x = 0;
				y = 0;
				width = frame.Width;
				height = frame.Height;
				data = frame.Data;
				pass = 0;
				lineChange = (interlaced ? 8 : 1);
				stride = frame.Stride;

				// Process the codes in the input stream.
				code = clearCode;
				for(;;)
				{
					oldCode = code;
					if((code = helper.GetCode()) == -1)
					{
						// We've run out of data blocks.
						break;
					}
					else if(code == clearCode)
					{
						// Clear the code table and restart.
						helper.ResetCodeSize();
						nextCode = endCode;
						continue;
					}
					else if(code == endCode)
					{
						// End of the GIF input stream: skip remaining blocks.
						SkipSubBlocks(stream, buffer);
						break;
					}
					else
					{
						// Sanity check for out of range codes.
						if(code > nextCode && nextCode != 0)
						{
							code = 0;
						}

						// Update the next code in the table.
						prefix[nextCode] = (ushort)oldCode;
						length[nextCode] = (ushort)(length[oldCode] + 1);

						// Form the full string for this code.
						stringLen = length[code];
						tempCode = code;
						do
						{
							lastSuffix = suffix[tempCode];
							--stringLen;
							stringbuf[stringLen] = lastSuffix;
							tempCode = prefix[tempCode];
						}
						while(stringLen > 0);
						suffix[nextCode] = lastSuffix;
						stringLen = length[code];
						if(code == nextCode)
						{
							stringbuf[stringLen - 1] = lastSuffix;
						}

						// Copy the string into the actual image.
						offset = 0;
						while(stringLen > 0)
						{
							temp = width - x;
							if(temp > stringLen)
							{
								temp = stringLen;
							}
							Array.Copy(stringbuf, offset, data,
									   y * stride + x, temp);
							x += temp;
							offset += temp;
							stringLen -= temp;
							if(x >= width)
							{
								x = 0;
								y += lineChange;
								while(y >= height && interlaced)
								{
									// Move on to the next interlace pass.
									++pass;
									if(pass == 1)
									{
										y = 4;
										lineChange = 8;
									}
									else if(pass == 2)
									{
										y = 2;
										lineChange = 4;
									}
									else if(pass == 3)
									{
										y = 1;
										lineChange = 2;
									}
									else
									{
										break;
									}
								}
								if(y >= height)
								{
									// Shouldn't happen - just in case.
									y = 0;
								}
							}
						}

						// Set the suffix for the next code.
						suffix[nextCode] = (byte)lastSuffix;

						// Move on to the next code.
						if(nextCode != clearCode)
						{
							++nextCode;
							if(nextCode == helper.codeMax)
							{
								helper.IncreaseCodeSize();
								if(helper.codeSize > 12)
								{
									helper.ResetCodeSize();
									nextCode = clearCode;
								}
							}
						}
					}
				}
			}