Exemplo n.º 1
0
        /// <summary>
        /// Tokenizes the GIF image's byte[] into constituent components.
        /// </summary>
        public static DataStream ParseDataStream(byte[] data)
        {
            DataStream ds = new DataStream();

            using (MemoryStream ms = new MemoryStream(data))
            {
                using (BinaryReader br = new BinaryReader(ms))
                {
                    ds.Header = VcvjParser.ParseHeader(br.ReadBytes(Header.TotalBlockLength));

                    ds.LogicalScreen = new LogicalScreen()
                    {
                        LogicalScreenDescriptor = VcvjParser.ParseLogicalScreenDescriptor(br.ReadBytes(LogicalScreenDescriptor.TotalBlockLength))
                    };

                    if (ds.LogicalScreen.LogicalScreenDescriptor.HasGlobalColorTable)
                    {
                        ds.LogicalScreen.GlobalColorTable = VcvjParser.ParseGlobalColorTable(
                            br.ReadBytes(ds.LogicalScreen.LogicalScreenDescriptor.GlobalColorTableLength)
                            );
                    }

                    while (br.PeekChar() != -1)
                    {
                        long currentIndex = br.BaseStream.Position;
                        byte currentByte  = data[currentIndex];
                        byte?nextByte     = currentIndex + 1 < data.Length ? (byte?)data[currentIndex + 1] : (byte?)null;

                        if (ParserUtils.IsTrailerMarker(currentByte))
                        {
                            ds.Trailer = new Trailer(br.ReadByte());
                            continue;
                        }
                        else if (ParserUtils.IsApplicationExtensionBlock(currentByte, nextByte))
                        {
                            ApplicationExtension ae = VcvjParser.ParseApplicationExtension(
                                br.ReadBytes(VcvjParser.GetApplicationExtensionBlockLength(currentIndex, ref data))
                                );

                            ds.DataBlocks.Add(ae);
                            continue;
                        }
                        else if (ParserUtils.IsCommentExtensionBlock(currentByte, nextByte))
                        {
                            int totalBlockLength = data[currentIndex + 2] + 4;
                            CommentExtension ce  = VcvjParser.ParseCommentExtension(br.ReadBytes(totalBlockLength));

                            ds.DataBlocks.Add(ce);
                            continue;
                        }
                        else
                        {
                            GraphicBlock gb = new GraphicBlock();

                            if (ParserUtils.IsGraphicControlExtensionBlock(currentByte, nextByte))
                            {
                                gb.GraphicControlExtension = VcvjParser.ParseGraphicControlExtension(
                                    br.ReadBytes(8)
                                    );

                                currentIndex = br.BaseStream.Position;
                                currentByte  = data[currentIndex];
                                nextByte     = data[currentIndex + 1];
                            }

                            if (ParserUtils.IsImageDescriptor(currentByte))
                            {
                                TableBasedImage tbi = new TableBasedImage()
                                {
                                    ImageDescriptor = VcvjParser.ParseImageDescriptor(
                                        br.ReadBytes(10)
                                        )
                                };

                                if (tbi.ImageDescriptor.LocalColorTableFlag)
                                {
                                    tbi.LocalColorTable = VcvjParser.ParseLocalColorTable(
                                        br.ReadBytes(tbi.ImageDescriptor.LocalColorTableLength)
                                        );
                                }

                                currentIndex = br.BaseStream.Position;
                                currentByte  = data[currentIndex];
                                nextByte     = data[currentIndex + 1];

                                tbi.ImageData = VcvjParser.ParseImageData(
                                    br.ReadBytes(VcvjParser.GetImageDataBlockLength(currentIndex, ref data))
                                    );

                                gb.GraphicRenderingBlock = tbi;

                                ds.DataBlocks.Add(gb);
                                continue;
                            }
                            else if (ParserUtils.IsPlaintextExtension(currentByte, nextByte))
                            {
                                //GraphicBlock gb = new GraphicBlock()
                                //{
                                //};
                            }
                            else if (ParserUtils.IsApplicationExtensionBlock(currentByte, nextByte))
                            {
                                ApplicationExtension ae = VcvjParser.ParseApplicationExtension(
                                    br.ReadBytes(VcvjParser.GetApplicationExtensionBlockLength(currentIndex, ref data))
                                    );

                                ds.DataBlocks.Add(ae);
                                continue;
                            }
                            else if (ParserUtils.IsCommentExtensionBlock(currentByte, nextByte))
                            {
                                int totalBlockLength = data[currentIndex + 2] + 4;
                                CommentExtension ce  = VcvjParser.ParseCommentExtension(br.ReadBytes(totalBlockLength));

                                ds.DataBlocks.Add(ce);
                                continue;
                            }
                            else
                            {
                                throw new UnidentifiedBlockException(
                                          string.Format(
                                              "The current byte is {0} and the next one is {1}. Not really sure what to make of this.",
                                              currentByte.ToString(),
                                              String.IsNullOrEmpty(nextByte.ToString()) ? "null" : nextByte.ToString()
                                              )
                                          );
                            }
                        }
                    }
                }
            }
            return(ds);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Compiles the parsed tokens/components back into a byte array.
        /// </summary>
        public void CompileByteArray()
        {
            List <byte> output = new List <byte>();

            output.AddRange(DataStream.Header.Bytes);
            output.AddRange(DataStream.LogicalScreen.LogicalScreenDescriptor.Bytes);

            if (DataStream.LogicalScreen.GlobalColorTable != null)
            {
                output.AddRange(DataStream.LogicalScreen.GlobalColorTable.Bytes);
            }

            foreach (DataBlock db in DataStream.DataBlocks)
            {
                if (db is GraphicBlock)
                {
                    GraphicBlock gb = (GraphicBlock)db;

                    if (gb.GraphicControlExtension != null)
                    {
                        output.AddRange(gb.GraphicControlExtension.Bytes);
                    }

                    if (gb.GraphicRenderingBlock is PlainTextExtension)
                    {
                        PlainTextExtension pte = (PlainTextExtension)gb.GraphicRenderingBlock;

                        output.AddRange(pte.Bytes);
                    }
                    else if (gb.GraphicRenderingBlock is TableBasedImage)
                    {
                        TableBasedImage tbi = (TableBasedImage)gb.GraphicRenderingBlock;

                        output.AddRange(tbi.ImageDescriptor.Bytes);

                        if (tbi.LocalColorTable != null)
                        {
                            output.AddRange(tbi.LocalColorTable.Bytes);
                        }

                        output.AddRange(tbi.ImageData.Bytes);
                    }
                }
                else if (db is SpecialPurposeBlock)
                {
                    SpecialPurposeBlock spb = (SpecialPurposeBlock)db;

                    if (spb is ApplicationExtension)
                    {
                        ApplicationExtension ae = (ApplicationExtension)spb;

                        output.AddRange(ae.Bytes);
                    }
                    else if (spb is CommentExtension)
                    {
                        CommentExtension ce = (CommentExtension)spb;

                        output.AddRange(ce.Bytes);
                    }
                }
            }

            output.AddRange(DataStream.Trailer.Bytes);

            DataStream.Bytes = output.ToArray();
        }