// BCLIM Data Writing internal static int Write16BitColorPalette(Bitmap img, ref MemoryStream ms) { using (Stream pixelcolors = new MemoryStream()) using (BinaryWriter bz = new BinaryWriter(pixelcolors)) { // Set up our basis. bool under16Colors = false; int colors = Bclim.GetColorCount(img); Color[] pcs = new Color[colors]; if (colors < 16) { under16Colors = true; } uint div = 1; if (under16Colors) { div = 2; } if (colors > 70) { throw new Exception("Too many colors"); } // Set up a new reverse image to build into. int w = Bclim.Gcm(img.Width, 8); int h = Bclim.Gcm(img.Height, 8); w = Math.Max(Bclim.Nlpo2(w), Bclim.Nlpo2(h)); h = w; byte[] pixelarray = new byte[w * h]; const int colorformat = 2; int ctr = 1; pcs[0] = Color.FromArgb(0, 0xFF, 0xFF, 0xFF); int p = Bclim.Gcm(w, 8) / 8; if (p == 0) { p = 1; } int d = 0; for (uint i = 0; i < pixelarray.Length; i++) { d = (int)(i / div); // Get Tile Coordinate Bclim.D2Xy(i % 64, out uint x, out uint y); // Get Shift Tile uint tile = i / 64; // Shift Tile Coordinate into Tilemap x += (uint)(tile % p) * 8; y += (uint)(tile / p) * 8; if (x >= img.Width || y >= img.Height) // Don't try to access any pixel data outside of our bounds. { i++; continue; } // Goto next tile. // Get Color of Pixel Color c = img.GetPixel((int)x, (int)y); // Color Table Building Logic int index = Array.IndexOf(pcs, c); if (c.A == 0) { index = 0; } if (index < 0) // If new color { pcs[ctr] = c; index = ctr; ctr++; } // Add it to color list // Add pixel to pixeldata if (under16Colors) { index = index << 4; } pixelarray[i / div] = (byte)index; if (!under16Colors) { continue; } c = img.GetPixel((int)x + 1, (int)y); index = Array.IndexOf(pcs, c); if (c.A == 0) { index = 0; } if (index < 0) // If new color { pcs[ctr] = c; index = ctr; ctr++; } pixelarray[i / div] |= (byte)index; i++; } // Write Intro bz.Write((ushort)colorformat); bz.Write((ushort)ctr); // Write Colors for (int i = 0; i < ctr; i++) { bz.Write(Bclim.GetRgba5551(pcs[i])); // Write byte array. } // Write Pixel Data for (uint i = 0; i < d; i++) { bz.Write(pixelarray[i]); } // Write Padding while (pixelcolors.Length < Bclim.Nlpo2((int)pixelcolors.Length)) { bz.Write((byte)0); } // Copy to main CLIM. pixelcolors.Position = 0; pixelcolors.CopyTo(ms); } return(7); }