public bool GetPcxData(uint group, uint image, out PCXDATA data) { KeyValuePair<PCXHEADER, PCXDATA> pair; if (!GetPcxData(group, image, out pair)) { data = new PCXDATA(); return false; } data = pair.Value; return true; }
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 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); }