Created
September 2, 2025 10:33
-
-
Save ogarvey/b1e72672dca0611b3d40cf5ee2456897 to your computer and use it in GitHub Desktop.
I.M Meen/Chill Manor Cmp Decoding Method
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public static Image<Rgba32> DecodeCmp(byte[] cmpData, byte[] originalPalette) | |
| { | |
| var width = BitConverter.ToUInt16(cmpData.Take(2).ToArray(), 0); | |
| var height = BitConverter.ToUInt16(cmpData.Skip(2).Take(2).ToArray(), 0); | |
| var firstNonTransparentRow = BitConverter.ToUInt16(cmpData.Skip(4).Take(2).ToArray(), 0); | |
| var lastNonTransparentRow = BitConverter.ToUInt16(cmpData.Skip(6).Take(2).ToArray(), 0); | |
| var firstNonTransparentColumn = BitConverter.ToUInt16(cmpData.Skip(8).Take(2).ToArray(), 0); | |
| var lastNonTransparentColumn = BitConverter.ToUInt16(cmpData.Skip(0xa).Take(2).ToArray(), 0); | |
| var colourCount = cmpData[0xc]; | |
| var colourBytes = cmpData.Skip(0xd).Take(colourCount).ToArray(); | |
| var cmpPaletteBytes = new byte[colourCount * 3]; | |
| for (int i = 0; i < colourCount; i++) | |
| { | |
| var colour = colourBytes[i]; | |
| var palIndex = colour * 3; | |
| cmpPaletteBytes[i * 3] = originalPalette[palIndex]; | |
| cmpPaletteBytes[i * 3 + 1] = originalPalette[palIndex + 1]; | |
| cmpPaletteBytes[i * 3 + 2] = originalPalette[palIndex + 2]; | |
| } | |
| var offsetDataOffset = 0xd + colourCount; | |
| var offsetList = new List<ushort>(); | |
| var offsetData = cmpData.Skip(offsetDataOffset).ToArray(); | |
| var offset = BitConverter.ToUInt16(offsetData.Take(2).ToArray(), 0); | |
| offsetList.Add(offset); | |
| var currentPos = offsetDataOffset + 2; | |
| while (currentPos < offsetList[0]) | |
| { | |
| offset = BitConverter.ToUInt16(cmpData.Skip(currentPos).Take(2).ToArray(), 0); | |
| offsetList.Add(offset); | |
| currentPos += 2; | |
| } | |
| var imageDataLines = new List<byte[]>(); | |
| for (int i = 0; i < offsetList.Count; i++) | |
| { | |
| var start = offsetList[i]; | |
| var end = i == offsetList.Count - 1 ? cmpData.Length : offsetList[i + 1]; | |
| var line = cmpData.Skip(start).Take(end - start).ToArray(); | |
| imageDataLines.Add(line); | |
| } | |
| var imageLines = new List<byte[]>(); | |
| if (firstNonTransparentRow > 0) | |
| { | |
| for (int i = 0; i < firstNonTransparentRow; i++) | |
| { | |
| var lineData = Enumerable.Repeat((byte)0x0, width).ToArray(); | |
| imageLines.Add(lineData); | |
| } | |
| } | |
| foreach (var line in imageDataLines) | |
| { | |
| var lineData = new byte[width]; | |
| var lineIndex = 0; | |
| for (int i = 0; i < line.Length; i++) | |
| { | |
| if (lineIndex >= lineData.Length - 1) | |
| { | |
| break; | |
| } | |
| var b = line[i]; | |
| if ((b & 0x80) == 0x80) | |
| { | |
| var count = b & 0x7F; | |
| for (int j = 0; j < count && lineIndex < lineData.Length; j++) | |
| { | |
| lineData[lineIndex] = 0x0; | |
| lineIndex++; | |
| } | |
| } | |
| else | |
| { | |
| lineData[lineIndex] = b; | |
| lineIndex++; | |
| } | |
| } | |
| imageLines.Add(lineData); | |
| } | |
| if (lastNonTransparentRow < height - 1) | |
| { | |
| for (int i = lastNonTransparentRow; i < height - 1; i++) | |
| { | |
| var lineData = Enumerable.Repeat((byte)0x0, width).ToArray(); | |
| imageLines.Add(lineData); | |
| } | |
| } | |
| var imageData = imageLines.SelectMany(x => x).ToArray(); | |
| var image = new Image<Rgba32>(width, height); | |
| for (int y = 0; y < height; y++) | |
| { | |
| for (int x = 0; x < width; x++) | |
| { | |
| var i = y * width + x; | |
| var paletteIndex = imageData[i]; | |
| Color color; | |
| if (paletteIndex < cmpPaletteBytes.Length / 3) | |
| { | |
| color = Color.FromRgb(cmpPaletteBytes[paletteIndex * 3], cmpPaletteBytes[paletteIndex * 3 + 1], cmpPaletteBytes[paletteIndex * 3 + 2]); | |
| } | |
| else | |
| { | |
| color = Color.Transparent; | |
| } | |
| image[x, y] = color; | |
| } | |
| } | |
| return image; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment