public static void ApplyPalette(GR.Image.IImage Image, Palette Palette) { for (int i = 0; i < Palette.NumColors; ++i) { Image.SetPaletteColor(i, (byte)((Palette.ColorValues[i] & 0x00ff0000) >> 16), (byte)((Palette.ColorValues[i] & 0x0000ff00) >> 8), (byte)(Palette.ColorValues[i] & 0xff)); } }
public static void ApplyPalette(GR.Image.IImage Image) { ApplyPalette(Image, ConstantData.Palette); }
public void DrawTo(GR.Image.IImage TargetImage, int X, int Y, int SourceX, int SourceY, int DrawWidth, int DrawHeight) { // clip to source if ((SourceX >= Width) || (SourceX + DrawWidth < 0) || (SourceY >= Height) || (SourceY + DrawHeight < 0)) { return; } if (SourceX + DrawWidth > Width) { DrawWidth = Width - SourceX; } if (SourceX < 0) { DrawWidth += SourceX; X += SourceX; SourceX = 0; } if (SourceY + DrawHeight > Height) { DrawHeight = Height - SourceY; } if (SourceY < 0) { DrawHeight += SourceY; Y += SourceY; SourceY = 0; } int copyWidth = DrawWidth; int copyHeight = DrawHeight; // clip to target if ((X >= TargetImage.Width) || (Y >= TargetImage.Height) || (X + copyWidth < 0) || (Y + copyHeight < 0)) { return; } if (X < 0) { SourceX -= X; copyWidth += X; X = 0; } if (X + copyWidth >= TargetImage.Width) { copyWidth = TargetImage.Width - X; } if (Y < 0) { SourceY -= Y; copyHeight += Y; Y = 0; } if (Y + copyHeight >= TargetImage.Height) { copyHeight = TargetImage.Height - Y; } if ((TargetImage.PixelFormat == PixelFormat) && (BitsPerPixel >= 8)) { unsafe { byte *pTargetPos = (byte *)TargetImage.PinData(); pTargetPos += TargetImage.BytesPerLine * Y + X * TargetImage.BitsPerPixel / 8; byte *pSourcePos = (byte *)PinData(); pSourcePos += BytesPerLine * SourceY + SourceX * BitsPerPixel / 8; for (int y = 0; y < copyHeight; ++y) { CopyMemory(new IntPtr(pTargetPos), new IntPtr(pSourcePos), (uint)(copyWidth * BitsPerPixel / 8)); pTargetPos += TargetImage.BytesPerLine; pSourcePos += BytesPerLine; } TargetImage.UnpinData(); UnpinData(); } } else { // safe (but slow) copy for (int i = 0; i < copyWidth; ++i) { for (int j = 0; j < copyHeight; ++j) { TargetImage.SetPixel(X + i, Y + j, GetPixel(SourceX + i, SourceY + j)); } } } }
bool Classification(CubeInfo cube_info, GR.Image.IImage Image) { double bisect, mid_red, mid_green, mid_blue; int count; NodeInfo node_info; double blue, green, red; uint index, level, id; for (int y = 0; y < Image.Height; ++y) { if (cube_info.nodes > MaxNodes) { // Prune one level if the color tree is too large. PruneLevel(cube_info, cube_info.root); --cube_info.depth; } for (int x = 0; x < Image.Width; x += count) { // Start at the root and descend the color cube tree. count = 1; index = MaxTreeDepth - 1; bisect = (MaxRGB() + 1) / 2.0; mid_red = MaxRGB() / 2.0; mid_green = MaxRGB() / 2.0; mid_blue = MaxRGB() / 2.0; node_info = cube_info.root; uint pixel = Image.GetPixel(x, y); int r = (int)((pixel & 0xff0000) >> 16); int g = (int)((pixel & 0xff00) >> 8); int b = (int)(pixel & 0xff); for (level = 1; level <= cube_info.depth; level++) { bisect *= 0.5; id = (uint)(((Downscale(r) >> (byte)index) & 0x01) << 2 | ((Downscale(g) >> (byte)index) & 0x01) << 1 | ((Downscale(b) >> (byte)index) & 0x01)); mid_red += (id & 4) != 0 ? bisect : -bisect; mid_green += (id & 2) != 0 ? bisect : -bisect; mid_blue += (id & 1) != 0 ? bisect : -bisect; if (node_info.child[id] == null) { // Set colors of new node to contain pixel. node_info.census |= (byte)(1 << (byte)id); node_info.child[id] = GetNodeInfo(cube_info, (byte)id, (byte)level, node_info); if (node_info.child[id] == null) { Debug.Log("this should never happen!"); } if (level == cube_info.depth) { ++cube_info.colors; } } // Approximate the quantization error represented by this node. node_info = node_info.child[id]; red = (double)r - mid_red; green = (double)g - mid_green; blue = (double)b - mid_blue; node_info.quantize_error += count * red * red + count * green * green + count * blue * blue; cube_info.root.quantize_error += node_info.quantize_error; --index; } // Sum RGB for this leaf for later derivation of the mean cube color. node_info.number_unique += count; node_info.total_red += count * r; node_info.total_green += count * g; node_info.total_blue += count * b; } } return(true); }
public static void DisplayChar(Formats.CharsetProject Charset, int CharIndex, GR.Image.IImage TargetImage, int X, int Y, int AlternativeColor, int AltBGColor, int AltMColor1, int AltMColor2, int AltBGColor4, Types.CharsetMode AlternativeMode) { Formats.CharData Char = Charset.Characters[CharIndex]; if (AlternativeMode == C64Studio.Types.CharsetMode.ECM) { // ECM Formats.CharData origChar = Charset.Characters[CharIndex % 64]; int bgColor = AltBGColor; switch (CharIndex / 64) { case 1: bgColor = AltMColor1; break; case 2: bgColor = AltMColor2; break; case 3: bgColor = AltBGColor4; break; } Displayer.CharacterDisplayer.DisplayHiResChar(origChar.Data, bgColor, AlternativeColor, TargetImage, X, Y); } else if (AlternativeMode == C64Studio.Types.CharsetMode.MULTICOLOR) { Displayer.CharacterDisplayer.DisplayMultiColorChar(Char.Data, AltBGColor, AltMColor1, AltMColor2, AlternativeColor, TargetImage, X, Y); } else if (AlternativeMode == C64Studio.Types.CharsetMode.HIRES) { Displayer.CharacterDisplayer.DisplayHiResChar(Char.Data, AltBGColor, AlternativeColor, TargetImage, X, Y); } }
public static void DisplayChar(Formats.CharsetProject Charset, int CharIndex, GR.Image.IImage TargetImage, int X, int Y, int AlternativeColor) { DisplayChar(Charset, CharIndex, TargetImage, X, Y, AlternativeColor, Charset.BackgroundColor, Charset.MultiColor1, Charset.MultiColor2, Charset.BGColor4); }
public static void DisplayMultiColorChar(GR.Memory.ByteBuffer Data, int BGColor, int MColor1, int MColor2, int CharColor, GR.Image.IImage TargetImage, int X, int Y) { // multicolor if (CharColor < 8) { DisplayHiResChar(Data, BGColor, CharColor, TargetImage, X, Y); return; } int charColor = CharColor - 8; for (int j = 0; j < 8; ++j) { for (int i = 0; i < 4; ++i) { int pixelValue = (Data.ByteAt(j) & (3 << ((3 - i) * 2))) >> ((3 - i) * 2); switch (pixelValue) { case 0: pixelValue = BGColor; break; case 1: pixelValue = MColor1; break; case 2: pixelValue = MColor2; break; case 3: pixelValue = charColor; break; } TargetImage.SetPixel(X + i * 2, Y + j, (uint)pixelValue); TargetImage.SetPixel(X + i * 2 + 1, Y + j, (uint)pixelValue); } } }
public static void DisplayChar(Formats.CharsetProject Charset, Palette Palette, int CharIndex, GR.Image.IImage TargetImage, int X, int Y, int AlternativeColor, int AltBGColor, int AltMColor1, int AltMColor2, int AltBGColor4) { if (CharIndex >= Charset.Characters.Count) { return; } Formats.CharData Char = Charset.Characters[CharIndex]; DisplayChar(Charset, Palette, CharIndex, TargetImage, X, Y, AlternativeColor, AltBGColor, AltMColor1, AltMColor2, AltBGColor4, Charset.Mode); }
public static void DisplayHiResSprite(GR.Memory.ByteBuffer Data, int BGColor, int SpriteColor, GR.Image.IImage Target, int X, int Y, bool ExpandX, bool ExpandY) { int pixelStepX = 1; int pixelStepY = 1; if (ExpandX) { pixelStepX = 2; } if (ExpandY) { pixelStepY = 2; } // single color for (int j = 0; j < 21; ++j) { for (int pp = 0; pp < pixelStepY; ++pp) { for (int k = 0; k < 3; ++k) { for (int i = 0; i < 8; ++i) { if ((Data.ByteAt(j * 3 + k) & (1 << (7 - i))) != 0) { //Data.Image.SetPixel( k * 8 + i, j, m_ColorValues[Data.Color] ); Target.SetPixel(X + (k * 8 + i) * pixelStepX, Y + j * pixelStepY + pp, (uint)SpriteColor); if (pixelStepX == 2) { Target.SetPixel(X + (k * 8 + i) * pixelStepX + 1, Y + j * pixelStepY + pp, (uint)SpriteColor); } } } } } } }
public static void DisplayHiResSprite(GR.Memory.ByteBuffer Data, Palette Palette, int Width, int Height, int BGColor, int SpriteColor, GR.Image.IImage TargetImage, int X, int Y) { DisplayHiResSprite(Data, Palette, Width, Height, BGColor, SpriteColor, TargetImage, X, Y, false, false); }
public static void DisplayMultiColorSprite(GR.Memory.ByteBuffer Data, Palette Palette, int Width, int Height, int BGColor, int MColor1, int MColor2, int SpriteColor, GR.Image.IImage Target, int X, int Y, bool ExpandX, bool ExpandY) { int pixelStepX = 1; int pixelStepY = 1; if (ExpandX) { pixelStepX = 2; } if (ExpandY) { pixelStepY = 2; } // multicolor for (int j = 0; j < Height; ++j) { for (int pp = 0; pp < pixelStepY; ++pp) { for (int k = 0; k < Width / 8; ++k) { for (int i = 0; i < 4; ++i) { int pixelValue = (Data.ByteAt(j * 3 + k) & (3 << ((3 - i) * 2))) >> ((3 - i) * 2); switch (pixelValue) { case 0: pixelValue = BGColor; break; case 1: pixelValue = MColor1; break; case 3: pixelValue = MColor2; break; case 2: pixelValue = SpriteColor; break; } uint color = Palette.ColorValues[pixelValue]; Target.SetPixel(X + k * 8 * pixelStepX + i * 2 * pixelStepX, Y + j * pixelStepY + pp, color); Target.SetPixel(X + k * 8 * pixelStepX + i * 2 * pixelStepX + 1, Y + j * pixelStepY + pp, color); if (pixelStepX == 2) { Target.SetPixel(X + k * 8 * pixelStepX + i * 2 * pixelStepX + 2, Y + j * pixelStepY + pp, color); Target.SetPixel(X + k * 8 * pixelStepX + i * 2 * pixelStepX + 3, Y + j * pixelStepY + pp, color); } } } } } }
public static void DisplayHiResSprite(GR.Memory.ByteBuffer Data, Palette Palette, int Width, int Height, int BGColor, int SpriteColor, GR.Image.IImage Target, int X, int Y, bool ExpandX, bool ExpandY) { int pixelStepX = 1; int pixelStepY = 1; if (ExpandX) { pixelStepX = 2; } if (ExpandY) { pixelStepY = 2; } // single color for (int j = 0; j < Height; ++j) { for (int pp = 0; pp < pixelStepY; ++pp) { for (int k = 0; k < Width / 8; ++k) { for (int i = 0; i < 8; ++i) { if ((Data.ByteAt(j * 3 + k) & (1 << (7 - i))) != 0) { uint color = Palette.ColorValues[SpriteColor]; Target.SetPixel(X + (k * 8 + i) * pixelStepX, Y + j * pixelStepY + pp, color); if (pixelStepX == 2) { Target.SetPixel(X + (k * 8 + i) * pixelStepX + 1, Y + j * pixelStepY + pp, color); } } else { uint color = Palette.ColorValues[BGColor]; Target.SetPixel(X + (k * 8 + i) * pixelStepX, Y + j * pixelStepY + pp, color); if (pixelStepX == 2) { Target.SetPixel(X + (k * 8 + i) * pixelStepX + 1, Y + j * pixelStepY + pp, color); } } } } } } }
public static void DisplayFCMSprite(GR.Memory.ByteBuffer Data, Palette Palette, int Width, int Height, int BGColor, GR.Image.IImage Target, int X, int Y, bool ExpandX, bool ExpandY) { int pixelStepX = 1; int pixelStepY = 1; if (ExpandX) { pixelStepX = 2; } if (ExpandY) { pixelStepY = 2; } int lineBytes = (Width + 1) / 2; for (int j = 0; j < Height; ++j) { for (int pp = 0; pp < pixelStepY; ++pp) { for (int i = 0; i < Width; i += 2) { byte pixelDuo = Data.ByteAt(j * lineBytes + i / 2); byte colorToUse = (byte)BGColor; if ((pixelDuo >> 4) != 0) { colorToUse = (byte)(pixelDuo >> 4); } uint color = Palette.ColorValues[colorToUse]; Target.SetPixel((X + i) * pixelStepX, Y + j * pixelStepY + pp, color); if (pixelStepX == 2) { Target.SetPixel((X + i) * pixelStepX + 1, Y + j * pixelStepY + pp, color); } colorToUse = (byte)BGColor; if ((pixelDuo & 0x0f) != 0) { colorToUse = (byte)(pixelDuo & 0x0f); } color = Palette.ColorValues[colorToUse]; Target.SetPixel((X + i + 1) * pixelStepX, Y + j * pixelStepY + pp, color); if (pixelStepX == 2) { Target.SetPixel((X + i + 1) * pixelStepX + 1, Y + j * pixelStepY + pp, color); } } } } }
public GR.Image.IImage Reduce(GR.Image.IImage pPackSource) { return(Assignment(m_pCubeInfo, pPackSource)); }
GR.Image.MemoryImage Assignment(CubeInfo cube_info, GR.Image.IImage pCD) { var format = GR.Drawing.PixelFormat.Format8bppIndexed; if (m_Colors <= 2) { format = GR.Drawing.PixelFormat.Format1bppIndexed; } /* * else if ( m_Colors <= 4 ) * { * format = System.Drawing.Imaging.PixelFormat.Format2bppIndexed; * }*/ else if (m_Colors <= 16) { format = GR.Drawing.PixelFormat.Format4bppIndexed; } var pImage = new GR.Image.MemoryImage(pCD.Width, pCD.Height, format); var pal = new RetroDevStudio.Palette(m_Colors); byte index; int count, i; NodeInfo node_info; uint dither, id; // Allocate image colormap. cube_info.colormap = new PixelPacket[256]; cube_info.colors = 0; DefineColormap(cube_info, cube_info.root); // Create a reduced color image. dither = cube_info.quantize_info.dither; for (int y = 0; y < pCD.Height; y++) { //indexes=GetIndexes(image); for (int x = 0; x < pCD.Width; x += count) { // Identify the deepest node containing the pixel's color. count = 1; uint pixel = pCD.GetPixel(x, y); int r = (byte)((pixel & 0xff0000) >> 16), g = (byte)((pixel & 0xff00) >> 8), b = (byte)(pixel & 0xff); node_info = cube_info.root; for (index = MaxTreeDepth - 1; (int)index > 0; index--) { id = (uint)(((Downscale(r) >> index) & 0x01) << 2 | ((Downscale(g) >> index) & 0x01) << 1 | ((Downscale(b) >> index) & 0x01)); if ((node_info.census & (1 << (byte)id)) == 0) { break; } node_info = node_info.child[id]; } // Find closest color among siblings and their children. cube_info.color.red = (byte)r; cube_info.color.green = (byte)g; cube_info.color.blue = (byte)b; cube_info.distance = 3.0 * (MaxRGB() + 1) * (MaxRGB() + 1); ClosestColor(cube_info, node_info.parent); index = (byte)cube_info.color_number; for (i = 0; i < count; i++) { if (cube_info.quantize_info.measure_error == 0) { pImage.SetPixel(x, y, index); } } } } for (i = 0; i < cube_info.colors; i++) { pal.ColorValues[i] = (uint)(0xff000000 | (uint)(cube_info.colormap[i].red << 16) | (uint)(cube_info.colormap[i].green << 8) | (uint)cube_info.colormap[i].blue); pImage.SetPaletteColor(i, cube_info.colormap[i].red, cube_info.colormap[i].green, cube_info.colormap[i].blue); } return(pImage); }
public static void DisplayMultiColorSprite(GR.Memory.ByteBuffer Data, int BGColor, int MColor1, int MColor2, int SpriteColor, GR.Image.IImage TargetImage, int X, int Y) { DisplayMultiColorSprite(Data, BGColor, MColor1, MColor2, SpriteColor, TargetImage, X, Y, false, false); }
public static void DisplayMega65FCMChar(GR.Memory.ByteBuffer Data, Palette Palette, int BGColor, int CharColor, GR.Image.IImage TargetImage, int X, int Y) { for (int j = 0; j < 8; ++j) { for (int i = 0; i < 8; ++i) { int colorIndex = Data.ByteAt(i + j * 8); TargetImage.SetPixel(X + i, Y + j, Palette.ColorValues[colorIndex]); } } }
public static void DisplayMultiColorSprite(GR.Memory.ByteBuffer Data, int BGColor, int MColor1, int MColor2, int SpriteColor, GR.Image.IImage Target, int X, int Y, bool ExpandX, bool ExpandY) { int pixelStepX = 1; int pixelStepY = 1; if (ExpandX) { pixelStepX = 2; } if (ExpandY) { pixelStepY = 2; } // multicolor for (int j = 0; j < 21; ++j) { for (int pp = 0; pp < pixelStepY; ++pp) { for (int k = 0; k < 3; ++k) { for (int i = 0; i < 4; ++i) { int pixelValue = (Data.ByteAt(j * 3 + k) & (3 << ((3 - i) * 2))) >> ((3 - i) * 2); switch (pixelValue) { case 0: //pixelValue = BackgroundColor; continue; case 1: pixelValue = MColor1; break; case 3: pixelValue = MColor2; break; case 2: pixelValue = SpriteColor; break; } Target.SetPixel(X + k * 8 * pixelStepX + i * 2 * pixelStepX, Y + j * pixelStepY + pp, (uint)pixelValue); Target.SetPixel(X + k * 8 * pixelStepX + i * 2 * pixelStepX + 1, Y + j * pixelStepY + pp, (uint)pixelValue); if (pixelStepX == 2) { Target.SetPixel(X + k * 8 * pixelStepX + i * 2 * pixelStepX + 2, Y + j * pixelStepY + pp, (uint)pixelValue); Target.SetPixel(X + k * 8 * pixelStepX + i * 2 * pixelStepX + 3, Y + j * pixelStepY + pp, (uint)pixelValue); } } } } } }
public static void DisplayChar(Formats.CharsetProject Charset, Palette Palette, int CharIndex, GR.Image.IImage TargetImage, int X, int Y, int AlternativeColor, int AltBGColor, int AltMColor1, int AltMColor2, int AltBGColor4, TextCharMode AlternativeMode) { Formats.CharData Char = Charset.Characters[CharIndex]; if (AlternativeMode == TextCharMode.COMMODORE_ECM) { // ECM Formats.CharData origChar = Charset.Characters[CharIndex % 64]; int bgColor = AltBGColor; switch (CharIndex / 64) { case 1: bgColor = AltMColor1; break; case 2: bgColor = AltMColor2; break; case 3: bgColor = AltBGColor4; break; } DisplayHiResChar(origChar.Tile.Data, Palette, bgColor, AlternativeColor, TargetImage, X, Y); } else if (AlternativeMode == TextCharMode.COMMODORE_MULTICOLOR) { DisplayMultiColorChar(Char.Tile.Data, Palette, AltBGColor, AltMColor1, AltMColor2, AlternativeColor, TargetImage, X, Y); } else if (AlternativeMode == TextCharMode.COMMODORE_HIRES) { DisplayHiResChar(Char.Tile.Data, Palette, AltBGColor, AlternativeColor, TargetImage, X, Y); } else if ((AlternativeMode == TextCharMode.MEGA65_FCM) || (AlternativeMode == TextCharMode.MEGA65_FCM_16BIT)) { DisplayMega65FCMChar(Char.Tile.Data, Palette, AltBGColor, AlternativeColor, TargetImage, X, Y); } else if (AlternativeMode == TextCharMode.VIC20) { DisplayVIC20Char(Char.Tile.Data, Palette, AltBGColor, AltMColor1, AltMColor2, AlternativeColor, TargetImage, X, Y); } else { Debug.Log("DisplayChar #2 unsupported mode " + AlternativeMode); } }
public static void DisplayHiResSprite(GR.Memory.ByteBuffer Data, int BGColor, int SpriteColor, GR.Image.IImage TargetImage, int X, int Y) { DisplayHiResSprite(Data, BGColor, SpriteColor, TargetImage, X, Y, false, false); }
public static void DisplayChar(Formats.CharsetProject Charset, int CharIndex, GR.Image.IImage TargetImage, int X, int Y) { Formats.CharData Char = Charset.Characters[CharIndex]; DisplayChar(Charset, CharIndex, TargetImage, X, Y, Char.Color); }
public static void DisplayMega65NCMChar(GR.Memory.ByteBuffer Data, Palette Palette, int BGColor, int CharColor, GR.Image.IImage TargetImage, int X, int Y) { for (int j = 0; j < 8; ++j) { for (int i = 0; i < 16; ++i) { int colorIndex = Data.ByteAt(i / 2 + j * 8); if ((i % 2) != 0) { colorIndex >>= 4; } else { colorIndex &= 0x0f; } if (colorIndex == 0) { colorIndex = BGColor; } TargetImage.SetPixel(X + i, Y + j, Palette.ColorValues[colorIndex]); } } }
public static void DisplayChar(Formats.CharsetProject Charset, int CharIndex, GR.Image.IImage TargetImage, int X, int Y, int AlternativeColor, int AltBGColor, int AltMColor1, int AltMColor2, int AltBGColor4) { Formats.CharData Char = Charset.Characters[CharIndex]; DisplayChar(Charset, CharIndex, TargetImage, X, Y, AlternativeColor, AltBGColor, AltMColor1, AltMColor2, AltBGColor4, Char.Mode); }
public void DrawTo(GR.Image.IImage TargetImage, int X, int Y, int Width, int Height) { DrawTo(TargetImage, X, Y, 0, 0, Width, Height); }
public static void DisplayHiResChar(GR.Memory.ByteBuffer Data, int BGColor, int CharColor, GR.Image.IImage TargetImage, int X, int Y) { // single color int colorIndex = 0; for (int j = 0; j < 8; ++j) { for (int i = 0; i < 8; ++i) { if ((Data.ByteAt(j) & (1 << (7 - i))) != 0) { colorIndex = CharColor; } else { colorIndex = BGColor; } TargetImage.SetPixel(X + i, Y + j, (uint)colorIndex); } } }
public void AddSourceToColorCube(GR.Image.IImage Image) { Classification(m_pCubeInfo, Image); }