public void Serialize(Stream stream, ColourCollection palette, AdobePhotoshopColourSwatchFileVersion version)
 {
     this.Serialize(stream, palette, version, AdobePhotoshopColourSwatchColourSpace.RGB);
 }
 /// <summary>
 /// Serializes the specified <see cref="ColourCollection" /> and writes the palette to a file using the specified <see cref="Stream" />.
 /// </summary>
 /// <param name="stream">The <see cref="Stream" /> used to write the palette.</param>
 /// <param name="palette">The <see cref="ColourCollection" /> to serialize.</param>
 public override void Serialise(Stream stream, ColourCollection palette)
 {
     this.Serialize(stream, palette, AdobePhotoshopColourSwatchColourSpace.RGB);
 }
 public void Serialize(Stream stream, ColourCollection palette, AdobePhotoshopColourSwatchColourSpace colourSpace)
 {
     this.Serialize(stream, palette, AdobePhotoshopColourSwatchFileVersion.VERSION2, colourSpace);
 }
 /// <summary>
 /// Serializes the specified <see cref="ColourCollection" /> and writes the palette to a file using the specified Stream.
 /// </summary>
 /// <param name="stream">The <see cref="Stream" /> used to write the palette.</param>
 /// <param name="palette">The <see cref="ColourCollection" /> to serialize.</param>
 void IPaletteSerialiser.Serialise(Stream stream, ColourCollection palette)
 {
     this.Serialise(stream, palette);
 }
 /// <summary>
 /// Serializes the specified <see cref="ColourCollection" /> and writes the palette to a file using the specified <see cref="Stream"/>.
 /// </summary>
 /// <param name="stream">The <see cref="Stream" /> used to write the palette.</param>
 /// <param name="palette">The <see cref="ColourCollection" /> to serialize.</param>
 public abstract void Serialise(Stream stream, ColourCollection palette);
        protected virtual void WritePalette(Stream stream, ColourCollection palette, AdobePhotoshopColourSwatchFileVersion version, AdobePhotoshopColourSwatchColourSpace colorSpace)
        {
            int swatchIndex;

            this.WriteInt16(stream, (short)version);
            this.WriteInt16(stream, (short)palette.Count);

            swatchIndex = 0;

            foreach (Color colour in palette)
            {
                short value1;
                short value2;
                short value3;
                short value4;

                swatchIndex++;

                switch (colorSpace)
                {
                case AdobePhotoshopColourSwatchColourSpace.RGB:
                    value1 = (short)(colour.R * 256);
                    value2 = (short)(colour.G * 256);
                    value3 = (short)(colour.B * 256);
                    value4 = 0;
                    break;

                case AdobePhotoshopColourSwatchColourSpace.HSB:
                    value1 = (short)(colour.GetHue() * 182.04);
                    value2 = (short)(colour.GetSaturation() * 655.35);
                    value3 = (short)(colour.GetBrightness() * 655.35);
                    value4 = 0;
                    break;

                case AdobePhotoshopColourSwatchColourSpace.GRAYSCALE:
                    if (colour.R == colour.G && colour.R == colour.B)
                    {
                        // already grayscale
                        value1 = (short)(colour.R * 39.0625);
                    }
                    else
                    {
                        // color is not grayscale, convert
                        value1 = (short)((colour.R + colour.G + colour.B) / 3.0 * 39.0625);
                    }
                    value2 = 0;
                    value3 = 0;
                    value4 = 0;
                    break;

                default:
                    throw new InvalidOperationException("Color space not supported.");
                }

                this.WriteInt16(stream, (short)colorSpace);
                this.WriteInt16(stream, value1);
                this.WriteInt16(stream, value2);
                this.WriteInt16(stream, value3);
                this.WriteInt16(stream, value4);

                if (version == AdobePhotoshopColourSwatchFileVersion.VERSION2)
                {
                    string name;

#if USENAMEHACK
                    name = palette.GetName(swatchIndex - 1);
                    if (string.IsNullOrEmpty(name))
                    {
                        name = string.Format("Swatch {0}", swatchIndex);
                    }
#else
                    name = colour.IsNamedColor ? colour.Name : string.Format("Swatch {0}", swatchIndex);
#endif

                    this.WriteInt32(stream, name.Length);
                    this.WriteString(stream, name);
                }
            }
        }
        protected virtual ColourCollection ReadPalette(Stream stream, AdobePhotoshopColourSwatchFileVersion version)
        {
            int colourCount;
            ColourCollection results;

            results = new ColourCollection();

            // read the number of colors, which also occupies two bytes
            colourCount = this.ReadInt16(stream);

            for (int i = 0; i < colourCount; i++)
            {
                AdobePhotoshopColourSwatchColourSpace colorSpace;
                int    value1;
                int    value2;
                int    value3;
                string name;

                // again, two bytes for the color space
                colorSpace = (AdobePhotoshopColourSwatchColourSpace)this.ReadInt16(stream);

                value1 = this.ReadInt16(stream);
                value2 = this.ReadInt16(stream);
                value3 = this.ReadInt16(stream);
                this.ReadInt16(stream); // only CMYK supports this field. As we can't handle CMYK colors, we read the value to advance the stream but don't do anything with it

                if (version == AdobePhotoshopColourSwatchFileVersion.VERSION2)
                {
                    int length;

                    // need to read the name even though currently our colour collection doesn't support names
                    length = this.ReadInt32(stream);
                    name   = this.ReadString(stream, length);
                }
                else
                {
                    name = string.Empty;
                }

                switch (colorSpace)
                {
                case AdobePhotoshopColourSwatchColourSpace.RGB:
                    int red;
                    int green;
                    int blue;

                    // RGB.
                    // The first three values in the color data are red , green , and blue . They are full unsigned
                    //  16-bit values as in Apple's RGBColor data structure. Pure red = 65535, 0, 0.

                    red   = value1 / 256;
                    green = value2 / 256;
                    blue  = value3 / 256;

                    results.Add(Color.FromArgb(red, green, blue));
                    break;

                case AdobePhotoshopColourSwatchColourSpace.HSB:
                    double hue;
                    double saturation;
                    double brightness;

                    // HSB.
                    // The first three values in the color data are hue , saturation , and brightness . They are full
                    // unsigned 16-bit values as in Apple's HSVColor data structure. Pure red = 0,65535, 65535.

                    hue        = value1 / 182.04;
                    saturation = value2 / 655.35;
                    brightness = value3 / 655.35;

                    results.Add(new HSLColour(hue, saturation, brightness).ToRgbColour());
                    break;

                case AdobePhotoshopColourSwatchColourSpace.GRAYSCALE:

                    int gray;

                    // Grayscale.
                    // The first value in the color data is the gray value, from 0...10000.
                    gray = (int)(value1 / 39.0625);

                    results.Add(Color.FromArgb(gray, gray, gray));
                    break;

                default:
                    throw new InvalidDataException(string.Format("Color space '{0}' not supported.", colorSpace));
                }

#if USENAMEHACK
                results.SetName(i, name);
#endif
            }

            return(results);
        }
Example #8
0
        /// <summary>
        /// Deserializes the <see cref="ColourCollection" /> contained by the specified <see cref="Stream" />.
        /// </summary>
        /// <param name="stream">The <see cref="Stream" /> that contains the palette to deserialize.</param>
        /// <returns>The <see cref="ColourCollection" /> being deserialized.</returns>
        public override ColourCollection Deserialise(Stream stream)
        {
            byte[]           buffer;
            string           header;
            ColourCollection results;

            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            results = new ColourCollection();

            // read the FORM header that identifies the document as an IFF file
            buffer = new byte[4];
            stream.Read(buffer, 0, buffer.Length);
            if (Encoding.ASCII.GetString(buffer) != "FORM")
            {
                throw new InvalidDataException("Form header not found.");
            }

            // the next value is the size of all the data in the FORM chunk
            // We don't actually need this value, but we have to read it
            // regardless to advance the stream
            this.ReadInt32(stream);

            // read either the PBM or ILBM header that identifies this document as an image file
            stream.Read(buffer, 0, buffer.Length);
            header = Encoding.ASCII.GetString(buffer);
            if (header != "PBM " && header != "ILBM")
            {
                throw new InvalidDataException("Bitmap header not found.");
            }

            while (stream.Read(buffer, 0, buffer.Length) == buffer.Length)
            {
                int chunkLength;

                chunkLength = this.ReadInt32(stream);

                if (Encoding.ASCII.GetString(buffer) != "CMAP")
                {
                    // some other LBM chunk, skip it
                    if (stream.CanSeek)
                    {
                        stream.Seek(chunkLength, SeekOrigin.Current);
                    }
                    else
                    {
                        for (int i = 0; i < chunkLength; i++)
                        {
                            stream.ReadByte();
                        }
                    }
                }
                else
                {
                    // color map chunk!
                    for (int i = 0; i < chunkLength / 3; i++)
                    {
                        int r;
                        int g;
                        int b;

                        r = stream.ReadByte();
                        g = stream.ReadByte();
                        b = stream.ReadByte();

                        results.Add(Color.FromArgb(r, g, b));
                    }

                    // all done so stop reading the rest of the file
                    break;
                }

                // chunks always contain an even number of bytes even if the recorded length is odd
                // if the length is odd, then there's a padding byte in the file - just read and discard
                if (chunkLength % 2 != 0)
                {
                    stream.ReadByte();
                }
            }

            return(results);
        }