public Mask(BinaryReverseReader reader, Layer layer) { this._layer = layer; int nLength = (int)reader.ReadUInt32(); if (nLength == 0) return; long nStart = reader.BaseStream.Position; this.Rectangle = new ERectangle(); this.Rectangle.Y = reader.ReadInt32(); this.Rectangle.X = reader.ReadInt32(); this.Rectangle.Height = reader.ReadInt32() - Rectangle.Y; this.Rectangle.Width = reader.ReadInt32() - Rectangle.X; byte color = reader.ReadByte(); byte flags = reader.ReadByte(); if (nLength == 36) { int someOtherFlags = reader.ReadByte(); byte maskBg = reader.ReadByte(); ERectangle rect = new ERectangle(); rect.Y = reader.ReadInt32(); rect.X = reader.ReadInt32(); rect.Height = reader.ReadInt32() - rect.Y; rect.Width = reader.ReadInt32() - rect.X; } reader.BaseStream.Position = nStart + nLength; }
/// <summary> /// Initializes a new instance of the <see cref="ResolutionInfo"/> class using the <see cref="ImageResource"/>. /// </summary> /// <param name="imgRes">The image resource to use.</param> public ResolutionInfo(ImageResource imgRes) : base(imgRes) { BinaryReverseReader dataReader = imgRes.DataReader; // read horizontal resolution dataReader.ReadInt16(); // read horizontal resolution units (1=pixels per inch, 2=pixels per centimeter) dataReader.ReadInt32(); // read the width units (1=inches, 2=cm, 3=pt, 4=picas, 5=columns) dataReader.ReadInt16(); // read vertical resolution dataReader.ReadInt16(); // read vertical resolution units (1=pixels per inch, 2=pixels per centimeter) dataReader.ReadInt32(); // read the height units (1=inches, 2=cm, 3=pt, 4=picas, 5=columns) dataReader.ReadInt16(); dataReader.Close(); }
public Channel(BinaryReverseReader reader, Layer layer) { this._usage = reader.ReadInt16(); this._length = (long)reader.ReadUInt32(); this._layer = layer; }
public CopyrightInfo(ImageResource imgRes) { BinaryReverseReader reader = imgRes.GetDataReader(); this.Copyrighted = reader.ReadByte() == 0?false:true; reader.Close(); }
private byte lookForwardByte(BinaryReverseReader stream) { byte b = readByte(stream); putBack(); return(b); }
public TypeToolTyShPH6(BinaryReverseReader r) { ushort Version = r.ReadUInt16(); //1= Photoshop 5.0 this.Transform = new Matrix2D(r); ushort TextDescriptorVersion = r.ReadUInt16(); //=50. For Photoshop 6.0. if (TextDescriptorVersion == 50) { uint XTextDescriptorVersion = r.ReadUInt32(); //=16. For Photoshop 6.0. this.TxtDescriptor = new PsdDescriptor(r); ushort WarpVersion = r.ReadUInt16(); //2 bytes, =1. For Photoshop 6.0. uint WarpDescriptorVersion = r.ReadUInt32(); //4 bytes, =16. For Photoshop 6.0. var a = (PsdTextData)TxtDescriptor.getObjects()["EngineData"]; engine = (object)a.getProperties(); engineData = (Dictionary <string, object>)engine; StylesheetReader = new TdTaStylesheetReader(engineData); //string desc = this.TxtDescriptor.getString(); this.WarpDescriptor = new PsdDescriptor(r); //Warp descriptor this.Data = r.ReadBytes((int)r.BytesToEnd); //17 bytes???? All zeroes? if (Data.Length != 17 || !(Array.TrueForAll(Data, b => b == 0))) { string s = ReadableBinary.CreateHexEditorString(Data); } } }
public void ReadPixels(BinaryReverseReader reader) { long posBefore = reader.BaseStream.Position; this._data = PixelsProcessing.ReadPixels(reader, this.Layer.Width, this.Layer.Height, this.Layer.BitsPerPixel, false); reader.BaseStream.Position = posBefore + this._length; }
static private BinaryReverseReader CreateReadStream(LayerInfo info) { RawLayerInfo rawly = (RawLayerInfo)info; Stream str = new MemoryStream(rawly.Data); BinaryReverseReader brd = new BinaryReverseReader(str); if (rawly.Key == "vogk") { int version = brd.ReadInt32(); int version1 = brd.ReadInt32(); } else if (rawly.Key == "vstk") { int vers = brd.ReadInt32(); } else if (rawly.Key == "vscg") { int v = brd.ReadInt32(); int v1 = brd.ReadInt32(); } else if (rawly.Key == "lfx2") { int v = brd.ReadInt32(); int v1 = brd.ReadInt32(); } else if (rawly.Key == "SoCo") { int v = brd.ReadInt32(); } return(brd); }
public ResolutionInfo(ImageResource imgRes) : base(imgRes) { //m_bResolutionInfoFilled = true; BinaryReverseReader reader = imgRes.GetDataReader(); this.hRes = reader.ReadInt16(); this.hResUnit = reader.ReadInt32(); this.widthUnit = reader.ReadInt16(); this.vRes = reader.ReadInt16(); this.vResUnit = reader.ReadInt32(); this.heightUnit = reader.ReadInt16(); reader.Close(); //int ppm_x = 3780; // 96 dpi //int ppm_y = 3780; // 96 dpi //if (psd.ResolutionInfo != null) //{ // int nHorzResolution = (int)psd.ResolutionInfo.hRes; // int nVertResolution = (int)psd.ResolutionInfo.vRes; // ppm_x = (nHorzResolution * 10000) / 254; // ppm_y = (nVertResolution * 10000) / 254; //} }
/** * Instantiates a new psd descriptor. * * @param stream the stream * @throws IOException Signals that an I/O exception has occurred. */ public PsdDescriptor(BinaryReverseReader stream) { int unicstrlength = stream.ReadInt32() * 2; string unicstr = Encoding.Unicode.GetString(stream.ReadBytes(unicstrlength)); int classlength = stream.ReadInt32(); if (classlength != 0) { classId = Encoding.Default.GetString(stream.ReadBytes(classlength)); } else { classId = Encoding.Default.GetString(stream.ReadBytes(4)); } // Unicode string: name from classID // int nameLen = stream.ReadInt32() * 2; //stream.ReadBytes(nameLen); //classId = stream.ReadString(); int itemsCount = stream.ReadInt32(); for (int i = 0; i < itemsCount; i++) { int size = stream.ReadInt32(); if (size == 0) { size = 4; } String key = Encoding.Default.GetString(stream.ReadBytes(size)); objects.Add(key, PsdObjectFactory.loadPsdObject(stream)); //objects.Add(key, new PsdObject()); } }
public PsdText(BinaryReverseReader stream) { int textSize = stream.ReadInt32() * 2; StringBuilder buffer = new StringBuilder(textSize); bool stopReading = false; for (int ti = 0; ti < textSize; ti++) { char b = (char)stream.ReadByte(); if (b == 0) { stopReading = true; } else { stopReading = false; } if (!stopReading) { if (b == 13 || b == 10) { buffer.Append('\n'); } else { buffer.Append(b); } } } value = buffer.ToString(); }
private void skipString(BinaryReverseReader stream, string str) { for (int i = 0; i < str.Length; i++) { char streamCh = (char)readByte(stream); Debug.Assert(streamCh == str[i], "char " + streamCh + " mustBe " + str[i]); } }
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 }
public Color ReadColor(BinaryReverseReader reader) { reader.BaseStream.Position+=2; //padding ushort r = reader.ReadUInt16(); ushort g = reader.ReadUInt16(); ushort b = reader.ReadUInt16(); return Color.FromArgb((int)r,(int)g,(int)b); }
static private BinaryReverseReader GetByteStreamFromDouble(double val) { byte[] barr = ConvertDoubleToByteArray(val); Stream st = new MemoryStream(barr); BinaryReverseReader rd = new BinaryReverseReader(st); return(rd); }
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 }
public string ReadPascalString(BinaryReverseReader rd) { var size = rd.ReadByte(); var body = rd.ReadBytes(size); var text = System.Text.Encoding.ASCII.GetString(body); return(text); }
internal Channel(BinaryReverseReader reverseReader, Layer layer) { Debug.WriteLine("Channel started at " + reverseReader.BaseStream.Position.ToString(CultureInfo.InvariantCulture)); ID = reverseReader.ReadInt16(); Length = reverseReader.ReadInt32(); Layer = layer; }
public Matrix2D(BinaryReverseReader r) { this.M11 = ReadPSDDouble(r); this.M12 = ReadPSDDouble(r); this.M13 = ReadPSDDouble(r); this.M21 = ReadPSDDouble(r); this.M22 = ReadPSDDouble(r); this.M23 = ReadPSDDouble(r); }
/** * Instantiates a new psd list. * * @param stream the stream * @throws IOException Signals that an I/O exception has occurred. */ public PsdList(BinaryReverseReader stream) { int itemsCount = stream.ReadInt32(); for (int i = 0; i < itemsCount; i++) { objects.Add(PsdObjectFactory.loadPsdObject(stream)); } }
public Matrix2D(BinaryReverseReader r) { this.M11 = r.ReadDouble(); this.M12 = r.ReadDouble(); this.M13 = r.ReadDouble(); this.M21 = r.ReadDouble(); this.M22 = r.ReadDouble(); this.M23 = r.ReadDouble(); }
public ImageResource(BinaryReverseReader reader) { this.ID = reader.ReadUInt16(); this.Name = reader.ReadPascalString(); uint settingLength = reader.ReadUInt32(); this.Data = reader.ReadBytes((int)settingLength); if (reader.BaseStream.Position % 2 == 1) reader.ReadByte(); }
public Color ReadColor(BinaryReverseReader reader) { reader.BaseStream.Position += 2; //padding ushort r = reader.ReadUInt16(); ushort g = reader.ReadUInt16(); ushort b = reader.ReadUInt16(); return(Color.FromArgb((int)r, (int)g, (int)b)); }
static private double ReadPSDDouble(BinaryReverseReader br) { double val = br.ReadDouble(); unsafe { BinaryReverseReader.SwapBytes((byte *)&val, 8); } return(val); }
private void skipWhitespaces(BinaryReverseReader stream) { byte b; do { b = readByte(stream); } while (b == ' ' || b == 10 || b == 9); putBack(); }
public int getSize(BinaryReverseReader str) { int size = str.ReadInt32(); if (size == 0) { size = 4; } return(size); }
public PsdTextData(BinaryReverseReader stream) { int size = stream.ReadInt32(); byte[] array = new byte[size]; array = stream.ReadBytes(size); Stream str = new MemoryStream(array); BinaryReverseReader br = new BinaryReverseReader(str); properties = readMap(br); }
public double ReadPSDDouble(BinaryReverseReader br) { //TODO: examine PSD format! double val = br.ReadDouble(); unsafe { BinaryReverseReader.SwapBytes((byte *)&val, 8); } return(val); }
public BlendingRanges(BinaryReverseReader reader, Layer layer) { Data = new Byte[0]; Debug.WriteLine("BlendingRanges started at " + reader.BaseStream.Position.ToString(CultureInfo.InvariantCulture)); Layer = layer; Int32 dataLength = reader.ReadInt32(); if (dataLength <= 0) return; Data = reader.ReadBytes(dataLength); }
public ImageResource(BinaryReverseReader reader) { this.ID = reader.ReadUInt16(); this.Name = reader.ReadPascalString(); uint settingLength = reader.ReadUInt32(); this.Data = reader.ReadBytes((int)settingLength); if (reader.BaseStream.Position % 2 == 1) { reader.ReadByte(); } }
public Shadow(PhotoshopFile.Layer.AdjustmentLayerInfo info) { this.m_data = info.Data; this.m_key = info.Key; this.m_layer = info.Layer; BinaryReverseReader r = this.DataReader; //string blendModeSignature = null; int version = r.ReadInt32(); switch (version) { case 0: this.Blur = r.ReadUInt32(); this.Intensity = r.ReadUInt32(); this.Angle = r.ReadUInt32(); this.Distance = r.ReadUInt32(); this.Color = r.ReadPSDColor(16, true); this.BlendModeKey = this.ReadBlendKey(r); //this.BlendModeSignature = r.ReadUInt32(); //this.BlendModeKey = r.ReadUInt32(); this.Enabled = r.ReadBoolean(); this.UseGlobalAngle = r.ReadBoolean(); this.Opacity = r.ReadByte(); break; case 2: this.Blur = (uint)r.ReadUInt16(); this.Intensity = r.ReadUInt32(); this.Angle = r.ReadUInt32(); this.Distance = r.ReadUInt32(); ushort something = r.ReadUInt16(); //TODO:? this.Color = r.ReadPSDColor(16, true); this.BlendModeKey = this.ReadBlendKey(r); this.Enabled = r.ReadBoolean(); this.UseGlobalAngle = r.ReadBoolean(); this.Opacity = r.ReadByte(); //TODO: 10 unknown bytes! break; } this.Data = null; }
/// <summary> /// Initializes a new instance of the <see cref="BlendingRanges"/> class. /// </summary> /// <param name="reader">The reader containing the PSD file data</param> public BlendingRanges(BinaryReverseReader reader) { // read the data length int count = reader.ReadInt32(); if (count <= 0) { return; } // read the data reader.ReadBytes(count); }
private byte readByte(BinaryReverseReader stream) { if (useCachedByte) { Debug.Assert(cachedByte != -1); useCachedByte = false; return((byte)cachedByte); } else { cachedByte = stream.ReadByte(); return((byte)cachedByte); } }
public Bevel(PhotoshopFile.Layer.AdjustmentLayerInfo info) { this.m_data = info.Data; this.m_key = info.Key; this.m_layer = info.Layer; BinaryReverseReader r = this.DataReader; //string blendModeSignature = null; uint version = r.ReadUInt32(); switch (version) { case 0: this.Blur = r.ReadUInt32(); this.Data = null; break; case 2: this.Angle = (uint)r.ReadUInt16(); this.Strength = (uint)r.ReadUInt16(); this.Blur = (uint)r.ReadUInt16(); this.Unknown1 = r.ReadByte(); this.Unknown2 = r.ReadByte(); this.Unknown3 = r.ReadUInt16(); this.Unknown4 = r.ReadUInt16(); this.BlendModeKey = this.ReadBlendKey(r); this.ShadowBlendModeKey = this.ReadBlendKey(r); this.Color = r.ReadPSDColor(16, true); this.ShadowColor = r.ReadPSDColor(16, true); this.BevelStyle = r.ReadByte(); this.Opacity = r.ReadByte(); this.ShadowOpacity = r.ReadByte(); this.Enabled = r.ReadBoolean(); this.UseGlobalAngle = r.ReadBoolean(); this.Inverted = r.ReadBoolean(); System.Drawing.Color someColor = r.ReadPSDColor(16, true); System.Drawing.Color someColor2 = r.ReadPSDColor(16, true); break; } this.Data = null; }
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(); }
public void ReadPixels(BinaryReverseReader reader) { foreach (Channel ch in this._channels.Values) { if (ch.Usage != -2) { ch.ReadPixels(reader); } } if (this._mask != null) { this._mask.ReadPixels(reader); } }
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; }
public TdTaParser(BinaryReverseReader r) { this.r = r; }
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 } }
public TdTaParseException(string message, BinaryReverseReader r) : base(message + "\nMore data:" + new string(r.ReadChars((int)Math.Max(100, r.BytesToEnd)))) { }
//public static Bitmap ConvertToBitmap(byte[] pData, ) //{ //} public static byte[] ReadPixels(BinaryReverseReader reader, int width, int height, int bitsPerPixel, bool isMergedBitmap) { if (!isMergedBitmap) { //TODO: read mask data (always uncompressed) //reader.ReadBytes((int)maskChannel.Length); } short nCompression = reader.ReadInt16(); //int width = (int)psd.Header.Columns; //int height = (int)psd.Header.Rows; int bytesPerPixelPerChannel = bitsPerPixel / 8; // psd.Header.Depth / 8; if (bytesPerPixelPerChannel < 1) bytesPerPixelPerChannel = 1; //int nPixels = width * height; int bytesPerRow = width * bytesPerPixelPerChannel; int totalBytes = bytesPerRow * height; //int nTotalBytes = nPixels * bytesPerPixelPerChannel * psd.Header.Channels; byte[] pData = new byte[totalBytes]; try { switch (nCompression) { case 0: // uncompressed reader.Read(pData, 0, totalBytes); break; case 1: // rle compression // If it's NOT the FinalBitmap, the RLE-compressed data is proceeded by a 2-byte data count for each row in the data if (!isMergedBitmap) { int[] rowLenghtList = new int[height]; for (int i = 0; i < height; i++) rowLenghtList[i] = reader.ReadInt16(); } for (int i = 0; i < height; i++) { int offset = i * width; int numDecodedBytes = 0; while (numDecodedBytes < width) numDecodedBytes += RleCodec.DecodeChunk(reader.BaseStream, pData, offset + numDecodedBytes); } break; case 2: // ZIP without prediction throw (new Exception("ZIP without prediction, no specification")); case 3: // ZIP with prediction throw (new Exception("ZIP with prediction, no specification")); default: throw (new Exception("Unknown compression format: " + nCompression.ToString())); } } catch { } return pData; }
} //end Load() /// <summary> /// Loads up the Layers of the supplied PSD file /// </summary> private void LoadLayers(BinaryReverseReader reader) { Debug.WriteLine("LoadLayers started at " + reader.BaseStream.Position.ToString(CultureInfo.InvariantCulture)); UInt32 layersInfoSectionLength = reader.ReadUInt32(); if (layersInfoSectionLength <= 0) return; Int64 startPosition = reader.BaseStream.Position; Int16 numberOfLayers = reader.ReadInt16(); // If <0, then number of layers is absolute value, // and the first alpha channel contains the transparency data for // the merged result. if (numberOfLayers < 0) { AbsoluteAlpha = true; numberOfLayers = Math.Abs(numberOfLayers); } _layers.Clear(); if (numberOfLayers == 0) return; for (Int32 i = 0; i < numberOfLayers; i++) { _layers.Add(new Layer(reader, this)); } foreach (Layer layer in Layers) { foreach (Layer.Channel channel in layer.Channels.Where(c => c.ID != -2)) { channel.LoadPixelData(reader); } layer.MaskData.LoadPixelData(reader); } if (reader.BaseStream.Position % 2 == 1) reader.ReadByte(); // make sure we are not on a wrong offset, so set the stream position // manually reader.BaseStream.Position = startPosition + layersInfoSectionLength; }
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(); }
public string ReadBlendKey(BinaryReverseReader r) { string blendModeSignature = new string(r.ReadPSDChars(4)); return new string(r.ReadPSDChars(4)); }
/// <summary> /// Load up the masking information of the supplied PSD /// </summary> private void LoadGlobalLayerMask(BinaryReverseReader reader) { Debug.WriteLine("LoadGlobalLayerMask started at " + reader.BaseStream.Position.ToString(CultureInfo.InvariantCulture)); UInt32 maskLength = reader.ReadUInt32(); if (maskLength <= 0) return; _globalLayerMaskData = reader.ReadBytes((Int32)maskLength); }
internal void LoadPixelData(BinaryReverseReader reader) { Debug.WriteLine("Mask.LoadPixelData started at " + reader.BaseStream.Position.ToString(CultureInfo.InvariantCulture)); if (Rect.IsEmpty || Layer.SortedChannels.ContainsKey(-2) == false) return; Channel maskChannel = Layer.SortedChannels[-2]; maskChannel.Data = reader.ReadBytes(maskChannel.Length); using (BinaryReverseReader readerImg = maskChannel.DataReader) { maskChannel.ImageCompression = (ImageCompression)readerImg.ReadInt16(); int bytesPerRow = 0; switch (Layer.PsdFile.Depth) { case 1: bytesPerRow = Rect.Width;//NOT Shure break; case 8: bytesPerRow = Rect.Width; break; case 16: bytesPerRow = Rect.Width * 2; break; } maskChannel.ImageData = new byte[Rect.Height * bytesPerRow]; // Fill Array for (int i = 0; i < maskChannel.ImageData.Length; i++) { maskChannel.ImageData[i] = 0xAB; } ImageData = (byte[])maskChannel.ImageData.Clone(); switch (maskChannel.ImageCompression) { case ImageCompression.Raw: readerImg.Read(maskChannel.ImageData, 0, maskChannel.ImageData.Length); break; case ImageCompression.Rle: { int[] rowLenghtList = new int[Rect.Height]; for (int i = 0; i < rowLenghtList.Length; i++) rowLenghtList[i] = readerImg.ReadInt16(); for (int i = 0; i < Rect.Height; i++) { int rowIndex = i * Rect.Width; RleHelper.DecodedRow(readerImg.BaseStream, maskChannel.ImageData, rowIndex, bytesPerRow); } } break; } ImageData = (byte[])maskChannel.ImageData.Clone(); } }
internal void LoadPixelData(BinaryReverseReader reverseReader) { Debug.WriteLine("Channel.LoadPixelData started at " + reverseReader.BaseStream.Position.ToString(CultureInfo.InvariantCulture)); Data = reverseReader.ReadBytes(Length); using (BinaryReverseReader imageReader = DataReader) { ImageCompression = (ImageCompression)imageReader.ReadInt16(); Int32 bytesPerRow = 0; switch (Layer.PsdFile.Depth) { case 1: bytesPerRow = Layer.Rect.Width;//NOT sure break; case 8: bytesPerRow = Layer.Rect.Width; break; case 16: bytesPerRow = Layer.Rect.Width * 2; break; } ImageData = new Byte[Layer.Rect.Height * bytesPerRow]; switch (ImageCompression) { case ImageCompression.Raw: imageReader.Read(ImageData, 0, ImageData.Length); break; case ImageCompression.Rle: { Int32[] rowLengthList = new Int32[Layer.Rect.Height]; for (Int32 i = 0; i < rowLengthList.Length; i++) rowLengthList[i] = imageReader.ReadInt16(); for (Int32 i = 0; i < Layer.Rect.Height; i++) { Int32 rowIndex = i * Layer.Rect.Width; RleHelper.DecodedRow(imageReader.BaseStream, ImageData, rowIndex, bytesPerRow); //if (rowLenghtList[i] % 2 == 1) // readerImg.ReadByte(); } } break; } } }
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()
/// <summary> /// Reads bytes until a unescaped closing parenthesis in found. Unescapes escaped parenthesis. /// Leaves reader on the char following the closing parenthesis. /// </summary> /// <param name="r"></param> /// <returns></returns> public static byte[] parseBinary(BinaryReverseReader r) { MemoryStream ms = new MemoryStream(128); //For writing the decoded binary byte b = 0; byte lastb = 0; bool hasLastByte = false; //Read bytes, keeping a two-byte shifting buffer so we can decode escaped chars. while (r.CanReadByte()) { b = r.ReadByte(); //Look for closing parenthesis if ((char)b == ')') { if (hasLastByte && (char)lastb == '\\') { //Escaped parenthesis, skip slash lastb = 0; hasLastByte = false; } else { //Unescaped closing parenthesis! We hit the end! if (hasLastByte) ms.WriteByte(lastb); //If we still have a byte in the buffer. return ms.ToArray();//We hit the end, an unescaped closng parenthesis. } } //Far as I know, nothing else is escaped. //Write lastb if present. if (hasLastByte) ms.WriteByte(lastb); //Shift buffer lastb = b; hasLastByte = true; } throw new TdTaParseException("Hit end of stream without finding closing parenthesis!"); }
internal Mask(BinaryReverseReader reader, Layer layer) { Debug.WriteLine("Mask started at " + reader.BaseStream.Position.ToString(CultureInfo.InvariantCulture)); Layer = layer; uint maskLength = reader.ReadUInt32(); if (maskLength <= 0) return; long startPosition = reader.BaseStream.Position; Rectangle localRectangle = new Rectangle { Y = reader.ReadInt32(), X = reader.ReadInt32() }; localRectangle.Height = reader.ReadInt32() - localRectangle.Y; localRectangle.Width = reader.ReadInt32() - localRectangle.X; Rect = localRectangle; DefaultColor = reader.ReadByte(); byte flags = reader.ReadByte(); _flags = new BitVector32(flags); if (maskLength == 36) { #pragma warning disable 168 BitVector32 realFlags = new BitVector32(reader.ReadByte()); byte realUserMaskBackground = reader.ReadByte(); Rectangle rect = new Rectangle { Y = reader.ReadInt32(), X = reader.ReadInt32(), Height = reader.ReadInt32() - Rect.Y, Width = reader.ReadInt32() - Rect.X }; #pragma warning restore 168 } // there is other stuff following, but we will ignore this. reader.BaseStream.Position = startPosition + maskLength; }
public override Endogine.ColorEx.Palette Load(string filename) { Serialization.BinaryReverseReader reader = new BinaryReverseReader(new System.IO.FileStream(filename, System.IO.FileMode.Open)); //Serialization.BinaryReaderEx reader = new BinaryReaderEx(new System.IO.FileStream(filename, System.IO.FileMode.Open)); ushort version = reader.ReadUInt16(); ushort numColors = reader.ReadUInt16(); if (version > 2) { throw new Exception("Can't parse .ACO palettes with version > 2: "+filename); } Endogine.ColorEx.Palette palette = new Endogine.ColorEx.Palette(); for (int colorNum = 0; colorNum < numColors; colorNum++) { ushort colorSpaceId = reader.ReadUInt16(); ushort[] vals = new ushort[4]; for (int i = 0; i < 4; i++) vals[i] = reader.ReadUInt16(); string name = colorNum.ToString(); if (version == 2) { reader.ReadUInt16(); //padded int nameLength = reader.ReadUInt16(); if (reader.BaseStream.Position % 2 == 1) // ? reader.ReadUInt16(); //padded for (int letterNum = 0; letterNum < nameLength; letterNum++) { char c = (char)reader.ReadUInt16(); name+=c.ToString(); } } ColorEx.ColorBase color; //TODO; uses 16 bits per channel, but here I truncate it to 8 bits switch (colorSpaceId) { case 0: //RGB ColorEx.ColorRgb rgb = new Endogine.ColorEx.ColorRgb(); rgb.R = vals[0] / 256; rgb.G = vals[1] / 256; rgb.B = vals[2] / 256; color = rgb; break; case 1: //HSB ColorEx.ColorHsb hsb = new Endogine.ColorEx.ColorHsb(); hsb.H = (float)vals[0] / 182.04f; hsb.S = (float)vals[1] / 655.35f / 100f; hsb.B = (float)vals[2] / 655.35f / 100f; color = hsb; break; case 2: //CMYK ColorEx.ColorCmyk cmyk = new Endogine.ColorEx.ColorCmyk(); cmyk.C = (float)vals[0] / 256; cmyk.M = (float)vals[1] / 256; cmyk.Y = (float)vals[2] / 256; cmyk.K = (float)vals[3] / 256; color = cmyk; break; case 7: //Lab float[] ab = new float[2]; for (int i = 1; i < 3; i++) { if (vals[i] <= 12000) ab[i - 1] = (float)vals[i] / 100; else ab[i - 1] = (float)(65536 - vals[i]) / 100; } ColorEx.ColorLab lab = new Endogine.ColorEx.ColorLab(); lab.L = (float)vals[0]/100; lab.a = vals[1]; lab.b = vals[2]; //Angle:2, Observer:D65 color = lab; break; case 8: //Grayscale ColorEx.ColorRgb rgbGray = new Endogine.ColorEx.ColorRgb(); int gray = (int)((float)vals[0] / 39.0625f); rgbGray.R = gray; rgbGray.G = gray; rgbGray.B = gray; color = rgbGray; break; case 9: //Wide CMYK default: throw new Exception("Can't read colorspace "+colorSpaceId+" in "+filename); } palette.Add(name, color); } return palette; }
public void ReadPixels(BinaryReverseReader reader) { foreach (Channel ch in this._channels.Values) { if (ch.Usage != -2) ch.ReadPixels(reader); } if (this._mask != null) this._mask.ReadPixels(reader); }
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); }
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(); }
/// <summary> /// Parses tdta contents into tokens. Throws a generic exception if unrecognized tokens are encountered /// </summary> /// <param name="r"></param> /// <returns></returns> public static Token nextToken(BinaryReverseReader r) { if (!r.CanReadByte()) return null; char c = r.ReadChar(); switch (c) { case '(': return new Token(parseBinary(r)); //Binary data. Leading and trailing parens are stripped, and escaped parens are restored to normal. case '[': return new Token(TokenType.StartList, c.ToString()); // [ opening list char case ']': return new Token(TokenType.EndList, c.ToString()); //Closing list char } //<< opening dict //>> closing dict if (c == '<' || c == '>') { char c2 = r.ReadChar(); if (c2 != c) throw new TdTaParseException("Unrecognized token: " + c + c2,r); if (c == '<') return new Token(TokenType.StartDict, "<<"); else return new Token(TokenType.EndDict, ">>"); } //Dict key (Any non-whitespace, non-[]<> sequence allowed following forward slash) if (c == '/'){ StringBuilder sb = new StringBuilder(40); while (r.CanReadByte()){ //Peek at the next char to see if it is whitespace char pc = (char)r.PeekChar(); if (Char.IsWhiteSpace(pc) || pc == '\n' || pc=='[' || pc==']' || pc=='<' || pc=='>'){ //We're done. //Strip the leading slash, create token with name return new Token(TokenType.MapKey,sb.ToString()); }else{ //A valid char, append it. sb.Append(r.ReadChar()); } } } //Integer or double. Ends at whitespace, newline, ], or > if (Char.IsDigit(c) || c=='-' || c == '.'){ StringBuilder sb = new StringBuilder(40); sb.Append(c); while (r.CanReadByte()){ //Peek at the next char to see if it is whitespace char pc = (char)r.PeekChar(); if (Char.IsWhiteSpace(pc) || pc == '\n' || pc ==']' || pc =='>'){ //We're done. Find out what kind of number it is. string s = sb.ToString(); //If it has a decimal, it's a double if (s.Contains('.')){ return new Token(TokenType.Double,double.Parse(s, floatingPointStyle,NumberFormatInfo.InvariantInfo)); }else{ return new Token(TokenType.Integer,int.Parse(s,NumberStyles.Integer,NumberFormatInfo.InvariantInfo)); } }else if (Char.IsDigit(c) || c=='-' || c == '.'){ //A valid char, append it. sb.Append(r.ReadChar()); }else{ //Unrecognized char in numeric sq throw new TdTaParseException("Unrecognized character in numeric sequence: " + sb.ToString() + pc,r); } } } //Boolean (true|false) parsing if (c == 't' || c == 'T' || c == 'f' || c == 'F'){ string s = c.ToString() + r.ReadChar().ToString() + r.ReadChar().ToString() + r.ReadChar().ToString(); char pc = (char)r.PeekChar(); if (s.Equals("true", StringComparison.OrdinalIgnoreCase)){ return new Token(TokenType.Boolean,true); }else if (s.Equals("fals", StringComparison.OrdinalIgnoreCase) && (pc == 'e' || pc == 'E')){ r.ReadChar(); //discard 'e' return new Token(TokenType.Boolean,false); }else{ throw new TdTaParseException("Unrecognized boolean value: " + s + pc,r); } } //Whitespace parsing if (Char.IsWhiteSpace(c) || c == '\n'){ StringBuilder sb = new StringBuilder(40); sb.Append(c); while (r.CanReadByte()){ //Peek at the next char to see if it is whitespace char pc = (char)r.PeekChar(); if (Char.IsWhiteSpace(pc) || pc == '\n'){ sb.Append(r.ReadChar()); }else{ //We done. break; } } return new Token(TokenType.Whitespace,sb.ToString()); } throw new TdTaParseException("Unrecognized token: " + c,r); }