public static List <ImageResource> ReadImageResources(BinaryPSDReader reader) { List <ImageResource> result = new List <ImageResource>(); while (true) { long nBefore = reader.BaseStream.Position; string settingSignature = new string(reader.ReadPSDChars(4)); if (settingSignature != "8BIM") { reader.BaseStream.Position = nBefore; //reader.BaseStream.Position-=4; break; } ImageResource imgRes = new ImageResource(reader); ResourceIDs resID = (ResourceIDs)imgRes.ID; if (!Enum.IsDefined(typeof(ResourceIDs), (int)imgRes.ID)) { if (imgRes.ID > 2000 && imgRes.ID <= 2999) { //Stupid Adobe engineers... This is SO not using the same pattern as everything else!!! resID = ResourceIDs.PathInfo; } } if (ResourceTypes.ContainsKey(resID)) { Type type = ResourceTypes[resID]; System.Reflection.ConstructorInfo ci = type.GetConstructor(new Type[] { typeof(ImageResource) }); imgRes = (ImageResource)ci.Invoke(new object[] { imgRes }); } //if (resID != ResourceIDs.Undefined) result.Add(imgRes); } return(result); }
public static void Prepare() { if (ResourceTypes != null) { return; } //Get ImageResource types //TODO: is there a way to not get *all* types, but only those in a sub-namespace? ResourceTypes = new Dictionary <ResourceIDs, Type>(); Type[] types = typeof(ImageResource).Assembly.GetTypes(); foreach (Type type in types) { if (type.FullName.Contains("ImageResources.")) { if (type.FullName.Contains("+")) { continue; } Type actualType = type; // type.ReflectedType; //Because strangely, when type has internal classes, it wraps both of them somehow? e.g. GridGuidesInfo+GridGuide System.Reflection.ConstructorInfo ci = actualType.GetConstructor(new Type[] { }); ImageResource ir = (ImageResource)ci.Invoke(new object[] { }); ResourceIDs[] rids = ir.AcceptedResourceIDs; if (rids == null) { string name = actualType.FullName.Substring(type.FullName.LastIndexOf(".") + 1); rids = new ResourceIDs[] { (ResourceIDs)Enum.Parse(typeof(ResourceIDs), name) }; } foreach (ResourceIDs rid in rids) { ResourceTypes.Add(rid, actualType); } } } }
public ImageResource(ImageResource imgRes) { this.ID = imgRes.ID; this.Name = imgRes.Name; }
//TODO: Resources should be an Endogine PropList public ImageResource AddResource(ImageResource.ResourceIDs resourceId) { //TODO: check if we already have one of same type! Except for f*cking paths (stupid Adobe), gotta get special treatment... Type type = ImageResource.ResourceTypes[resourceId]; ImageResource imgRes = ImageResource.CreateResource(type); this._imageResources.Add(imgRes); return imgRes; }
public Document(string a_sFilename) { this.Init(); FileStream stream = new FileStream(a_sFilename, FileMode.Open, FileAccess.Read); //stream. BinaryPSDReader reader = new BinaryPSDReader(stream); string signature = new string(reader.ReadPSDChars(4)); if (signature != "8BPS") { return; } this._header = new Header(reader); //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(); #region Palette uint nPaletteLength = reader.ReadUInt32(); if (nPaletteLength > 0) { this.ColorTable = new List <Color>(); for (int i = 0; i < nPaletteLength; i += 3) { this.ColorTable.Add(Color.FromArgb((int)reader.ReadByte(), (int)reader.ReadByte(), (int)reader.ReadByte())); } //this.ColorTable.Add(Color.FromArgb(255, 10, 20)); if (this.ColorMode == ColorModes.Duotone) { } else { } } #endregion uint nResLength = reader.ReadUInt32(); //? Number of bytes, or number of entries?? if (nResLength > 0) { //read settings this._imageResources = ImageResource.ReadImageResources(reader); } //reader.JumpToEvenNthByte(4); uint nTotalLayersBytes = reader.ReadUInt32(); long nAfterLayersDefinitions = reader.BaseStream.Position + nTotalLayersBytes; if (nTotalLayersBytes == 8) { stream.Position += nTotalLayersBytes; //this.Unknown = Endogine.Serialization.ReadableBinary.CreateHexEditorString(reader.ReadBytes((int)reader.BytesToEnd)); } else { uint nSize = reader.ReadUInt32(); //What's the difference between nTotalLayersBytes and nSize really? 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 List <Layer>(); // new Dictionary<int, Layer>(); for (int nLayerNum = 0; nLayerNum < nNumLayers; nLayerNum++) { Layer layerInfo = new Layer(reader, this); layerInfo.DebugLayerLoadOrdinal = nLayerNum; //if (layerInfo.LayerID < 0) // layerInfo.LayerID = nLayerNum; //if (this._layers.ContainsKey(layerInfo.LayerID)) // throw(new Exception("Duplicate layer IDs! " + layerInfo.LayerID.ToString())); //else // this._layers.Add(layerInfo.LayerID, layerInfo); this._layers.Add(layerInfo); loadOrderLayers.Add(layerInfo); } for (int layerNum = 0; layerNum < nNumLayers; layerNum++) { Layer layer = (Layer)loadOrderLayers[layerNum]; layer.ReadPixels(reader); } reader.JumpToEvenNthByte(4); if (reader.BaseStream.Position != nLayersEndPos) { reader.BaseStream.Position = nLayersEndPos; // nAfterLayersDefinitions; } //Global layer mask uint maskLength = reader.ReadUInt32(); this._tempGlobalLayerMask = null; if (maskLength > 0) { this._tempGlobalLayerMask = reader.ReadBytes((int)maskLength); //TODO: the docs are obviously wrong here... //ushort overlayColorSpace = reader.ReadUInt16(); //undefined in docs //for (int i = 0; i < 4; i++) // reader.ReadUInt16(); //TODO: UInt16 if 16-bit color? Color components - says *both* 4*2 bytes, and 8 bytes in the docs? //reader.ReadUInt16(); //opacity (0-100) //reader.ReadByte(); //Kind: 0=Color selectedi.e. inverted; 1=Color protected;128=use value stored per layer. //reader.ReadByte(); //padding } //hmm... another section of "global" layer resources..? while (true) { long cpPos = reader.BaseStream.Position; string sHeader = new string(reader.ReadPSDChars(4)); reader.BaseStream.Position = cpPos; //TODO: -= 4 should work, but sometimes ReadPSDChars advances 5?!?! if (sHeader != "8BIM") { break; } LayerResource res = LayerResource.ReadLayerResource(reader, null); this._globalLayerResources.Add(res); } } bool readGlobalImage = true; if (readGlobalImage) { this._globalImage = new GlobalImage(this); this._globalImage.Load(reader); //the big merged bitmap (which is how the photoshop document looked when it was saved) //Bitmap bmp = this._globalImage.Bitmap; } reader.Close(); stream.Close(); }
private void Init() { ImageResource.Prepare(); }
public static List<ImageResource> ReadImageResources(BinaryPSDReader reader) { List<ImageResource> result = new List<ImageResource>(); while (true) { long nBefore = reader.BaseStream.Position; string settingSignature = new string(reader.ReadPSDChars(4)); if (settingSignature != "8BIM") { reader.BaseStream.Position = nBefore; //reader.BaseStream.Position-=4; break; } ImageResource imgRes = new ImageResource(reader); ResourceIDs resID = (ResourceIDs)imgRes.ID; if (!Enum.IsDefined(typeof(ResourceIDs), (int)imgRes.ID)) { if (imgRes.ID > 2000 && imgRes.ID <= 2999) { //Stupid Adobe engineers... This is SO not using the same pattern as everything else!!! resID = ResourceIDs.PathInfo; } } if (ResourceTypes.ContainsKey(resID)) { Type type = ResourceTypes[resID]; System.Reflection.ConstructorInfo ci = type.GetConstructor(new Type[] { typeof(ImageResource) }); imgRes = (ImageResource)ci.Invoke(new object[] { imgRes }); } //if (resID != ResourceIDs.Undefined) result.Add(imgRes); } return result; }