// Get bitmap data by BmpNo private Color32[] GetBitmapByBmpNo(int bmpno, AdrnData adrnBlock) { if (adrnBlock.BitmapNo != bmpno) { Debug.Log("Error loading adrnData, could be resulted from errors in bin loading"); return(null); } if (fsReal == null) { fsReal = File.OpenRead(Application.dataPath + Consts.REAL); } if (fsReal == null) { Debug.Log("Error opening real.bin"); return(null); } fsReal.Seek((long)adrnBlock.Address, SeekOrigin.Begin); Stream realOut = new MemoryStream(); RealHeader rhOut = new RealHeader(); if (Decode(fsReal, out realOut, out rhOut) == true) { realOut.Seek(0, SeekOrigin.Begin); Color32[] colors = new Color32[realOut.Length]; for (int i = 0; i < realOut.Length; i++) { int colorindex = realOut.ReadByte(); if (colorindex < 0 || colorindex > 255) { return(null); } colors[i].a = activePalette[colorindex].a; colors[i].r = activePalette[colorindex].r; colors[i].g = activePalette[colorindex].g; colors[i].b = activePalette[colorindex].b; } return(colors); } else { Debug.Log("Error while decoding from stream"); return(null); } }
// Decode input to bitmap data private bool Decode(Stream input, out Stream output, out RealHeader header) { output = new MemoryStream(); byte[] bufferHeader = new byte[16]; input.Read(bufferHeader, 0, bufferHeader.Length); header = new RealHeader(); header = ByteToStruct <RealHeader>(bufferHeader); if (!string.Equals("RD", System.Text.Encoding.Default.GetString(System.BitConverter.GetBytes(header.ID)))) { output = null; return(false); } byte[] bufferInput = new byte[header.Size - bufferHeader.Length]; int bytesread = input.Read(bufferInput, 0, header.Size - bufferHeader.Length); // 未壓縮圖像數據大小尚未明朗 if (header.CompressFlag == 0) { Debug.Log("Warning: Uncompressed image data detected!"); output.Seek(0, SeekOrigin.Begin); output.Write(bufferInput, 0, bytesread); return(true); } int indexInput = 0; byte idx; byte repData; int cnt; output.Seek(0, SeekOrigin.Begin); while (indexInput < bufferInput.Length) { idx = bufferInput[indexInput++]; if ((idx & Consts.BIT_CMP) != 0) { if ((idx & Consts.BIT_ZERO) != 0) { repData = 0; } else { repData = bufferInput[indexInput++]; } if ((idx & Consts.BIT_REP_LARG2) != 0) { cnt = ((idx & 0x0f) << 16); cnt |= ((bufferInput[indexInput]) << 8); indexInput++; cnt |= bufferInput[indexInput++]; } else if ((idx & Consts.BIT_REP_LARG) != 0) { cnt = ((idx & 0x0f) << 8); cnt |= bufferInput[indexInput++]; } else { cnt = (idx & 0x0f); } for (int i = 0; i < cnt && output.CanWrite; i++) { output.WriteByte(repData); } } else { if ((idx & Consts.BIT_REP_LARG) != 0) { cnt = ((idx & 0x0f) << 8); cnt |= bufferInput[indexInput++]; } else { cnt = (idx & 0x0f); } if (cnt >= 0xfffff) { return(false); } for (int i = 0; i < cnt && output.CanWrite; i++) // TODO 長度限制待測試 { output.WriteByte(bufferInput[indexInput++]); } } } return(true); }