/// <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 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; //} }
public bool kind; // selected = false, protected = true public DisplayInfo(ImageResource imgRes) { BinaryReverseReader reader = imgRes.GetDataReader(); this.ColorSpace = (ColorModes)reader.ReadInt16(); for (int i = 0; i < 4; i++) { this.Color[i] = reader.ReadInt16(); } this.Opacity = (short)Math.Max(0, Math.Min(100, (int)reader.ReadInt16())); this.kind = reader.ReadByte() == 0?false:true; reader.Close(); }
public Channel(BinaryReverseReader reader, Layer layer) { this._usage = reader.ReadInt16(); this._length = (long)reader.ReadUInt32(); this._layer = layer; }
public ResolutionInfo(ImageResource imgRes) : base(imgRes) { //文档 四 - 1 ID 1005 BinaryReverseReader dataReader = imgRes.DataReader; //这里解析是错的, 但解的字节数没错,反正这些数据没用,就没修改了,要用的时候参考文档修改 dataReader.ReadInt16(); dataReader.ReadInt32(); dataReader.ReadInt16(); dataReader.ReadInt16(); dataReader.ReadInt32(); dataReader.ReadInt16(); dataReader.Close(); }
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 Thumbnail(ImageResource imgRes) { BinaryReverseReader reader = imgRes.GetDataReader(); //m_bThumbnailFilled = true; this.nFormat = reader.ReadInt32(); this.nWidth = reader.ReadInt32(); this.nHeight = reader.ReadInt32(); this.nWidthBytes = reader.ReadInt32(); this.nSize = reader.ReadInt32(); this.nCompressedSize = reader.ReadInt32(); this.nBitPerPixel = reader.ReadInt16(); this.nPlanes = reader.ReadInt16(); int nTotalData = this.nSize - 28; // header byte [] buffer = new byte[nTotalData]; if (this.ID == 1033) { // BGR for (int n = 0; n < nTotalData; n = n + 3) { buffer[n + 2] = reader.ReadByte(); buffer[n + 1] = reader.ReadByte(); buffer[n + 0] = reader.ReadByte(); } } else if (this.ID == 1036) { // RGB for (int n = 0; n < nTotalData; ++n) { buffer[n] = reader.ReadByte(); } } reader.Close(); }
//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; }
//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); }
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 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(); }
} //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 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()
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(); }
private short readShort(BinaryReverseReader stream) { cachedByte = -1; useCachedByte = false; return(stream.ReadInt16()); }