예제 #1
0
		public static PCXHEADER LoadFromStream(Stream stream)
		{
			PCXHEADER header = new PCXHEADER ();
			if (stream == null) {
				return header;
			}
			var mgr = FilePathMgr.GetInstance ();
			header.Manufacturer = (byte)stream.ReadByte ();
			header.Version = (byte)stream.ReadByte ();
			header.Encoding = (byte)stream.ReadByte ();
			header.BPP = (byte)stream.ReadByte ();
			header.x = (ushort)mgr.ReadShort (stream);
			header.y = (ushort)mgr.ReadShort (stream);
			header.widht = (ushort)mgr.ReadShort (stream);
			header.height = (ushort)mgr.ReadShort (stream);
			header.HRES = (ushort)mgr.ReadShort (stream);
			header.VRES = (ushort)mgr.ReadShort (stream);
			header.ColorMap = mgr.ReadString (stream, 48, System.Text.Encoding.ASCII);
			header.reserved1 = (byte)stream.ReadByte ();
			header.NPlanes = (byte)stream.ReadByte ();
			header.bytesPerLine = (byte)stream.ReadByte ();
			header.palletInfo = (byte)stream.ReadByte ();
			header.HorzScreenSize = (ushort)mgr.ReadShort (stream);
			header.VertScreenSize = (ushort)mgr.ReadShort (stream);
			header.Reserved2 = mgr.ReadString(stream, 54, System.Text.Encoding.ASCII);
			return header;
		}
예제 #2
0
		private void LoadPCXLine8(PCXHEADER header, Stream stream, ref byte[] lineBuffer)
		{
			int _LineWidth = header.bytesPerLine;
			if (lineBuffer == null || lineBuffer.Length < _LineWidth)
				lineBuffer = new byte[_LineWidth];
			int _ReadIndex = 0;
			while (true)
			{
				//判断行扫描结束返回码  
				if (stream.Position + 1 >= stream.Length)
					break;

				byte _Data = (byte)stream.ReadByte();
                if (_Data > 0xC0)
				{
                    int _Count = _Data - 0xC0;
					byte sameData = 0;
					for (int i = 0; i != _Count; ++i)
					{
						if (i == 0) {
							sameData = (byte)stream.ReadByte ();
						}
                        if (_ReadIndex >= _LineWidth)
							break;
                        lineBuffer[_ReadIndex] = sameData;
                        ++_ReadIndex;
					}
				}
				else
				{
					lineBuffer[_ReadIndex] = _Data;
					++_ReadIndex;
				}
				if (_ReadIndex >= _LineWidth) break;
			}
		}
예제 #3
0
        private bool LoadPcx2(int offset, SFFSUBHEADER subHeader, byte[] source, ref Stream stream, out KeyValuePair<PCXHEADER, PCXDATA> dataPair)
        {
            if ((offset < 0) || (offset >= source.Length))
            {
                dataPair = new KeyValuePair<PCXHEADER, PCXDATA>();
                return false;
            }
            /*
            if (source[offset] != 0x0A)
            {
                dataPair = new KeyValuePair<PCXHEADER, PCXDATA>();
               // return false;
            }
            */

            if (stream == null)
                stream = new MemoryStream(source);
            try
            {
                stream.Seek(offset, SeekOrigin.Begin);

                PCXHEADER header = PCXHEADER.LoadFromStream(stream);

                if (header.BPP == 0)
                {
                    dataPair = new KeyValuePair<PCXHEADER, PCXDATA>();
                    return true;
                }

                header.widht = (ushort)(header.widht - header.x + 1);
                header.height = (ushort)(header.height - header.y + 1);
                //	byte[] ret = new byte[header.widht * header.NPlanes * header.height];
                byte[] ret = null;
                byte[] lineBuffer = null;
                for (int i = 0; i < (int)header.height; ++i)
                {
                    switch (header.NPlanes)
                    {
                        // 24位
                        case 3:
                            LoadPCXLine24(header, stream, ref lineBuffer);
                            break;
                        // 256色
                        case 1:
                            LoadPCXLine8(header, stream, ref lineBuffer);
                            break;
                        default:
                            dataPair = new KeyValuePair<PCXHEADER, PCXDATA>();
                            return false;
                    }

                    if (lineBuffer != null && lineBuffer.Length > 0)
                    {
                         int lineSize = header.NPlanes * header.widht;
                        if (ret == null)
                        {
                           // ret = new byte[header.widht * header.NPlanes * header.height];
                            ret = new byte[lineSize * header.height];
                        }

                        Buffer.BlockCopy(lineBuffer, 0, ret, i * lineSize, lineSize);
                    }
                }

                // H changed
                int chgSize = header.NPlanes * header.widht;
                byte[] temp = null;
                if (lineBuffer != null && lineBuffer.Length >= chgSize)
                    temp = lineBuffer;
                else
                {
                    lineBuffer = null;
                    temp = new byte[chgSize];
                }
                for (int y = 0; y < (int)header.height / 2; ++y)
                {
                    int x = ((int)header.height - 1 - y);
                    int s = y * chgSize;
                    int d = x * chgSize;
                    Buffer.BlockCopy(ret, d, temp, 0, chgSize);
                    Buffer.BlockCopy(ret, s, ret, d, chgSize);
                    Buffer.BlockCopy(temp, 0, ret, s, chgSize);
                }

                // 读取调色版
                PCXDATA pcxData = new PCXDATA();
                pcxData.data = ret;
                pcxData.pallet = null;

                if (!subHeader.PalletSame && !HasNormalPallet && header.NPlanes <= 1)
                {
                    // 判断是不是9000,1
                    if (subHeader.GroubNumber == 9000 && subHeader.ImageNumber == 1)
                    {
                        pcxData.palletLink = m_currentLink;
                    }
                    else
                    {
                        if (stream.Position + 256 * 3 <= stream.Length)
                        {
                            pcxData.pallet = new Color32[256];
                            for (int i = 0; i != 256; ++i)
                            {
                                byte r = (byte)stream.ReadByte();
                                byte g = (byte)stream.ReadByte();
                                byte b = (byte)stream.ReadByte();

                                byte a;
                                if (i == 0)
                                    a = 0;
                                else
                                {
                                    if ((r == pcxData.pallet[i - 1].r) && (g == pcxData.pallet[i - 1].g) && (b == pcxData.pallet[i - 1].b))
                                        a = 0;
                                    else
                                        a = 0xFF;
                                }

                                pcxData.pallet[i] = new Color32(r, g, b, a);
                            }
                            m_currentLink = new KeyValuePair<short, short>(subHeader.GroubNumber, subHeader.ImageNumber);
                        }
                    }
                }
                else
                {
                    pcxData.palletLink = m_currentLink;
                }

                dataPair = new KeyValuePair<PCXHEADER, PCXDATA>(header, pcxData);

            }
            catch (Exception e)
            {
                Debug.LogError(e.Message);
                dataPair = new KeyValuePair<PCXHEADER, PCXDATA>();
                return false;
            }
            return true;
        }
예제 #4
0
		private void LoadPCXLine24(PCXHEADER header, Stream stream, ref byte[] lineBuffer)
		{
			Debug.LogError ("Call function LoadPCXLine24");
		}
예제 #5
0
		private byte[] DecodePcxData(int offset, PCXHEADER header, byte[] source)
		{
			byte[] ret = null;

			if ((offset < 0) || (offset >= source.Length))
				return ret;

			//int nTotalyByte = (int)(header.bytesPerLine * header.NPlanes);
			int bpp = (int)(header.NPlanes * 8);
			if (bpp > 8)
				return ret; // not support

			try
			{
			int width = header.widht;
			if (width < header.bytesPerLine * header.NPlanes)
				width = header.bytesPerLine * header.NPlanes;

			int size = 0;
			int Pos = 0;
			//ret = new byte[header.widht * header.NPlanes * header.height + 1];
            ret = new byte[header.widht * header.NPlanes * header.height];
            bool isEnd = false;
			for (int y = 0; y < header.height; ++y)
			{
                if (isEnd)
                    break;

				int x = 0;
				while (x < width)
				{
                    int idx = offset + Pos++;
                    if (idx >= source.Length)
                    {
                        isEnd = true;
                        break;
                    }
                    byte byData = source[idx];
					if ((byData & 0xC0) == 0xC0)
					{
						size = byData & 0x3F;
                        idx = offset + Pos++;
                        if (idx >= source.Length)
                        {
                            isEnd = true;
                            break;
                        }
                        byData = source[idx];
					} else
					{
						size = 1;
					}

					while (size-- > 0)
					{
                        if (x <= header.widht)
                        {
                            idx = x + (y * header.widht * header.NPlanes);
                            if (idx >= ret.Length)
                                break;
                            ret[idx] = byData;
                        }
						//this it to Skip blank data on PCX image wich are on the right side
						// TODO:OK? Skip two bytes
						if ((x == width) && (width != header.widht))
						{
							int nHowManyBlank = width - (int)header.widht;
							for (int i = 0; i < nHowManyBlank; ++i)
								Pos += 2;
						}


						x++;
					}
				}
			}

				// H changed
				byte[] temp = new byte[header.widht];
                int lineSize = header.widht * header.NPlanes;
				for (int y = 0; y < (int)header.height/2; ++y)
				{
					int x = ((int)header.height - 1 - y);
                    int s = y * lineSize;
                    int d = x * lineSize;
                    Buffer.BlockCopy(ret, d, temp, 0, lineSize);
                    Buffer.BlockCopy(ret, s, ret, d, lineSize);
                    Buffer.BlockCopy(temp, 0, ret, s, lineSize);
				}
			} catch(Exception e)
			{
				Debug.LogError(e.Message);
				return null;
			}



			return ret;
		}
예제 #6
0
		private bool LoadPcx(int offset, SFFSUBHEADER subHeader, byte[] source, out KeyValuePair<PCXHEADER, PCXDATA> dataPair)
		{
			if ((offset < 0) || (offset >= source.Length))
			{
				dataPair = new KeyValuePair<PCXHEADER, PCXDATA>();
				return false;
			}

			PCXHEADER header = new PCXHEADER();
			int bufSize = Marshal.SizeOf(header);
			if (offset + bufSize > source.Length)
			{
				dataPair = new KeyValuePair<PCXHEADER, PCXDATA>();
				return false;
			}
			IntPtr buf = Marshal.AllocHGlobal(bufSize);
			try
			{
				Marshal.Copy(source, offset, buf, bufSize);
				header = (PCXHEADER)Marshal.PtrToStructure(buf, typeof(PCXHEADER));
			} finally
			{
				Marshal.FreeHGlobal(buf);
			}

			if (header.BPP == 0)
			{
				dataPair = new KeyValuePair<PCXHEADER, PCXDATA>();
				return true;
			}

			offset += bufSize;

			int pcxBufSz = (int)subHeader.LenghtOfSubheader - 127;
			if (pcxBufSz <= 0)
			{
				dataPair = new KeyValuePair<PCXHEADER, PCXDATA>();
				return true;
			}

			if (offset + pcxBufSz > source.Length)
			{
				dataPair = new KeyValuePair<PCXHEADER, PCXDATA>();
				return true;
			}
			byte[] pcxBuf = new byte[pcxBufSz];
			Buffer.BlockCopy(source, offset, pcxBuf, 0, pcxBufSz); 
			offset += pcxBufSz;

			if (offset >= source.Length)
			{
				dataPair = new KeyValuePair<PCXHEADER, PCXDATA>();
				return false;
			}

			header.widht = (ushort)(header.widht - header.x + 1);
			header.height = (ushort)(header.height - header.y + 1);

			//byte[] dst = DecodePcxData(offset, header, pcxBuf);
			byte[] dst = DecodePcxData(0, header, pcxBuf);
			pcxBuf = null;
			if ((dst == null) || (dst.Length <= 0))
			{
				// empty
				dataPair = new KeyValuePair<PCXHEADER, PCXDATA>();
				return true;
			}


			PCXDATA pcxData = new PCXDATA();
			pcxData.data = dst;
			pcxData.pallet = null;

			// 判断是不是9000,1
		//	if (subHeader.GroubNumber == 9000 && subHeader.ImageNumber == 1) {
			//	pcxData.palletLink = m_currentLink;
			/*} else*/ {
				offset -= 768;
				//eat empty 8bit
				offset++;

				byte s = source [offset++];
				if ((s == 12) && !subHeader.PalletSame && !HasNormalPallet && header.NPlanes <= 1) 
 {           // if (!subHeader.PalletSame && !HasNormalPallet && header.NPlanes <= 1)
					// load pallet
					pcxData.pallet = new Color32[256];
					for (int i = 0; i < 256; ++i) {
						byte r = source [offset++];
						byte g = source [offset++];
						byte b = source [offset++];
						byte a;
						if (i == 0)
							a = 0;
						else {
							if ((r == pcxData.pallet [i - 1].r) && (g == pcxData.pallet [i - 1].g) && (b == pcxData.pallet [i - 1].b))
								a = 0;
							else
								a = 0xFF;
						}
						pcxData.pallet [i] = new Color32 (r, g, b, a);
					}
					m_currentLink = new KeyValuePair<short, short> (subHeader.GroubNumber, subHeader.ImageNumber);
				} else
					pcxData.palletLink = m_currentLink;
			}

			dataPair = new KeyValuePair<PCXHEADER, PCXDATA>(header, pcxData);

			return true;
		}
예제 #7
0
		private void OnSffReaderV2(sff.sffReader reader, sff.sprMsgV2 spr, int linkGoup, int linkIndex, int linkPalGroup, int linkPalIndex, byte[] rawData)
		{
			bool isImageLink = linkGoup >= 0 && linkIndex >= 0;
			if (!isImageLink) {

				KeyValuePair<uint, uint> key = new KeyValuePair<uint, uint>((uint)spr.group, (uint)spr.index);
				if (mPcxDataMap.ContainsKey(key))
					return;

				PCXHEADER header = new PCXHEADER ();
				header.widht = spr.width;
				header.height = spr.height;
				//	header.x = (ushort)spr.x;
				//header.y = (ushort)spr.y;
				header.x = 0;
				header.y = 0;
				header.NPlanes = 1;

				if (rawData != null && rawData.Length > 0) {
					int chgSize = header.NPlanes * header.widht;
					byte[] temp = null;
					if (m_lineBuffer != null && m_lineBuffer.Length >= chgSize)
						temp = m_lineBuffer;
					else {
						temp = new byte[chgSize];
						m_lineBuffer = temp;
					}
					for (int y = 0; y < (int)header.height / 2; ++y) {
						int x = ((int)header.height - 1 - y);
						int s = y * chgSize;
						int d = x * chgSize;
						Buffer.BlockCopy (rawData, d, temp, 0, chgSize);
						Buffer.BlockCopy (rawData, s, rawData, d, chgSize);
						Buffer.BlockCopy (temp, 0, rawData, s, chgSize);
					}
				}

				PCXDATA data = new PCXDATA ();
				data.data = rawData;
				bool isPalletLink = (linkPalGroup >= 0 && linkPalIndex >= 0) && ((linkPalGroup != spr.group) || (linkPalIndex != spr.index));
				if (!isPalletLink) {
					byte[] pal = reader.GetPal (spr.group, spr.index);
					//data.pallet = GetPalletFromByteArr (pal);
					data.pallet = pal;
					data.palletLink = new KeyValuePair<short, short> (-1, -1);
				} else {
					data.palletLink = new KeyValuePair<short, short> ((short)linkPalGroup, (short)linkPalIndex);
					data.pallet = null;
				}

				KeyValuePair<PCXHEADER, PCXDATA> value = new KeyValuePair<PCXHEADER, PCXDATA> (header, data);
				mPcxDataMap.Add (key, value);
			}


			SFFSUBHEADER subHeader = new SFFSUBHEADER ();
			subHeader.GroubNumber = (short)spr.group;
			subHeader.ImageNumber = (short)spr.index;
			subHeader.x = spr.x;
			subHeader.y = spr.y;

			if (isImageLink) {
				subHeader.IndexOfPrevious = (short)GetSubHeaderIndex (linkGoup, linkIndex);
				subHeader.LenghtOfSubheader = 0;
			} else {
				subHeader.IndexOfPrevious = -1;
			}

			SubHeaders.Add(subHeader);
		}