Beispiel #1
0
        private static void CheckFrame(Stream s,
                                       ColourTable globalColourTable,
                                       Bitmap bitmap)
        {
            CheckExtensionIntroducer(s);
            CheckGraphicControlLabel(s);
            CheckGraphicControlExtension(s);
            CheckImageSeparator(s);
            bool shouldHaveLocalColourTable
                = (globalColourTable == null) ? true : false;
            int             lctSizeBits = shouldHaveLocalColourTable ? 1 : 0;
            ImageDescriptor id
                = CheckImageDescriptor(s,
                                       shouldHaveLocalColourTable,
                                       lctSizeBits);

            if (globalColourTable == null)
            {
                // no global colour table so must be a local colour table on
                // each frame
                ColourTable lct = CheckColourTable(s, id.LocalColourTableSize);
                CheckImageData(s, lct, id, bitmap);
            }
            else
            {
                CheckImageData(s, globalColourTable, id, bitmap);
            }
            CheckBlockTerminator(s);
        }
Beispiel #2
0
        /// <summary>
        /// Returns a colour table containing the colours of the quantized image.
        /// </summary>
        /// <returns>
        /// A colour table containing up to 256 colours, being the colours of
        /// the image after quantization.
        /// </returns>
        private ColourTable ColourMap()
        {
            ColourTable map = new ColourTable();

            int[] originalIndices = new int[_neuronCount];
            int[] thisNeuron;

            // Build an array of the original indices of the neurons in the
            // network, before the BuildIndex method reordered them.
            for (int neuronIndex = 0; neuronIndex < _neuronCount; neuronIndex++)
            {
                thisNeuron = _network[neuronIndex];
                originalIndices[thisNeuron[3]] = neuronIndex;
            }

            for (int i = 0; i < _neuronCount; i++)
            {
                int indexInNetwork = originalIndices[i];
                map.Add(Color.FromArgb(255,
                                       _network[indexInNetwork][0],
                                       _network[indexInNetwork][1],
                                       _network[indexInNetwork][2]));
            }
            return(map);
        }
        /// <summary>
        /// Returns the index within the supplied colour table of the colour
        /// closest to the supplied colour.
        /// </summary>
        /// <param name="colourToFind">
        /// The colour to find the closest match for.
        /// </param>
        /// <param name="colourTable">
        /// The active colour table.
        /// </param>
        /// <returns>
        /// Returns -1 if the supplied colour is null.
        /// </returns>
        private static int FindClosest(Color colourToFind,
                                       ColourTable colourTable)
        {
            if (colourTable == null)
            {
                // TESTME: FindClosest - null colour table
                return(-1);
            }
            int r      = colourToFind.R;
            int g      = colourToFind.G;
            int b      = colourToFind.B;
            int minpos = 0;
            int dmin   = 256 * 256 * 256;
            int len    = colourTable.Length;

            for (int i = 0; i < len; i++)
            {
                int dr = r - colourTable[i].R;
                int dg = g - colourTable[i].G;
                int db = b - colourTable[i].B;
                int d  = dr * dr + dg * dg + db * db;
                if (d < dmin)
                {
                    dmin   = d;
                    minpos = i;
                }
            }
            return(minpos);
        }
Beispiel #4
0
        /// <summary>
        /// Decodes the supplied GIF stream.
        /// </summary>
        public void Decode()
        {
            _frameDelays           = new List <int>();
            _loadedFrames          = new Queue <GifFrame>();
            _frames                = new Collection <GifFrame>();
            _applicationExtensions = new Collection <ApplicationExtension>();
            _gct = null;

            _header = new GifHeader(_stream);
            if (_header.ErrorState != ErrorState.Ok)
            {
                return;
            }

            _lsd = new LogicalScreenDescriptor(_stream);
            if (TestState(ErrorState.EndOfInputStream))
            {
                return;
            }

            if (_lsd.HasGlobalColourTable)
            {
                _gct = new ColourTable(_stream, _lsd.GlobalColourTableSize);
            }

            if (ConsolidatedState == ErrorState.Ok)
            {
                ReadContents(_stream);
            }

            ApplyMemoryFields();
        }
        /// <summary>
        /// Writes an image descriptor to the supplied stream.
        /// </summary>
        /// <param name="imageSize">
        /// The size, in pixels, of the image in this frame.
        /// </param>
        /// <param name="position">
        /// The position of this image within the logical screen.
        /// </param>
        /// <param name="localColourTable">
        /// The local colour table for this frame.
        /// Supply null if the global colour table is to be used for this frame.
        /// </param>
        /// <param name="outputStream">
        /// The stream to write to.
        /// </param>
        private static void WriteImageDescriptor(Size imageSize,
                                                 Point position,
                                                 ColourTable localColourTable,
                                                 Stream outputStream)
        {
            bool hasLocalColourTable;
            int  localColourTableSize;

            if (localColourTable == null)
            {
                hasLocalColourTable  = false;
                localColourTableSize = 0;
            }
            else
            {
                hasLocalColourTable  = true;
                localColourTableSize = localColourTable.SizeBits;
            }

            bool            isInterlaced             = false; // encoding of interlaced images not currently supported
            bool            localColourTableIsSorted = false; // sorting of colour tables not currently supported
            ImageDescriptor id = new ImageDescriptor(position,
                                                     imageSize,
                                                     hasLocalColourTable,
                                                     isInterlaced,
                                                     localColourTableIsSorted,
                                                     localColourTableSize);

            outputStream.WriteByte(GifComponent.CodeImageSeparator);
            id.WriteToStream(outputStream);
        }
Beispiel #6
0
        private void ConstructorStreamTest(bool xmlDebugging)
        {
            MemoryStream s = CreateStream();

            // Extra stuff not included in the frame stream, to pass to the
            // constructor.
            ColourTable             colourTable = WikipediaExample.GlobalColourTable;
            GraphicControlExtension ext         = WikipediaExample.GraphicControlExtension;
            LogicalScreenDescriptor lsd         = WikipediaExample.LogicalScreenDescriptor;

            _frame = new GifFrame(s, lsd, colourTable, ext, null, null, xmlDebugging);

            Assert.AreEqual(ErrorState.Ok, _frame.ConsolidatedState);

            WikipediaExample.CheckImage(_frame.TheImage);
            WikipediaExample.CheckImageDescriptor(_frame.ImageDescriptor);
            WikipediaExample.CheckGraphicControlExtension(_frame.GraphicControlExtension);
            WikipediaExample.CheckImageData(_frame.IndexedPixels);
            Assert.AreEqual(0, _frame.BackgroundColour.R);
            Assert.AreEqual(0, _frame.BackgroundColour.G);
            Assert.AreEqual(0, _frame.BackgroundColour.B);

            if (xmlDebugging)
            {
                Assert.AreEqual(ExpectedDebugXml, _frame.DebugXml);
            }
        }
Beispiel #7
0
 public GifFrame(Stream inputStream,
                 LogicalScreenDescriptor lsd,
                 ColourTable gct,
                 GraphicControlExtension gce,
                 GifFrame previousFrame,
                 GifFrame previousFrameBut1)
     : base(inputStream, lsd, gct, gce, previousFrame, previousFrameBut1)
 {
 }
Beispiel #8
0
        private static ColourTable CheckColourTable(Stream s,
                                                    int colourTableSize)
        {
            // read colour table
            ColourTable ct = new ColourTable(s, colourTableSize);

            Assert.AreEqual(ErrorState.Ok, ct.ConsolidatedState);
            return(ct);
        }
        protected ColourTable GetTextureClut(ushort clut, int length)
        {
            ColourTable colourTable = new ColourTable
            {
                clut        = clut,
                x           = (clut & 0x1F) << 4,      //(clut & 0x3F) << 4,
                    y       = (clut >> 6) & 0x1FF,
                    colours = null
            };

            Color[] colours = new Color[length];

            int scaledX = colourTable.x;
            int scaledY = colourTable.y;

            int yOffset = scaledY * _TotalWidth;

            for (int x = 0; x < length;)
            {
                int xOffset = scaledX;

                try
                {
                    xOffset += x;
                    ushort val = _TextureData[yOffset + xOffset];

                    ushort alpha = 255;
                    ushort red   = val;
                    ushort green = val;
                    ushort blue  = val;

                    blue  = (ushort)(((ushort)(val << 1) >> 11) << 3);
                    green = (ushort)(((ushort)(val << 6) >> 11) << 3);
                    red   = (ushort)(((ushort)(val << 11) >> 11) << 3);

                    alpha = (ushort)(val >> 15);
                    if (alpha != 0 || blue != 0 || green != 0 || red != 0)
                    {
                        alpha = 255;
                    }
                    else
                    {
                        alpha = 0;
                    }

                    colours[x++] = Color.FromArgb(alpha, red, green, blue);
                }
                catch (Exception ex)
                {
                }
            }

            colourTable.colours = colours;
            return(colourTable);
        }
Beispiel #10
0
        private ColourTable GetColorTable()
        {
            if (_colorTable != null || ColourSelectionMode != CGM.Commands.ColourSelectionMode.Type.INDEXED)
            {
                return(_colorTable);
            }

            _colorTable = Commands.SingleOrDefault(c => c.ElementClass == ClassCode.AttributeElements && c.ElementId == 34) as ColourTable;

            return(_colorTable);
        }
        private ColourTable SetActiveColourTable()
        {
            ColourTable act;             // active colour table

            if (_strategy == ColourTableStrategy.UseLocal)
            {
                if (_quantizerType == QuantizerType.UseSuppliedPalette)
                {
                    if (_frames[_encodingFrame].Palette == null)
                    {
                        // TESTME: SetActiveColourTable - SetActiveColourTable, UseSuppliedPalette, no palette supplied
                        string message
                            = "You have opted to use a local colour table built "
                              + "from a supplied palette, but frame "
                              + _encodingFrame
                              + "does not have a palette.";
                        throw new InvalidOperationException(message);
                    }
                    else
                    {
                        // Build local colour table from colours in the frame's
                        // supplied palette.
                        act = new ColourTable();
                        foreach (Color c in _frames[_encodingFrame].Palette)
                        {
                            act.Add(c);
                        }
                        act.Pad();
                    }
                }
                else
                {
                    // Build local colour table based on colours in the image.
                    Image thisImage = _frames[_encodingFrame].TheImage;
                    _pixelAnalysis = new PixelAnalysis(thisImage,
                                                       _quantizerType);
                    _pixelAnalysis.ColourQuality = _quality;
                    _pixelAnalysis.Analyse();
                    // make local colour table active
                    act = _pixelAnalysis.ColourTable;
                }
            }
            else
            {
                // make global colour table active
                act = _globalColourTable;
            }
            return(act);
        }
Beispiel #12
0
        /// <summary>
        /// Reads GIF image from stream
        /// </summary>
        /// <param name="inputStream">
        /// Stream containing GIF file.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// The supplied stream is null.
        /// </exception>
        private void ReadStream(Stream inputStream)
        {
            _frames = new Collection <GifFrame>();
            _applicationExtensions = new Collection <ApplicationExtension>();
            _gct = null;

            _readStreamCounterText = "Reading stream byte";
            AddCounter(_readStreamCounterText, (int)inputStream.Length);
            _header = new GifHeader(inputStream, XmlDebugging);
            MyProgressCounters[_readStreamCounterText].Value
                = (int)inputStream.Position;
            WriteDebugXmlNode(_header.DebugXmlReader);
            if (_header.ErrorState != ErrorState.Ok)
            {
                WriteDebugXmlFinish();
                return;
            }

            _lsd = new LogicalScreenDescriptor(inputStream, XmlDebugging);
            MyProgressCounters[_readStreamCounterText].Value
                = (int)inputStream.Position;
            WriteDebugXmlNode(_lsd.DebugXmlReader);
            if (TestState(ErrorState.EndOfInputStream))
            {
                WriteDebugXmlFinish();
                return;
            }

            if (_lsd.HasGlobalColourTable)
            {
                _gct = new ColourTable(inputStream,
                                       _lsd.GlobalColourTableSize,
                                       XmlDebugging);
                MyProgressCounters[_readStreamCounterText].Value
                    = (int)inputStream.Position;
                WriteDebugXmlNode(_gct.DebugXmlReader);
            }

            if (ConsolidatedState == ErrorState.Ok)
            {
                ReadContents(inputStream);
                MyProgressCounters[_readStreamCounterText].Value
                    = (int)inputStream.Position;
            }
            inputStream.Close();
            WriteDebugXmlFinish();
            RemoveCounter(_readStreamCounterText);
        }
Beispiel #13
0
        /// <summary>
        /// Creates a colour table directly from the distinct colours in the
        /// supplied image(s).
        /// </summary>
        private void CreateDirectColourTable()
        {
            //AddCounter( buildColourTableCounterText,
            // _distinctColours.Values.Count );
            _colourTable = new ColourTable();
            int distinctColourIndex = 0;

            foreach (Color c in _distinctColours.Values)
            {
                //MyProgressCounters[buildColourTableCounterText].Value
                //= distinctColourIndex;
                _colourTable.Add(c);
                distinctColourIndex++;
            }
            _colourTable.Pad();
            //RemoveCounter( buildColourTableCounterText );
        }
Beispiel #14
0
        public void IndexerTest()
        {
            ReportStart();
            Stream s = PrepareStream();

            _table = new ColourTable(s, 4);

            Random r = new Random();

            for (int i = 0; i < _table.Length; i++)
            {
                Color c = Color.FromArgb(r.Next());
                _table[i] = c;
                Assert.AreEqual(c, _table[i], "Index " + i);
                Assert.AreEqual(c, _table.Colours[i], "Index " + i);
            }
            ReportEnd();
        }
        /// <summary>
        /// Converts the supplied image to a collection of pixel indices using
        /// the supplied colour table.
        /// Only used when the QuantizerType is set to UseSuppliedPalette
        /// </summary>
        /// <param name="act">The active colour table</param>
        /// <param name="image">The image</param>
        /// <returns></returns>
        private IndexedPixels MakeIndexedPixels(ColourTable act, Image image)
        {
            //AddCounter( counterText, pixelCount );
            Bitmap        bitmap = (Bitmap)image;
            IndexedPixels ip     = new IndexedPixels();

            for (int y = 0; y < image.Height; y++)
            {
                for (int x = 0; x < image.Width; x++)
                {
                    Color c     = bitmap.GetPixel(x, y);
                    int   index = FindClosest(c, act);
                    ip.Add((byte)index);
                    //MyProgressCounters[counterText].Value = ip.Count;
                }
            }
            //RemoveCounter( counterText );
            return(ip);
        }
Beispiel #16
0
        public void IndexerGetTestIndexOutOfRange()
        {
            ReportStart();
            Stream s = PrepareStream();

            _table = new ColourTable(s, 4);
            try
            {
                Color c = _table[4];
            }
            catch (ArgumentOutOfRangeException ex)
            {
                string message = "Colour table size: 4. Index: " + 4;
                StringAssert.Contains(message, ex.Message);
                Assert.AreEqual("index", ex.ParamName);
                ReportEnd();
                throw;
            }
        }
Beispiel #17
0
        public void ConstructorStreamTestTooFewColours()
        {
            ReportStart();
            Stream s = new MemoryStream();

            try
            {
                _table = new ColourTable(s, -1);
            }
            catch (ArgumentOutOfRangeException ex)
            {
                string message
                    = "The number of colours must be between 0 and 256. "
                      + "Number supplied: -1";
                StringAssert.Contains(message, ex.Message);
                Assert.AreEqual("numberOfColours", ex.ParamName);
                ReportEnd();
                throw;
            }
        }
Beispiel #18
0
        private void ConstructorStreamTestColourTableTooShort(bool xmlDebugging)
        {
            Stream s = PrepareStream();

            // Pass larger number of colours than are actually in the stream
            _table = new ColourTable(s, 5, xmlDebugging);
            Assert.AreEqual(ErrorState.ColourTableTooShort, _table.ErrorState);
            Assert.AreEqual(5, _table.Length);
            Assert.AreEqual(Color.FromArgb(255, 0, 0, 0), _table[0]);
            Assert.AreEqual(Color.FromArgb(255, 255, 0, 0), _table[1]);
            Assert.AreEqual(Color.FromArgb(255, 0, 255, 0), _table[2]);
            Assert.AreEqual(Color.FromArgb(255, 0, 0, 255), _table[3]);
            // missing colour should be set to black by the constructor
            Assert.AreEqual(Color.FromArgb(0, 0, 0, 0), _table[4]);

            if (xmlDebugging)
            {
                Assert.AreEqual(ExpectedDebugXml, _table.DebugXml);
            }
        }
Beispiel #19
0
        public void ConstructorStreamNullLogicalScreenDescriptorTest()
        {
            MemoryStream s = CreateStream();

            // Extra stuff not included in the frame stream, to pass to the
            // constructor
            ColourTable             colourTable = WikipediaExample.GlobalColourTable;
            GraphicControlExtension ext         = WikipediaExample.GraphicControlExtension;
            LogicalScreenDescriptor lsd         = null;

            try
            {
                _frame = new GifFrame(s, lsd, colourTable, ext, null, null);
            }
            catch (ArgumentNullException ex)
            {
                Assert.AreEqual("lsd", ex.ParamName);
                throw;
            }
        }
Beispiel #20
0
        /// <summary>
        /// Creates a colour table directly from the distinct colours in the
        /// supplied image(s).
        /// </summary>
        private void CreateDirectColourTable()
        {
            string buildColourTableCounterText
                = "Creating colour table from images";

            AddCounter(buildColourTableCounterText,
                       _distinctColours.Values.Count);
            _colourTable = new ColourTable();
            int distinctColourIndex = 0;

            foreach (Color c in _distinctColours.Values)
            {
                MyProgressCounters[buildColourTableCounterText].Value
                    = distinctColourIndex;
                _colourTable.Add(c);
                distinctColourIndex++;
            }
            _colourTable.Pad();
            RemoveCounter(buildColourTableCounterText);
        }
Beispiel #21
0
        private void ConstructorStreamNoImageDataTest(bool xmlDebugging)
        {
            MemoryStream s = new MemoryStream();

            // Image descriptor
            byte[] idBytes = WikipediaExample.ImageDescriptorBytes;
            s.Write(idBytes, 0, idBytes.Length);

            // miss out the image data
//			// Table-based image data
//			byte[] imageData = WikipediaExample.ImageDataBytes;
//			s.Write( imageData, 0, imageData.Length );
            byte[] imageData = new byte[]
            {
                0x08,                 // LZW minimum code size
//				0x00, // block size = 11
//				// 11 bytes of LZW encoded data follows
//				0x00, 0x01, 0x04, 0x18, 0x28, 0x70, 0xA0, 0xC1, 0x83, 0x01, 0x01,
                0x00                 // block terminator
            };
            s.Write(imageData, 0, imageData.Length);

            s.Seek(0, SeekOrigin.Begin);

            // Extra stuff not included in the frame stream, to pass to the
            // constructor
            ColourTable             colourTable = WikipediaExample.GlobalColourTable;
            GraphicControlExtension ext         = WikipediaExample.GraphicControlExtension;
            LogicalScreenDescriptor lsd         = WikipediaExample.LogicalScreenDescriptor;

            _frame = new GifFrame(s, lsd, colourTable, ext, null, null, xmlDebugging);

            Assert.AreEqual(ErrorState.TooFewPixelsInImageData,
                            _frame.ConsolidatedState);

            if (xmlDebugging)
            {
                Assert.AreEqual(ExpectedDebugXml, _frame.DebugXml);
            }
        }
Beispiel #22
0
        private void ConstructorStreamTest(bool xmlDebugging)
        {
            Stream s = PrepareStream();

            _table = new ColourTable(s, 4, xmlDebugging);
            Assert.AreEqual(4, _table.Length);
            Assert.AreEqual(4, _table.Colours.Length);
            Assert.AreEqual(Color.FromArgb(255, 0, 0, 0), _table.Colours[0]);
            Assert.AreEqual(Color.FromArgb(255, 255, 0, 0), _table.Colours[1]);
            Assert.AreEqual(Color.FromArgb(255, 0, 255, 0), _table.Colours[2]);
            Assert.AreEqual(Color.FromArgb(255, 0, 0, 255), _table.Colours[3]);
            Assert.AreEqual(Color.FromArgb(255, 0, 0, 0), _table[0]);
            Assert.AreEqual(Color.FromArgb(255, 255, 0, 0), _table[1]);
            Assert.AreEqual(Color.FromArgb(255, 0, 255, 0), _table[2]);
            Assert.AreEqual(Color.FromArgb(255, 0, 0, 255), _table[3]);
            Assert.AreEqual(ErrorState.Ok, _table.ConsolidatedState);

            if (xmlDebugging)
            {
                Assert.AreEqual(ExpectedDebugXml, _table.DebugXml);
            }
        }
Beispiel #23
0
        /// <summary>
        /// Reads GIF image from stream
        /// </summary>
        /// <param name="inputStream">
        /// Stream containing GIF file.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// The supplied stream is null.
        /// </exception>
        private void ReadStream(Stream inputStream)
        {
            _frames = new Collection <GifFrame>();
            _applicationExtensions = new Collection <ApplicationExtension>();
            _gct = null;

            _header = new GifHeader(inputStream, XmlDebugging);
            WriteDebugXmlNode(_header.DebugXmlReader);
            if (_header.ErrorState != ErrorState.Ok)
            {
                WriteDebugXmlFinish();
                return;
            }

            _lsd = new LogicalScreenDescriptor(inputStream, XmlDebugging);
            WriteDebugXmlNode(_lsd.DebugXmlReader);
            if (TestState(ErrorState.EndOfInputStream))
            {
                WriteDebugXmlFinish();
                return;
            }

            if (_lsd.HasGlobalColourTable)
            {
                _gct = new ColourTable(inputStream,
                                       _lsd.GlobalColourTableSize,
                                       XmlDebugging);
                WriteDebugXmlNode(_gct.DebugXmlReader);
            }

            if (ConsolidatedState == ErrorState.Ok)
            {
                ReadContents(inputStream);
            }
            inputStream.Close();
            WriteDebugXmlFinish();
        }
Beispiel #24
0
        public void WriteToStreamTest()
        {
            ReportStart();
            _table = new ColourTable();
            _table.Add(Color.FromArgb(255, 255, 0, 0));                 // red
            _table.Add(Color.FromArgb(255, 0, 255, 0));                 // green
            _table.Add(Color.FromArgb(255, 0, 0, 255));                 // blue
            _table.Add(Color.FromArgb(255, 255, 255, 255));             // white

            MemoryStream s = new MemoryStream();

            _table.WriteToStream(s);
            s.Seek(0, SeekOrigin.Begin);

            ColourTable t = new ColourTable(s, 4);

            Assert.AreEqual(ErrorState.Ok, t.ConsolidatedState);
            Assert.AreEqual(_table.Colours.Length, t.Colours.Length);
            for (int i = 0; i < t.Colours.Length; i++)
            {
                Assert.AreEqual(_table[i], t[i], "Colour index " + i);
            }
            ReportEnd();
        }
Beispiel #25
0
        private static void CheckImageData(Stream s,
                                           ColourTable act,
                                           ImageDescriptor id,
                                           Bitmap expectedBitmap)
        {
            // read, decode and check image data
            // Cannot compare encoded LZW data directly as different encoders
            // will create different colour tables, so even if the bitmaps are
            // identical, the colour indices will be different
            int pixelCount           = id.Size.Width * id.Size.Height;
            TableBasedImageData tbid = new TableBasedImageData(s, pixelCount);

            Assert.AreEqual(ErrorState.Ok, tbid.ConsolidatedState);
            for (int y = 0; y < id.Size.Height; y++)
            {
                for (int x = 0; x < id.Size.Width; x++)
                {
                    int i = (y * id.Size.Width) + x;
                    Assert.AreEqual(expectedBitmap.GetPixel(x, y),
                                    act[tbid.Pixels[i]],
                                    "X: " + x + ", Y: " + y);
                }
            }
        }
        public Bitmap Render()
        {
            var inputList = new List<PointD>(PixelHeight*PixelWidth);
            var xAxisValues = Maths.DoubleRange(PixelWidth, TopLeftCorner.X, TopLeftCorner.X + ViewWidth);
            var yAxisValues = Maths.DoubleRange(PixelHeight, TopLeftCorner.Y, TopLeftCorner.Y + ViewHeight);

            for (int x = 0; x < PixelWidth; x++)
            {
                for (int y = 0; y < PixelHeight; y++)
                {
                    inputList.Add(new PointD(xAxisValues[x], yAxisValues[y]));
                }
            }

            var output = Model.Iterate(inputList, MaxIterations);

            var colourTable = new ColourTable(1024){
                StartColor = Color.Black,
                EndColor = Color.FromArgb(255, 255, 0, 255)
            };
            colourTable.SetupColourTable();
            var bitmap = new Bitmap(PixelWidth, PixelHeight);
            bitmapRenderer.Render(bitmap, output, colourTable, MaxIterations);

            return bitmap;
        }
Beispiel #27
0
        private void RenderImage()
        {
            try {
                statusLabel.Text = "Status: Rendering";
                if (Convert.ToBoolean(pixelStepTextBox.Text.Equals("")) ||
                    Convert.ToBoolean(pixelStepTextBox.Text.Equals("0")) ||
                    Convert.ToBoolean(iterationCountTextBox.Text.Equals("")) ||
                    Convert.ToBoolean(yMinCheckBox.Text.Equals("")) ||
                    Convert.ToBoolean(yMaxCheckBox.Text.Equals("")) ||
                    Convert.ToBoolean(xMinCheckBox.Text.Equals("")) ||
                    Convert.ToBoolean(xMaxCheckBox.Text.Equals("")))
                {
                    // Choose default parameters and warn the user if the settings are all empty.
                    pixelStepTextBox.Text      = "1";
                    iterationCountTextBox.Text = "85";
                    yMinCheckBox.Text          = "-1";
                    yMaxCheckBox.Text          = "1";
                    xMinCheckBox.Text          = "-2";
                    xMaxCheckBox.Text          = "1";
                    MessageBox.Show("Invalid fields detected. Using default values.");
                    statusLabel.Text = "Status: Error";
                    return;
                }
                else
                {
                    // Show zoom and undo controls.
                    zoomCheckbox.Show();
                    undoButton.Show();
                    undoNum++;
                }

                // Mandelbrot iteration count.
                kMax       = Convert.ToInt32(iterationCountTextBox.Text);
                numColours = kMax;

                // If colourTable is not yet created or kMax has changed, create colourTable.
                if ((colourTable == null) || (kMax != colourTable.kMax) || (numColours != colourTable.nColour))
                {
                    colourTable = new ColourTable(numColours, kMax);
                }

                // Get the x, y range (mathematical coordinates) to plot.
                yMin = Convert.ToDouble(yMinCheckBox.Text);
                yMax = Convert.ToDouble(yMaxCheckBox.Text);
                xMin = Convert.ToDouble(xMinCheckBox.Text);
                xMax = Convert.ToDouble(xMaxCheckBox.Text);

                // Zoom scale.
                zoomScale = Convert.ToInt16(zoomTextBox.Text);

                // Clear any existing graphics content.
                g.Clear(Color.White);

                // Initialise working variables.
                int    height = (int)g.VisibleClipBounds.Size.Height;
                int    kLast  = -1;
                double modulusSquared;
                Color  color;
                Color  colorLast = Color.Red;

                // Get screen boundary (lower left & upper right). This is
                // used when calculating the pixel scaling factors.
                ComplexPoint screenBottomLeft = new ComplexPoint(xMin, yMin);
                ComplexPoint screenTopRight   = new ComplexPoint(xMax, yMax);

                // Create pixel manager. This sets up the scaling factors used when
                // converting from mathemathical to screen (pixel units) using the
                myPixelManager = new ScreenPixelManage(g, screenBottomLeft, screenTopRight);

                // The pixel step size defines the increment in screen pixels for each point
                // at which the Mandelbrot calcualtion will be done. e.g. a Step of 5 means
                // that the calcualtion will be done a 5-pixel increments. The X & Y increments
                // are the same.
                //
                // This increment is converted to mathematical coordinates.
                int          xyPixelStep = Convert.ToInt16(pixelStepTextBox.Text);
                ComplexPoint pixelStep   = new ComplexPoint(xyPixelStep, xyPixelStep);
                ComplexPoint xyStep      = myPixelManager.GetDeltaMathsCoord(pixelStep);

                // Start stopwatch - used to measure performance improvements
                // (from improving the efficiency of the maths implementation).
                Stopwatch sw = new Stopwatch();
                sw.Start();

                // Main loop, nested over Y (outer) and X (inner) values.
                int lineNumber = 0;
                int yPix       = myBitmap.Height - 1;
                for (double y = yMin; y < yMax; y += xyStep.img)
                {
                    int xPix = 0;
                    for (double x = xMin; x < xMax; x += xyStep.real)
                    {
                        // Create complex point C = x + i*y.
                        ComplexPoint c = new ComplexPoint(x, y);

                        // Initialise complex value Zk.
                        ComplexPoint zk = new ComplexPoint(0, 0);

                        // Do the main Mandelbrot calculation. Iterate until the equation
                        // converges or the maximum number of iterations is reached.
                        int k = 0;
                        do
                        {
                            zk             = zk.DoCmplxSqPlusConst(c);
                            modulusSquared = zk.DoMoulusSq();
                            k++;
                        } while ((modulusSquared <= 4.0) && (k < kMax));

                        if (k < kMax)
                        {
                            // Max number of iterations was not reached. This means that the
                            // equation converged. Now assign a colour to the current pixel that
                            // depends on the number of iterations, k, that were done.

                            if (k == kLast)
                            {
                                // If the iteration count is the same as the last count, re-use the
                                // last pen. This avoids re-calculating colour factors which is
                                // computationally intensive. We benefit from this often because
                                // adjacent pixels are often the same colour, especially in large parts
                                // of the Mandelbrot set that are away from the areas of detail.
                                color = colorLast;
                            }
                            else
                            {
                                // Calculate coluor scaling, from k. We don't use complicated/fancy colour
                                // lookup tables. Instead, the following simple conversion works well:
                                //
                                // hue = (k/kMax)**0.25 where the constant 0.25 can be changed if wanted.
                                // This formula stretches colours allowing more to be assigned at higher values
                                // of k, which brings out detail in the Mandelbrot images.

                                // The following is a full colour calculation, replaced now with colour table.
                                // Uncomment and disable the colour table if wanted. The colour table works
                                // well but supports fewer colours than full calculation of hue and colour
                                // using double-precision arithmetic.
                                //double colourIndex = ((double)k) / kMax;
                                //double hue = Math.Pow(colourIndex, 0.25);

                                // Colour table lookup.
                                // Convert the hue value to a useable colour and assign to current pen.
                                // The saturation and lightness are hard-coded at 0.9 and 0.6 respectively,
                                // which work well.
                                color     = colourTable.GetColour(k);
                                colorLast = color;
                            }

                            // Draw single pixel
                            if (xyPixelStep == 1)
                            {
                                // Pixel step is 1, set a single pixel.
                                if ((xPix < myBitmap.Width) && (yPix >= 0))
                                {
                                    myBitmap.SetPixel(xPix, yPix, color);
                                }
                            }
                            else
                            {
                                // Pixel step is > 1, set a square of pixels.
                                for (int pX = 0; pX < xyPixelStep; pX++)
                                {
                                    for (int pY = 0; pY < xyPixelStep; pY++)
                                    {
                                        if (((xPix + pX) < myBitmap.Width) && ((yPix - pY) >= 0))
                                        {
                                            myBitmap.SetPixel(xPix + pX, yPix - pY, color);
                                        }
                                    }
                                }
                            }
                        }
                        xPix += xyPixelStep;
                    }
                    yPix -= xyPixelStep;
                    lineNumber++;
                    if ((lineNumber % 120) == 0)
                    {
                        Refresh();
                    }
                }
                // Finished rendering. Stop the stopwatch and show the elapsed time.
                sw.Stop();
                Refresh();
                stopwatchLabel.Text = Convert.ToString(sw.Elapsed.TotalSeconds);
                statusLabel.Text    = "Status: Render complete";

                // Save current settings to undo file.
                StreamWriter writer = new StreamWriter(@"C:\Users\" + userName + "\\mandelbrot_config\\Undo\\undo" + undoNum + ".txt");
                writer.Write(pixelStepTextBox.Text + Environment.NewLine + iterationCountTextBox.Text + Environment.NewLine + yMinCheckBox.Text + Environment.NewLine + yMaxCheckBox.Text + Environment.NewLine + xMinCheckBox.Text + Environment.NewLine + xMaxCheckBox.Text);
                writer.Close();
                writer.Dispose();
            } catch (Exception e2) {
                MessageBox.Show("Exception Trapped: " + e2.Message, "Error");
                statusLabel.Text = "Status: Error";
            }
        }
Beispiel #28
0
        public void WikipediaExampleTest()
        {
            ReportStart();
            _e = new AnimatedGifEncoder();
            GifFrame frame = new GifFrame(WikipediaExample.ExpectedBitmap);

            frame.Delay = WikipediaExample.DelayTime;
            _e.AddFrame(frame);

            // TODO: some way of creating/testing a UseLocal version of WikipediaExample
            string fileName = "WikipediaExampleUseGlobal.gif";

            _e.WriteToFile(fileName);
            Stream s = File.OpenRead(fileName);

            int code;

            // check GIF header
            GifHeader gh = new GifHeader(s);

            Assert.AreEqual(ErrorState.Ok, gh.ConsolidatedState);

            // check logical screen descriptor
            LogicalScreenDescriptor lsd = new LogicalScreenDescriptor(s);

            Assert.AreEqual(ErrorState.Ok, lsd.ConsolidatedState);
            WikipediaExample.CheckLogicalScreenDescriptor(lsd);

            // read global colour table
            ColourTable gct
                = new ColourTable(s, WikipediaExample.GlobalColourTableSize);

            Assert.AreEqual(ErrorState.Ok, gct.ConsolidatedState);
            // cannot compare global colour table as different encoders will
            // produce difference colour tables.
//			WikipediaExample.CheckGlobalColourTable( gct );

            // check for extension introducer
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeExtensionIntroducer, code);

            // check for app extension label
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeApplicationExtensionLabel, code);

            // check netscape extension
            ApplicationExtension ae = new ApplicationExtension(s);

            Assert.AreEqual(ErrorState.Ok, ae.ConsolidatedState);
            NetscapeExtension ne = new NetscapeExtension(ae);

            Assert.AreEqual(ErrorState.Ok, ne.ConsolidatedState);
            Assert.AreEqual(0, ne.LoopCount);

            // check for extension introducer
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeExtensionIntroducer, code);

            // check for gce label
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeGraphicControlLabel, code);

            // check graphic control extension
            GraphicControlExtension gce = new GraphicControlExtension(s);

            Assert.AreEqual(ErrorState.Ok, gce.ConsolidatedState);
            WikipediaExample.CheckGraphicControlExtension(gce);

            // check for image separator
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeImageSeparator, code);

            // check for image descriptor
            ImageDescriptor id = new ImageDescriptor(s);

            Assert.AreEqual(ErrorState.Ok, id.ConsolidatedState);
            WikipediaExample.CheckImageDescriptor(id);

            // read, decode and check image data
            // Cannot compare encoded LZW data directly as different encoders
            // will create different colour tables, so even if the bitmaps are
            // identical, the colour indices will be different
            int pixelCount = WikipediaExample.FrameSize.Width
                             * WikipediaExample.FrameSize.Height;
            TableBasedImageData tbid = new TableBasedImageData(s, pixelCount);

            for (int y = 0; y < WikipediaExample.LogicalScreenSize.Height; y++)
            {
                for (int x = 0; x < WikipediaExample.LogicalScreenSize.Width; x++)
                {
                    int i = (y * WikipediaExample.LogicalScreenSize.Width) + x;
                    Assert.AreEqual(WikipediaExample.ExpectedBitmap.GetPixel(x, y),
                                    gct[tbid.Pixels[i]],
                                    "X: " + x + ", Y: " + y);
                }
            }

            // Check for block terminator after image data
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(0x00, code);

            // check for GIF trailer
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeTrailer, code);

            // check we're at the end of the stream
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(-1, code);
            s.Close();

            _d = new GifDecoder(fileName);
            _d.Decode();
            Assert.AreEqual(ErrorState.Ok, _d.ConsolidatedState);
            BitmapAssert.AreEqual(WikipediaExample.ExpectedBitmap,
                                  (Bitmap)_d.Frames[0].TheImage,
                                  "");
            ReportEnd();
        }
Beispiel #29
0
        /// <summary>
        /// Tests the AnimatedGifEncoder and the encoded GIF file it produces
        /// using the supplied parameters as property values.
        /// </summary>
        private void TestAnimatedGifEncoder(ColourTableStrategy strategy,
                                            int colourQuality,
                                            Size logicalScreenSize)
        {
            _e = new AnimatedGifEncoder();

            // Check default properties set by constructor.
            Assert.AreEqual(ColourTableStrategy.UseGlobal,
                            _e.ColourTableStrategy,
                            "Colour table strategy set by constructor");
            Assert.AreEqual(10,
                            _e.SamplingFactor,
                            "Colour quantization quality set by constructor");
            Assert.AreEqual(Size.Empty,
                            _e.LogicalScreenSize,
                            "Logical screen size set by constructor");

            _e.ColourTableStrategy = strategy;
            _e.SamplingFactor      = colourQuality;
            _e.LogicalScreenSize   = logicalScreenSize;

            // Check property set/gets
            Assert.AreEqual(strategy,
                            _e.ColourTableStrategy,
                            "Colour table strategy property set/get");
            Assert.AreEqual(colourQuality,
                            _e.SamplingFactor,
                            "Colour quantization quality property set/get");
            Assert.AreEqual(logicalScreenSize,
                            _e.LogicalScreenSize,
                            "Logical screen size property get/set");

            foreach (GifFrame thisFrame in _frames)
            {
                _e.AddFrame(thisFrame);
            }

            StackTrace t = new StackTrace();
            StackFrame f = t.GetFrame(1);
            string     fileName
                = "Checks." + this.GetType().Name
                  + "." + f.GetMethod().Name + ".gif";

            _e.WriteToFile(fileName);

            Stream s = File.OpenRead(fileName);

            // global info
            CheckGifHeader(s);
            bool shouldHaveGlobalColourTable
                = (strategy == ColourTableStrategy.UseGlobal);
            LogicalScreenDescriptor lsd
                = CheckLogicalScreenDescriptor(s, shouldHaveGlobalColourTable);

            // Only check the global colour table if there should be one
            ColourTable gct = null;

            if (shouldHaveGlobalColourTable)
            {
                gct = CheckColourTable(s, lsd.GlobalColourTableSize);
            }

            CheckExtensionIntroducer(s);
            CheckAppExtensionLabel(s);
            CheckNetscapeExtension(s, 0);

            CheckFrame(s, gct, Bitmap1());
            CheckFrame(s, gct, Bitmap2());

            // end of image data
            CheckGifTrailer(s);
            CheckEndOfStream(s);
            s.Close();

            // Check the file using the decoder
            _d = new GifDecoder(fileName);
            _d.Decode();
            Assert.AreEqual(ErrorState.Ok,
                            _d.ConsolidatedState,
                            "Decoder consolidated state");
            Assert.AreEqual(2, _d.Frames.Count, "Decoder frame count");
            Assert.AreEqual(shouldHaveGlobalColourTable,
                            _d.LogicalScreenDescriptor.HasGlobalColourTable,
                            "Should have global colour table");
            Assert.AreEqual(logicalScreenSize,
                            _d.LogicalScreenDescriptor.LogicalScreenSize,
                            "Decoder logical screen size");

            BitmapAssert.AreEqual(Bitmap1(),
                                  (Bitmap)_d.Frames[0].TheImage,
                                  "frame 0");
            BitmapAssert.AreEqual(Bitmap2(),
                                  (Bitmap)_d.Frames[1].TheImage,
                                  "frame 1");

            bool shouldHaveLocalColourTable = !shouldHaveGlobalColourTable;

            Assert.AreEqual(shouldHaveLocalColourTable,
                            _d.Frames[0].ImageDescriptor.HasLocalColourTable,
                            "Frame 0 has local colour table");
            Assert.AreEqual(shouldHaveLocalColourTable,
                            _d.Frames[1].ImageDescriptor.HasLocalColourTable,
                            "Frame 0 has local colour table");
        }
        private void WriteFrame(Stream outputStream)
        {
            GifFrame    thisFrame = _frames[_encodingFrame];
            Image       thisImage = thisFrame.TheImage;
            ColourTable act       = SetActiveColourTable();
            int         transparentColourIndex;

            if (_transparent == Color.Empty)
            {
                transparentColourIndex = 0;
            }
            else
            {
                // TESTME: WriteFrame - _transparent != Color.Empty
                transparentColourIndex = FindClosest(_transparent, act);
            }
            WriteGraphicCtrlExt(thisFrame,
                                transparentColourIndex,
                                outputStream);
            ColourTable lct;

            if (_strategy == ColourTableStrategy.UseLocal)
            {
                lct = act;
            }
            else
            {
                lct = null;
            }
            WriteImageDescriptor(thisImage.Size,
                                 thisFrame.Position,
                                 lct,
                                 outputStream);

            // Write a local colour table if the strategy is to do so
            if (_strategy == ColourTableStrategy.UseLocal)
            {
                act.WriteToStream(outputStream);
                IndexedPixels ip;
                if (_quantizerType == QuantizerType.UseSuppliedPalette)
                {
                    ip = MakeIndexedPixels(act, thisImage);
                }
                else
                {
                    ip = _pixelAnalysis.IndexedPixels;
                }
                WritePixels(ip, outputStream);
            }
            else             // global colour table
            {
                IndexedPixels ip;
                if (_quantizerType == QuantizerType.UseSuppliedPalette)
                {
                    ip = MakeIndexedPixels(act, thisImage);
                }
                else
                {
                    ip = _pixelAnalysis.IndexedPixelsCollection[_encodingFrame];
                }
                WritePixels(ip, outputStream);
            }
        }
        /// <summary>
        /// Writes a Logical Screen Descriptor to the supplied stream.
        /// Also writes a global colour table if required.
        /// </summary>
        /// <param name="outputStream">
        /// The stream to write to.
        /// </param>
        private void WriteLogicalScreenDescriptor(Stream outputStream)
        {
            bool hasGlobalColourTable      = _strategy == ColourTableStrategy.UseGlobal;
            int  colourResolution          = 7;     // TODO: parameterise colourResolution?
            bool globalColourTableIsSorted = false; // Sorting of colour tables is not currently supported
            int  backgroundColorIndex      = 0;     // TODO: parameterise backgroundColourIndex?
            int  pixelAspectRatio          = 0;     // TODO: parameterise pixelAspectRatio?

            if (_strategy == ColourTableStrategy.UseGlobal)
            {
                if (_quantizerType == QuantizerType.UseSuppliedPalette)
                {
                    // use supplied palette
                    _globalColourTable = new ColourTable();
                    //AddCounter( buildColourTableCounterText,
                    //   _palette.Count );
                    int paletteIndex = 0;
                    foreach (Color c in _palette)
                    {
                        _globalColourTable.Add(c);
                        //MyProgressCounters[buildColourTableCounterText].Value
                        //= paletteIndex;
                        paletteIndex++;
                    }
                    _globalColourTable.Pad();
                    //RemoveCounter( buildColourTableCounterText );
                }
                else
                {
                    // Analyse the pixels in all the images to build the
                    // global colour table.
                    Collection <Image> images = new Collection <Image>();
                    foreach (GifFrame thisFrame in _frames)
                    {
                        Image thisImage = thisFrame.TheImage;
                        images.Add(thisImage);
                    }
                    _pixelAnalysis = new PixelAnalysis(images);
                    _pixelAnalysis.ColourQuality = _quality;
                    _pixelAnalysis.Analyse();
                    _globalColourTable = _pixelAnalysis.ColourTable;
                }
                LogicalScreenDescriptor lsd =
                    new LogicalScreenDescriptor(_logicalScreenSize,
                                                hasGlobalColourTable,
                                                colourResolution,
                                                globalColourTableIsSorted,
                                                _globalColourTable.SizeBits,
                                                backgroundColorIndex,
                                                pixelAspectRatio);
                lsd.WriteToStream(outputStream);
                _globalColourTable.WriteToStream(outputStream);
            }
            else
            {
                LogicalScreenDescriptor lsd =
                    new LogicalScreenDescriptor(_logicalScreenSize,
                                                hasGlobalColourTable,
                                                colourResolution,
                                                globalColourTableIsSorted,
                                                7,
                                                backgroundColorIndex,
                                                pixelAspectRatio);
                lsd.WriteToStream(outputStream);
            }
        }