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; }
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; } }
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; }
private void LoadPCXLine24(PCXHEADER header, Stream stream, ref byte[] lineBuffer) { Debug.LogError ("Call function LoadPCXLine24"); }
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; }
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; }
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); }