예제 #1
0
        public Effect(BinaryReverseReader reader)
        {
            this.Name    = new string(reader.ReadChars(4));
            this.Size    = reader.ReadUInt32();
            this.Version = reader.ReadUInt32();

            this.loadedData = reader.ReadBytes((int)this.Size - 4);           //4 bytes for version
        }
예제 #2
0
        public Effect(BinaryReverseReader reader)
        {
            this.Name = new string(reader.ReadChars(4));
            this.Size = reader.ReadUInt32();
            this.Version = reader.ReadUInt32();

            this.loadedData = reader.ReadBytes((int)this.Size-4); //4 bytes for version
        }
예제 #3
0
        public AlphaChannels(ImageResource imgRes)
            : base(imgRes)
        {
            // 文档 四 - 2 ID 1006
            BinaryReverseReader dataReader = imgRes.DataReader;

            while (dataReader.BaseStream.Length - dataReader.BaseStream.Position > 0L)
            {
                byte length = dataReader.ReadByte();

                dataReader.ReadChars(length);
            }

            dataReader.Close();
        }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AlphaChannels" /> class.
        /// </summary>
        /// <param name="imgRes">The image resource.</param>
        public AlphaChannels(ImageResource imgRes)
            : base(imgRes)
        {
            BinaryReverseReader dataReader = imgRes.DataReader;

            while (dataReader.BaseStream.Length - dataReader.BaseStream.Position > 0L)
            {
                // read the length of the string
                byte length = dataReader.ReadByte();

                // read the string
                dataReader.ReadChars(length);
            }

            dataReader.Close();
        }
예제 #5
0
 public TdTaParseException(string message, BinaryReverseReader r)
     : base(message + "\nMore data:" + new string(r.ReadChars((int)Math.Max(100, r.BytesToEnd))))
 {
 }
예제 #6
0
        public Layer(BinaryReverseReader reader, Document document)
        {
            this._document = document;

            this._rect = new ERectangle();
            this._rect.Y = reader.ReadInt32();
            this._rect.X = reader.ReadInt32();
            this._rect.Height = reader.ReadInt32() - this._rect.Y;
            this._rect.Width = reader.ReadInt32() - this._rect.X;

            this.NumChannels = reader.ReadUInt16();
            this._channels = new Dictionary<int, Channel>();
            for (int channelNum = 0; channelNum < this.NumChannels; channelNum++)
            {
                Channel ch = new Channel(reader, this);
                this._channels.Add(ch.Usage, ch);
            }

            string sHeader = new string(reader.ReadChars(4));
            if (sHeader != "8BIM")
                throw(new Exception("Layer Channelheader error!"));

            this.BlendKey = new string(reader.ReadChars(4));
            int nBlend = -1;
            try
            {
                nBlend = (int)Enum.Parse(typeof(_blendKeysPsd), this.BlendKey);
            }
            catch { }
            if (nBlend >= 0)
            {
                BlendKeys key = (BlendKeys)nBlend;
                this.BlendKey = Enum.GetName(typeof(BlendKeys), key);
            }

            this.Opacity = reader.ReadByte(); //(byte)(255 - (int)reader.ReadByte());
            //paLayerInfo[#Opacity] = 256 - m_oReader.readUC() --256-ScaleCharToQuantum(ReadBlobByte(image))
            this.Clipping = reader.ReadByte();
            this.Flags = reader.ReadByte();

            reader.ReadByte(); //padding

            uint nSize = reader.ReadUInt32();
            long nChannelEndPos = reader.BaseStream.Position + (long)nSize;
            if (nSize > 0)
            {
                uint nLength;
                //uint nCombinedlength = 0;

                this._mask = new Mask(reader, this);
                if (this._mask.Rectangle == null)
                    this._mask = null;

                //reader.BaseStream.Position+=nLength-16;

                //nCombinedlength+= nLength + 4;

                //blending ranges
                nLength = reader.ReadUInt32();
                for (uint i = 0; i < nLength/8; i++)
                {
                    uint color1 = reader.ReadUInt32();
                    uint color2 = reader.ReadUInt32();
                }
                //nCombinedlength+= nLength + 4;

                //Name
                nLength = (uint)reader.ReadByte();
                reader.BaseStream.Position-=1;
                this.Name = reader.ReadPascalString();
                //nCombinedlength+= nLength + 4;

                #region Adjustment etc layers
                //TODO: there's probably a 2-byte padding here
                sHeader = new string(reader.ReadChars(4));
                if (sHeader != "8BIM")
                {
                    reader.BaseStream.Position-=2;
                    sHeader = new string(reader.ReadChars(4));
                }
                reader.BaseStream.Position-=4;

                do
                {
                    try
                    {
                        this.ReadPSDChannelTag(reader);
                    }
                    catch
                    {
                        //dunno what the last bytes are for, just skip them:
                        reader.BaseStream.Position = nChannelEndPos;
                    }
                }
                while(reader.BaseStream.Position < nChannelEndPos);

                #endregion
            }
        }
예제 #7
0
        private void ReadPSDChannelTag(BinaryReverseReader reader)
        {
            string sHeader = new string(reader.ReadChars(4));
            if (sHeader != "8BIM")
            {
                reader.BaseStream.Position-=4; //back it up before throwing exception
                throw(new Exception("Effect header incorrect"));
            }

            string sKey = new string(reader.ReadChars(4));
            uint nLength = reader.ReadUInt32();
            long nPosStart = reader.BaseStream.Position;

            switch (sKey)
            {
                case "lyid":
                    this.LayerID = (int)reader.ReadUInt32();
                    break;

                case "fxrp":
                    this.ReferencePoint = new EPointF();
                    this.ReferencePoint.X = reader.ReadPSD8BitSingle();
                    this.ReferencePoint.Y = reader.ReadPSD8BitSingle();
                    break;

                case "clbl":
                    //blend clipping
                    this.BlendClipping = reader.ReadBoolean();
                    reader.BaseStream.Position+=3; //padding
                    break;

                case "infx":
                    //blend interior elements
                    this.Blend = reader.ReadBoolean();
                    reader.BaseStream.Position+=3; //padding
                    break;

                case "knko":
                    //Knockout setting
                    this.Knockout = reader.ReadBoolean();
                    reader.BaseStream.Position+=3; //padding
                    break;

                case "lspf":
                    //Protected settings
                    //TODO:
                    reader.ReadBytes(4); //nLength?
                    //bits 0-2 = Transparency, composite and position
                    break;

                case "lclr":
                    //Sheet Color setting
                    this.SheetColor = System.Drawing.Color.FromArgb(
                        reader.ReadByte(),
                        reader.ReadByte(),
                        reader.ReadByte(),
                        reader.ReadByte());
                    reader.BaseStream.Position+=2; //padding
                    break;

                case "lnsr":
                    //Layer Name Source setting
                    string sWhatIsThis = new string(reader.ReadChars((int)nLength));
                    //this.NameSourceSetting = reader.ReadUInt32();
                    break;

                case "luni":
                    //Unicode Layer name
                    uint nUnicodeLength = reader.ReadUInt32();
                    this.UnicodeName = new string(reader.ReadChars((int)nUnicodeLength*2));
                    break;

                case "lrFX":
                    //Effects Layer info
                    reader.BaseStream.Position+=2; //unused
                    ushort nNumEffects = reader.ReadUInt16();
                    //      aEffectsInfo = []
                    //      paInfo[#EffectsInfo] = aEffectsInfo
                    for (int nEffectNum = 0; nEffectNum < nNumEffects; nEffectNum++)
                    {
                        sHeader = new string(reader.ReadChars(4));
                        if (sHeader != "8BIM")
                            throw(new Exception("Effect header incorrect"));

                        EffectLayers.Effect effectForReading = new Endogine.Serialization.Photoshop.EffectLayers.Effect(reader);
                        //reader.JumpToEvenNthByte(2);
                        EffectLayers.Effect effect = null;
                        //long nEffectEndPos = reader.BaseStream.Position + effect.Size;
                        switch (effectForReading.Name)
                        {
                            case "cmnS": //common state
                                BinaryReverseReader subreader = effectForReading.GetDataReader();
                                bool bVisible = subreader.ReadBoolean();
                                //reader.BaseStream.Position+=2; //unused
                                break;

                            case "dsdw":
                            case "isdw":
                                //drop/inner shadow
                                if (effectForReading.Version == 0)
                                    effect = new Endogine.Serialization.Photoshop.EffectLayers.Shadow(effectForReading);
                                else
                                {
                                    //TODO:
                                }
                                break;

                            case "oglw":
                            case "iglw":
                                //outer/inner glow
                                if (effectForReading.Version == 0)
                                    effect = new Endogine.Serialization.Photoshop.EffectLayers.Glow(effectForReading);
                                else
                                {
                                    //TODO:
                                }

                                break;
                            case "bevl": //bevel
                                if (effectForReading.Version == 0)
                                    effect = new Endogine.Serialization.Photoshop.EffectLayers.Bevel(effectForReading);
                                else
                                {
                                    //TODO:
                                }
                                break;

                            case "sofi": //unknown
                                break;
                        }
                        this.Effects.Add(effect);
                        //reader.BaseStream.Position = nEffectEndPos;
                    }
                    break;

                case "lsct":
                    //TODO: what is this?
                    reader.BaseStream.Position+=4;
                    break;

                case "TySh":
                case "lfx2":
                    //TODO: what are these?
                    break;

                default:
                    string sMsg = "Unknown layer setting: " + sKey + " Length:" + nLength.ToString() + " Pos: "+reader.BaseStream.Position.ToString();
                    //EH.Put(sMsg);
                    break;
            }
            //add to nLength so it's padded to 4
            int nLengthMod = (int)(nLength % (long)4);
            if (nLengthMod > 0)
                nLength+= 4-(uint)nLengthMod;

            reader.BaseStream.Position = nPosStart + nLength;
            reader.JumpToEvenNthByte(2);
        }
예제 #8
0
        public Document(string a_sFilename)
        {
            FileStream stream = new FileStream(a_sFilename,
                FileMode.Open, FileAccess.Read);
            //stream.
            BinaryReverseReader reader = new BinaryReverseReader(stream); //, System.Text.Encoding.UTF8); //System.Text.Encoding.BigEndianUnicode);

            string signature = new string(reader.ReadChars(4));
            if (signature != "8BPS")
                return;

            #region Header
            this.Version = reader.ReadUInt16();
            if (Version != 1)
                throw new Exception("Can not read .psd version " + Version);
            byte[] buf = new byte[256];
            reader.Read(buf, (int)reader.BaseStream.Position, 6); //6 bytes reserved
            this.Channels = reader.ReadInt16();
            this.Rows = reader.ReadUInt32();
            this.Columns = reader.ReadUInt32();
            this.BitsPerPixel = (int)reader.ReadUInt16();
            this.ColorMode = (ColorModes)reader.ReadInt16();
            #endregion

            #region Palette
            uint nPaletteLength = reader.ReadUInt32();
            if (nPaletteLength > 0)
            {
                this.ColorData = reader.ReadBytes((int)nPaletteLength);
                if (this.ColorMode == ColorModes.Duotone)
                {
                }
                else
                {
                }
            }
            #endregion

            #region ImageResource section
            uint nResLength = reader.ReadUInt32();
            ResourceIDs resID = ResourceIDs.Undefined;
            if (nResLength > 0)
            {
                //read settings
                while (true)
                {
                    long nBefore = reader.BaseStream.Position;
                    string settingSignature = new string(reader.ReadChars(4));
                    if (settingSignature != "8BIM")
                    {
                        reader.BaseStream.Position = nBefore;
                        //TODO: it SHOULD be 4 bytes back - but sometimes ReadChars(4) advances 5 positions. WHY?!?
            //						reader.BaseStream.Position-=4;
                        break;
                    }

                    ImageResource imgRes = new ImageResource(reader);
                    resID = (ResourceIDs)imgRes.ID;
                    switch (resID) //imgRes.ID)
                    {
                        case ResourceIDs.ResolutionInfo:
                            this.ResolutionInfo =
                                new Endogine.Serialization.Photoshop.ImageResources.ResolutionInfo(imgRes);
                            break;

                        case ResourceIDs.DisplayInfo:
                            ImageResources.DisplayInfo displayInfo = new Endogine.Serialization.Photoshop.ImageResources.DisplayInfo(imgRes);
                            break;

                        case ResourceIDs.CopyrightInfo:
                            ImageResources.CopyrightInfo copyright = new Endogine.Serialization.Photoshop.ImageResources.CopyrightInfo(imgRes);
                            break;

                        case ResourceIDs.Thumbnail1:
                        case ResourceIDs.Thumbnail2:
                            ImageResources.Thumbnail thumbnail = new Endogine.Serialization.Photoshop.ImageResources.Thumbnail(imgRes);
                            break;

                        case ResourceIDs.GlobalAngle:
                            //m_nGlobalAngle = reader.ReadInt32();
                            break;

                        case ResourceIDs.IndexedColorTableCount:
                            this.NumColors = reader.ReadInt16();
                            break;

                        case ResourceIDs.TransparentIndex:
                            //m_nTransparentIndex = reader.ReadInt16();
                            break;

                        case ResourceIDs.Slices://Slices. What's that..?
                            //Leftlong, Botmlong etc etc
                            break;

                        case ResourceIDs.XMLInfo:
                            break;

                        case ResourceIDs.Unknown:
                            //Seems to be very common...
                            break;
                    }
                }
            }
            #endregion

            if (resID == ResourceIDs.Unknown4)
            {
                //it seems this one is
            }
            //reader.JumpToEvenNthByte(4);
            int nTotalLayersBytes = reader.ReadInt32();
            long nAfterLayersDefinitions = reader.BaseStream.Position + nTotalLayersBytes;

            //TODO: ??
            if (nTotalLayersBytes == 8)
                stream.Position+=nTotalLayersBytes;

            uint nSize = reader.ReadUInt32();
            long nLayersEndPos = reader.BaseStream.Position + nSize;

            short nNumLayers = reader.ReadInt16();
            bool bSkipFirstAlpha = false;

            if (nNumLayers < 0)
            {
                bSkipFirstAlpha = true;
                nNumLayers = (short)-nNumLayers;
            }

            List<Layer> loadOrderLayers = new List<Layer>();
            this._layers = new Dictionary<int, Layer>();
            for (int nLayerNum = 0; nLayerNum < nNumLayers; nLayerNum++)
            {
                Layer layerInfo = new Layer(reader, this);
                if (this._layers.ContainsKey(layerInfo.LayerID))
                    throw(new Exception("Duplicate layer IDs! " + layerInfo.LayerID.ToString()));
                else
                    this._layers.Add(layerInfo.LayerID, layerInfo);
                loadOrderLayers.Add(layerInfo);
            }

            //I have no idea what this is:
            //			ushort nWhat = reader.ReadUInt16();
            //			reader.BaseStream.Position+=(long)this.Header.Rows*2*2; //this.Header.Channels; //*bitsperpixel

            for (int layerNum = 0; layerNum < nNumLayers; layerNum++)
            {
                Layer layer = (Layer)loadOrderLayers[layerNum];
                layer.ReadPixels(reader);
            }

            reader.BaseStream.Position = nAfterLayersDefinitions;

            if (false)
            {
                //the big merged bitmap (which is how the photoshop document looked when it was saved)
                //TODO: read!

                //Bitmap bmp = null;
                //if (bmp != null)
                //{
                //    Sprite sp = new Sprite();
                //    MemberSpriteBitmap mb = new MemberSpriteBitmap(bmp);
                //    sp.Member = mb;
                //}
            }

            reader.Close();
            stream.Close();
        }
예제 #9
0
 public TdTaParseException(string message, BinaryReverseReader r)
     : base(message + "\nMore data:" + new string(r.ReadChars((int)Math.Max(100, r.BytesToEnd))))
 {
 }
예제 #10
0
        public Layer(BinaryReverseReader reader, Document document)
        {
            this._document = document;

            this._rect        = new ERectangle();
            this._rect.Y      = reader.ReadInt32();
            this._rect.X      = reader.ReadInt32();
            this._rect.Height = reader.ReadInt32() - this._rect.Y;
            this._rect.Width  = reader.ReadInt32() - this._rect.X;


            this.NumChannels = reader.ReadUInt16();
            this._channels   = new Dictionary <int, Channel>();
            for (int channelNum = 0; channelNum < this.NumChannels; channelNum++)
            {
                Channel ch = new Channel(reader, this);
                this._channels.Add(ch.Usage, ch);
            }

            string sHeader = new string(reader.ReadChars(4));

            if (sHeader != "8BIM")
            {
                throw(new Exception("Layer Channelheader error!"));
            }

            this.BlendKey = new string(reader.ReadChars(4));
            int nBlend = -1;

            try
            {
                nBlend = (int)Enum.Parse(typeof(_blendKeysPsd), this.BlendKey);
            }
            catch { }
            if (nBlend >= 0)
            {
                BlendKeys key = (BlendKeys)nBlend;
                this.BlendKey = Enum.GetName(typeof(BlendKeys), key);
            }

            this.Opacity = reader.ReadByte(); //(byte)(255 - (int)reader.ReadByte());
            //paLayerInfo[#Opacity] = 256 - m_oReader.readUC() --256-ScaleCharToQuantum(ReadBlobByte(image))
            this.Clipping = reader.ReadByte();
            this.Flags    = reader.ReadByte();

            reader.ReadByte();     //padding


            uint nSize          = reader.ReadUInt32();
            long nChannelEndPos = reader.BaseStream.Position + (long)nSize;

            if (nSize > 0)
            {
                uint nLength;
                //uint nCombinedlength = 0;

                this._mask = new Mask(reader, this);
                if (this._mask.Rectangle == null)
                {
                    this._mask = null;
                }

                //reader.BaseStream.Position+=nLength-16;

                //nCombinedlength+= nLength + 4;

                //blending ranges
                nLength = reader.ReadUInt32();
                for (uint i = 0; i < nLength / 8; i++)
                {
                    uint color1 = reader.ReadUInt32();
                    uint color2 = reader.ReadUInt32();
                }
                //nCombinedlength+= nLength + 4;

                //Name
                nLength = (uint)reader.ReadByte();
                reader.BaseStream.Position -= 1;
                this.Name = reader.ReadPascalString();
                //nCombinedlength+= nLength + 4;


                #region Adjustment etc layers
                //TODO: there's probably a 2-byte padding here
                sHeader = new string(reader.ReadChars(4));
                if (sHeader != "8BIM")
                {
                    reader.BaseStream.Position -= 2;
                    sHeader = new string(reader.ReadChars(4));
                }
                reader.BaseStream.Position -= 4;

                do
                {
                    try
                    {
                        this.ReadPSDChannelTag(reader);
                    }
                    catch
                    {
                        //dunno what the last bytes are for, just skip them:
                        reader.BaseStream.Position = nChannelEndPos;
                    }
                }while(reader.BaseStream.Position < nChannelEndPos);

                #endregion
            }
        }
예제 #11
0
        private void ReadPSDChannelTag(BinaryReverseReader reader)
        {
            string sHeader = new string(reader.ReadChars(4));

            if (sHeader != "8BIM")
            {
                reader.BaseStream.Position -= 4;               //back it up before throwing exception
                throw(new Exception("Effect header incorrect"));
            }

            string sKey      = new string(reader.ReadChars(4));
            uint   nLength   = reader.ReadUInt32();
            long   nPosStart = reader.BaseStream.Position;

            switch (sKey)
            {
            case "lyid":
                this.LayerID = (int)reader.ReadUInt32();
                break;

            case "fxrp":
                this.ReferencePoint   = new EPointF();
                this.ReferencePoint.X = reader.ReadPSD8BitSingle();
                this.ReferencePoint.Y = reader.ReadPSD8BitSingle();
                break;

            case "clbl":
                //blend clipping
                this.BlendClipping          = reader.ReadBoolean();
                reader.BaseStream.Position += 3;                       //padding
                break;

            case "infx":
                //blend interior elements
                this.Blend = reader.ReadBoolean();
                reader.BaseStream.Position += 3;                       //padding
                break;

            case "knko":
                //Knockout setting
                this.Knockout = reader.ReadBoolean();
                reader.BaseStream.Position += 3;                       //padding
                break;

            case "lspf":
                //Protected settings
                //TODO:
                reader.ReadBytes(4);                         //nLength?
                //bits 0-2 = Transparency, composite and position
                break;

            case "lclr":
                //Sheet Color setting
                this.SheetColor = System.Drawing.Color.FromArgb(
                    reader.ReadByte(),
                    reader.ReadByte(),
                    reader.ReadByte(),
                    reader.ReadByte());
                reader.BaseStream.Position += 2;                       //padding
                break;

            case "lnsr":
                //Layer Name Source setting
                string sWhatIsThis = new string(reader.ReadChars((int)nLength));
                //this.NameSourceSetting = reader.ReadUInt32();
                break;

            case "luni":
                //Unicode Layer name
                uint nUnicodeLength = reader.ReadUInt32();
                this.UnicodeName = new string(reader.ReadChars((int)nUnicodeLength * 2));
                break;

            case "lrFX":
                //Effects Layer info
                reader.BaseStream.Position += 2;                       //unused
                ushort nNumEffects = reader.ReadUInt16();
                //      aEffectsInfo = []
                //      paInfo[#EffectsInfo] = aEffectsInfo
                for (int nEffectNum = 0; nEffectNum < nNumEffects; nEffectNum++)
                {
                    sHeader = new string(reader.ReadChars(4));
                    if (sHeader != "8BIM")
                    {
                        throw(new Exception("Effect header incorrect"));
                    }

                    EffectLayers.Effect effectForReading = new Endogine.Serialization.Photoshop.EffectLayers.Effect(reader);
                    //reader.JumpToEvenNthByte(2);
                    EffectLayers.Effect effect = null;
                    //long nEffectEndPos = reader.BaseStream.Position + effect.Size;
                    switch (effectForReading.Name)
                    {
                    case "cmnS":                                     //common state
                        BinaryReverseReader subreader = effectForReading.GetDataReader();
                        bool bVisible = subreader.ReadBoolean();
                        //reader.BaseStream.Position+=2; //unused
                        break;

                    case "dsdw":
                    case "isdw":
                        //drop/inner shadow
                        if (effectForReading.Version == 0)
                        {
                            effect = new Endogine.Serialization.Photoshop.EffectLayers.Shadow(effectForReading);
                        }
                        else
                        {
                            //TODO:
                        }
                        break;

                    case "oglw":
                    case "iglw":
                        //outer/inner glow
                        if (effectForReading.Version == 0)
                        {
                            effect = new Endogine.Serialization.Photoshop.EffectLayers.Glow(effectForReading);
                        }
                        else
                        {
                            //TODO:
                        }

                        break;

                    case "bevl":                                     //bevel
                        if (effectForReading.Version == 0)
                        {
                            effect = new Endogine.Serialization.Photoshop.EffectLayers.Bevel(effectForReading);
                        }
                        else
                        {
                            //TODO:
                        }
                        break;

                    case "sofi":                                     //unknown
                        break;
                    }
                    this.Effects.Add(effect);
                    //reader.BaseStream.Position = nEffectEndPos;
                }
                break;

            case "lsct":
                //TODO: what is this?
                reader.BaseStream.Position += 4;
                break;

            case "TySh":
            case "lfx2":
                //TODO: what are these?
                break;

            default:
                string sMsg = "Unknown layer setting: " + sKey + " Length:" + nLength.ToString() + " Pos: " + reader.BaseStream.Position.ToString();
                //EH.Put(sMsg);
                break;
            }
            //add to nLength so it's padded to 4
            int nLengthMod = (int)(nLength % (long)4);

            if (nLengthMod > 0)
            {
                nLength += 4 - (uint)nLengthMod;
            }

            reader.BaseStream.Position = nPosStart + nLength;
            reader.JumpToEvenNthByte(2);
        }
예제 #12
0
		public ImageResource(BinaryReverseReader reverseReader)
		{
			Name = String.Empty;
			OSType = new String(reverseReader.ReadChars(4));
			if (OSType != "8BIM" && OSType != "MeSa")
			{
				throw new InvalidOperationException("Could not read an image resource");
			}

			ID = reverseReader.ReadInt16();
			Name = reverseReader.ReadPascalString();

			UInt32 settingLength = reverseReader.ReadUInt32();
			Data = reverseReader.ReadBytes((Int32)settingLength);

			if (reverseReader.BaseStream.Position % 2 == 1) reverseReader.ReadByte();
		}
예제 #13
0
        public PsdFile Load(String filename)
		{
			using (FileStream stream = new FileStream(filename, FileMode.Open))
			{
				//binary reverse reader reads data types in big-endian format.
				BinaryReverseReader reader = new BinaryReverseReader(stream);

				#region "Headers"
				//The headers area is used to check for a valid PSD file
				Debug.WriteLine("LoadHeader started at " + reader.BaseStream.Position.ToString(CultureInfo.InvariantCulture));

				String signature = new String(reader.ReadChars(4));
				if (signature != "8BPS") throw new IOException("Bad or invalid file stream supplied");

				//get the version number, should be 1 always
				if ((Version = reader.ReadInt16()) != 1) throw new IOException("Invalid version number supplied");

				//get rid of the 6 bytes reserverd in PSD format
				reader.BaseStream.Position += 6;

				//get the rest of the information from the PSD file.
				//Everytime ReadInt16() is called, it reads 2 bytes.
				//Everytime ReadInt32() is called, it reads 4 bytes.
				_channels = reader.ReadInt16();
				_rows = reader.ReadInt32();
				_columns = reader.ReadInt32();
				_depth = reader.ReadInt16();
				ColorMode = (ColorModes)reader.ReadInt16();

				//by end of headers, the reader has read 26 bytes into the file.
				#endregion //End Headers

				#region "ColorModeData"
				Debug.WriteLine("LoadColorModeData started at " + reader.BaseStream.Position.ToString(CultureInfo.InvariantCulture));

				UInt32 paletteLength = reader.ReadUInt32(); //readUint32() advances the reader 4 bytes.
				if (paletteLength > 0)
				{
					ColorModeData = reader.ReadBytes((Int32)paletteLength);
				}
				#endregion //End ColorModeData


				#region "Loading Image Resources"
				//This part takes extensive use of classes that I didn't write therefore
				//I can't document much on what they do.

				Debug.WriteLine("LoadingImageResources started at " + reader.BaseStream.Position.ToString(CultureInfo.InvariantCulture));

                _imageResources.Clear();

				UInt32 imgResLength = reader.ReadUInt32();
				if (imgResLength <= 0) return null;

				Int64 startPosition = reader.BaseStream.Position;

				while ((reader.BaseStream.Position - startPosition) < imgResLength)
				{
					ImageResource imgRes = new ImageResource(reader);

					ResourceIDs resID = (ResourceIDs)imgRes.ID;
					switch (resID)
					{
						case ResourceIDs.ResolutionInfo:
							imgRes = new ResolutionInfo(imgRes);
							break;
						case ResourceIDs.Thumbnail1:
						case ResourceIDs.Thumbnail2:
							imgRes = new Thumbnail(imgRes);
							break;
						case ResourceIDs.AlphaChannelNames:
							imgRes = new AlphaChannels(imgRes);
							break;
					}

                    _imageResources.Add(imgRes);

				}
				// make sure we are not on a wrong offset, so set the stream position 
				// manually
				reader.BaseStream.Position = startPosition + imgResLength;

				#endregion //End LoadingImageResources


				#region "Layer and Mask Info"
				//We are gonna load up all the layers and masking of the PSD now.
				Debug.WriteLine("LoadLayerAndMaskInfo - Part1 started at " + reader.BaseStream.Position.ToString(CultureInfo.InvariantCulture));
				UInt32 layersAndMaskLength = reader.ReadUInt32();

				if (layersAndMaskLength <= 0) return null;

				//new start position
				startPosition = reader.BaseStream.Position;

				//Lets start by loading up all the layers
				LoadLayers(reader);
				//we are done the layers, load up the masks
				LoadGlobalLayerMask(reader);

				// make sure we are not on a wrong offset, so set the stream position 
				// manually
				reader.BaseStream.Position = startPosition + layersAndMaskLength;
				#endregion //End Layer and Mask info

				#region "Loading Final Image"

				//we have loaded up all the information from the PSD file
				//into variables we can use later on.

				//lets finish loading the raw data that defines the image 
				//in the picture.

				Debug.WriteLine("LoadImage started at " + reader.BaseStream.Position.ToString(CultureInfo.InvariantCulture));

				ImageCompression = (ImageCompression)reader.ReadInt16();

				ImageData = new Byte[_channels][];

				//---------------------------------------------------------------

				if (ImageCompression == ImageCompression.Rle)
				{
					// The RLE-compressed data is proceeded by a 2-byte data count for each row in the data,
					// which we're going to just skip.
					reader.BaseStream.Position += _rows * _channels * 2;
				}

				//---------------------------------------------------------------

				Int32 bytesPerRow = 0;

				switch (_depth)
				{
					case 1:
						bytesPerRow = _columns;//NOT Shure
						break;
					case 8:
						bytesPerRow = _columns;
						break;
					case 16:
						bytesPerRow = _columns * 2;
						break;
				}

				//---------------------------------------------------------------

				for (Int32 ch = 0; ch < _channels; ch++)
				{
					ImageData[ch] = new Byte[_rows * bytesPerRow];

					switch (ImageCompression)
					{
						case ImageCompression.Raw:
							reader.Read(ImageData[ch], 0, ImageData[ch].Length);
							break;
						case ImageCompression.Rle:
							{
								for (Int32 i = 0; i < _rows; i++)
								{
									Int32 rowIndex = i * _columns;
									RleHelper.DecodedRow(reader.BaseStream, ImageData[ch], rowIndex, bytesPerRow);
								}
							}
							break;
					}
				}

				#endregion //End LoadingFinalImage
			}

            return this;
		} //end Load()
예제 #14
0
        public Document(string a_sFilename)
        {
            FileStream stream = new FileStream(a_sFilename,
                                               FileMode.Open, FileAccess.Read);
            //stream.
            BinaryReverseReader reader = new BinaryReverseReader(stream);             //, System.Text.Encoding.UTF8); //System.Text.Encoding.BigEndianUnicode);

            string signature = new string(reader.ReadChars(4));

            if (signature != "8BPS")
            {
                return;
            }

            #region Header
            this.Version = reader.ReadUInt16();
            if (Version != 1)
            {
                throw new Exception("Can not read .psd version " + Version);
            }
            byte[] buf = new byte[256];
            reader.Read(buf, (int)reader.BaseStream.Position, 6); //6 bytes reserved
            this.Channels     = reader.ReadInt16();
            this.Rows         = reader.ReadUInt32();
            this.Columns      = reader.ReadUInt32();
            this.BitsPerPixel = (int)reader.ReadUInt16();
            this.ColorMode    = (ColorModes)reader.ReadInt16();
            #endregion

            #region Palette
            uint nPaletteLength = reader.ReadUInt32();
            if (nPaletteLength > 0)
            {
                this.ColorData = reader.ReadBytes((int)nPaletteLength);
                if (this.ColorMode == ColorModes.Duotone)
                {
                }
                else
                {
                }
            }
            #endregion

            #region ImageResource section
            uint        nResLength = reader.ReadUInt32();
            ResourceIDs resID      = ResourceIDs.Undefined;
            if (nResLength > 0)
            {
                //read settings
                while (true)
                {
                    long   nBefore          = reader.BaseStream.Position;
                    string settingSignature = new string(reader.ReadChars(4));
                    if (settingSignature != "8BIM")
                    {
                        reader.BaseStream.Position = nBefore;
                        //TODO: it SHOULD be 4 bytes back - but sometimes ReadChars(4) advances 5 positions. WHY?!?
//						reader.BaseStream.Position-=4;
                        break;
                    }

                    ImageResource imgRes = new ImageResource(reader);
                    resID = (ResourceIDs)imgRes.ID;
                    switch (resID)                     //imgRes.ID)
                    {
                    case ResourceIDs.ResolutionInfo:
                        this.ResolutionInfo =
                            new Endogine.Serialization.Photoshop.ImageResources.ResolutionInfo(imgRes);
                        break;

                    case ResourceIDs.DisplayInfo:
                        ImageResources.DisplayInfo displayInfo = new Endogine.Serialization.Photoshop.ImageResources.DisplayInfo(imgRes);
                        break;

                    case ResourceIDs.CopyrightInfo:
                        ImageResources.CopyrightInfo copyright = new Endogine.Serialization.Photoshop.ImageResources.CopyrightInfo(imgRes);
                        break;

                    case ResourceIDs.Thumbnail1:
                    case ResourceIDs.Thumbnail2:
                        ImageResources.Thumbnail thumbnail = new Endogine.Serialization.Photoshop.ImageResources.Thumbnail(imgRes);
                        break;

                    case ResourceIDs.GlobalAngle:
                        //m_nGlobalAngle = reader.ReadInt32();
                        break;

                    case ResourceIDs.IndexedColorTableCount:
                        this.NumColors = reader.ReadInt16();
                        break;

                    case ResourceIDs.TransparentIndex:
                        //m_nTransparentIndex = reader.ReadInt16();
                        break;

                    case ResourceIDs.Slices:                            //Slices. What's that..?
                        //Leftlong, Botmlong etc etc
                        break;

                    case ResourceIDs.XMLInfo:
                        break;

                    case ResourceIDs.Unknown:
                        //Seems to be very common...
                        break;
                    }
                }
            }
            #endregion

            if (resID == ResourceIDs.Unknown4)
            {
                //it seems this one is
            }
            //reader.JumpToEvenNthByte(4);
            int  nTotalLayersBytes       = reader.ReadInt32();
            long nAfterLayersDefinitions = reader.BaseStream.Position + nTotalLayersBytes;

            //TODO: ??
            if (nTotalLayersBytes == 8)
            {
                stream.Position += nTotalLayersBytes;
            }

            uint nSize         = reader.ReadUInt32();
            long nLayersEndPos = reader.BaseStream.Position + nSize;

            short nNumLayers      = reader.ReadInt16();
            bool  bSkipFirstAlpha = false;

            if (nNumLayers < 0)
            {
                bSkipFirstAlpha = true;
                nNumLayers      = (short)-nNumLayers;
            }

            List <Layer> loadOrderLayers = new List <Layer>();
            this._layers = new Dictionary <int, Layer>();
            for (int nLayerNum = 0; nLayerNum < nNumLayers; nLayerNum++)
            {
                Layer layerInfo = new Layer(reader, this);
                if (this._layers.ContainsKey(layerInfo.LayerID))
                {
                    throw(new Exception("Duplicate layer IDs! " + layerInfo.LayerID.ToString()));
                }
                else
                {
                    this._layers.Add(layerInfo.LayerID, layerInfo);
                }
                loadOrderLayers.Add(layerInfo);
            }

            //I have no idea what this is:
//			ushort nWhat = reader.ReadUInt16();
//			reader.BaseStream.Position+=(long)this.Header.Rows*2*2; //this.Header.Channels; //*bitsperpixel

            for (int layerNum = 0; layerNum < nNumLayers; layerNum++)
            {
                Layer layer = (Layer)loadOrderLayers[layerNum];
                layer.ReadPixels(reader);
            }

            reader.BaseStream.Position = nAfterLayersDefinitions;


            if (false)
            {
                //the big merged bitmap (which is how the photoshop document looked when it was saved)
                //TODO: read!

                //Bitmap bmp = null;
                //if (bmp != null)
                //{
                //    Sprite sp = new Sprite();
                //    MemberSpriteBitmap mb = new MemberSpriteBitmap(bmp);
                //    sp.Member = mb;
                //}
            }

            reader.Close();
            stream.Close();
        }
예제 #15
0
		public Layer(BinaryReverseReader reverseReader, PsdFile psdFile)
		{
			AdjustmentInfo = new List<AdjusmentLayerInfo>();
			SortedChannels = new SortedList<Int16, Channel>();
			Channels = new List<Channel>();
			Debug.WriteLine("Layer started at " + reverseReader.BaseStream.Position.ToString(CultureInfo.InvariantCulture));

			PsdFile = psdFile;

			Rectangle localRectangle = new Rectangle
			                           {
				                           Y = reverseReader.ReadInt32(),
										   X = reverseReader.ReadInt32()
			                           };
			localRectangle.Height = reverseReader.ReadInt32() - localRectangle.Y;
			localRectangle.Width = reverseReader.ReadInt32() - localRectangle.X;

			Rect = localRectangle;

			Int32 numberOfChannels = reverseReader.ReadUInt16();
			Channels.Clear();
			for (Int32 channel = 0; channel < numberOfChannels; channel++)
			{
				Channel ch = new Channel(reverseReader, this);
				Channels.Add(ch);
				SortedChannels.Add(ch.ID, ch);
			}

			String signature = new String(reverseReader.ReadChars(4));

			if (signature != "8BIM") throw (new IOException("Layer Channelheader error"));

			_blendModeKeyStr = new String(reverseReader.ReadChars(4));
			Opacity = reverseReader.ReadByte();

			Clipping = reverseReader.ReadByte() > 0;

			Byte flags = reverseReader.ReadByte();
			_flags = new BitVector32(flags);

			reverseReader.ReadByte(); //padding

			Debug.WriteLine("Layer extraDataSize started at " + reverseReader.BaseStream.Position.ToString(CultureInfo.InvariantCulture));

			// this is the total size of the MaskData, the BlendingRangesData, the 
			// Name and the AdjustmenLayerInfo
			UInt32 extraDataSize = reverseReader.ReadUInt32();

			// remember the start position for calculation of the 
			// AdjustmenLayerInfo size
			Int64 extraDataStartPosition = reverseReader.BaseStream.Position;

			MaskData = new Mask(reverseReader, this);
			BlendingRangesData = new BlendingRanges(reverseReader, this);

			Int64 namePosition = reverseReader.BaseStream.Position;

			Name = reverseReader.ReadPascalString();

			Int32 paddingBytes = (Int32)((reverseReader.BaseStream.Position - namePosition) % 4);

			Debug.Print("Layer {0} padding bytes after name", paddingBytes);
			reverseReader.ReadBytes(paddingBytes);

			AdjustmentInfo.Clear();

			Int64 adjustmenLayerEndPos = extraDataStartPosition + extraDataSize;
			while (reverseReader.BaseStream.Position < adjustmenLayerEndPos)
			{
				try
				{
					AdjustmentInfo.Add(new AdjusmentLayerInfo(reverseReader, this));
				}
				catch
				{
					reverseReader.BaseStream.Position = adjustmenLayerEndPos;
				}
			}

			// make shure we are not on a wrong offset, so set the stream position 
			// manually
			reverseReader.BaseStream.Position = adjustmenLayerEndPos;
		}