static void SetPixCol1(BitmapCpc dest) { int choix = 0; for (int y = 0; y < tailleY; y += 2) { for (int x = 0; x < tailleX; x += Tx) { int oldDist = 0x7FFFFFFF; int totR = 0, totV = 0, totB = 0; bitmap.GetPixel(x, y, ref totR, ref totV, ref totB); bitmap.AddGetPixel(x, y + 1, ref totR, ref totV, ref totB); totR >>= 1; totV >>= 1; totB >>= 1; for (int i = 0; i < MaxCol; i++) { int Dist = CalcDist(tabCol[i], totR, totV, totB); if (Dist < oldDist) { choix = i; oldDist = Dist; if (Dist == 0) { break; } } } dest.SetPixelCpc(x, y, choix); } } }
public void Reset(bool force = false) { if (!bitmapCpc.isCalc || force) { int startImg = force ? 0 : selImage; int endImg = force ? maxImage : selImage; for (int i = startImg; i < endImg; i++) { selImage = i; int col = System.Drawing.SystemColors.Control.ToArgb(); for (int y = 0; y < tabBmpLock[i].Height; y += 2) { int startX = y < BitmapCpc.TailleY ? BitmapCpc.TailleX : 0; tabBmpLock[i].SetHorLineDouble(0, y, startX, GetPalCPC(BitmapCpc.Palette[0])); tabBmpLock[i].SetHorLineDouble(startX, y, tabBmpLock[i].Width - startX, col); } } } int tx = BitmapCpc.CalcTx(); int maxPen = BitmapCpc.MaxPen(2); for (int i = 0; i < 16; i++) { colors[i].Visible = lockColors[i].Visible = i < maxPen; } ToolModeDraw(null); }
static void SetPixCol0(BitmapCpc dest) { for (int y = 0; y < tailleY; y += 2) { for (int x = 0; x < tailleX; x += Tx) { int oldDist = 0x7FFFFFFF; int p = bitmap.GetPixel(x, y); int choix = 0; for (int i = 0; i < MaxCol; i++) { int Dist = CalcDist(p, tabCol[i].GetColor); if (Dist < oldDist) { choix = i; oldDist = Dist; if (Dist == 0) { break; } } } dest.SetPixelCpc(x, y, choix); } } }
// // Passe 1 : Réduit la palette aux x couleurs de la palette du CPC. // Effectue également un traitement de l'erreur (tramage) si demandé. // Calcule le nombre de couleurs utilisées dans l'image, et // remplit le tableau coulTrouvee avec ces couleurs // static private void ConvertPasse1(DirectBitmap source, ImageCpc dest, Param prm) { int pct = Dither.SetMatDither(prm); RvbColor p = new RvbColor(0), choix, n1, n2; int indexChoix = 0; int incY = prm.trameTc ? 4 : 2; for (int yPix = 0; yPix < BitmapCpc.TailleY; yPix += incY) { int Tx = BitmapCpc.CalcTx(yPix); for (int xPix = 0; xPix < BitmapCpc.TailleX; xPix += Tx) { for (int yy = 0; yy < incY; yy += 2) { p = GetPixel(source, xPix, yy + yPix, Tx, prm, pct); // Recherche le point dans la couleur cpc la plus proche if (prm.cpcPlus) { choix = new RvbColor((byte)((p.r >> 4) * 17), (byte)((p.v >> 4) * 17), (byte)((p.b >> 4) * 17)); indexChoix = ((choix.v << 4) & 0xF00) + ((choix.b) & 0xF0) + ((choix.r) >> 4); } else { indexChoix = GetNumColorPixelCpc(prm, p); choix = BitmapCpc.RgbCPC[indexChoix]; } coulTrouvee[indexChoix, yPix >> 1]++; if (!prm.trameTc) { source.SetPixel(xPix, yy + yPix, prm.setPalCpc ? choix : p); } } if (prm.trameTc) { // Moyenne des 2 pixels RvbColor p0 = GetPixel(source, xPix, yPix, Tx, prm, pct); RvbColor p1 = GetPixel(source, xPix, yPix + 2, Tx, prm, pct); int r = (p0.r + p1.r); int v = (p0.v + p1.v); int b = (p0.b + p1.b); if (prm.cpcPlus) { n1 = new RvbColor((byte)((r >> 4) * 8), (byte)((v >> 4) * 8), (byte)((b >> 4) * 8)); n2 = new RvbColor((byte)((r >> 5) * 8), (byte)((v >> 5) * 8), (byte)((b >> 5) * 8)); } else { n1 = BitmapCpc.RgbCPC[(r > prm.cstR3 ? 6 : r > prm.cstR1 ? 3 : 0) + (v > prm.cstV3 ? 18 : v > prm.cstV1 ? 9 : 0) + (b > prm.cstB3 ? 2 : b > prm.cstB1 ? 1 : 0)]; n2 = BitmapCpc.RgbCPC[(r > prm.cstR4 ? 6 : r > prm.cstR2 ? 3 : 0) + (v > prm.cstV4 ? 18 : v > prm.cstV2 ? 9 : 0) + (b > prm.cstB4 ? 2 : b > prm.cstB2 ? 1 : 0)]; } source.SetPixel(xPix, yPix, (xPix & Tx) == 0 ? n1 : n2); source.SetPixel(xPix, yPix + 2, (xPix & Tx) == 0 ? n2 : n1); } } } }
private void ToolModeDraw(MouseEventArgs e) { int incY = BitmapCpc.modeVirtuel >= 8 ? 8 : 2; int yReel = e != null ? (offsetY + (e.Y / zoom)) & -incY : 0; int tx = BitmapCpc.CalcTx(yReel); drawColor.BackColor = Color.FromArgb(bitmapCpc.GetColorPal(drawCol % (BitmapCpc.modeVirtuel == 6 ? 16 : 1 << tx)).GetColorArgb); undrawColor.BackColor = Color.FromArgb(bitmapCpc.GetColorPal(undrawCol % (BitmapCpc.modeVirtuel == 6 ? 16 : 1 << tx)).GetColorArgb); drawColor.Width = undrawColor.Width = 35 * Math.Min(tx, 4); drawColor.Refresh(); undrawColor.Refresh(); if (e == null || e.Button == MouseButtons.None) { if (doDraw) { doDraw = false; undo.EndUndoRedo(); } } else { int pen = e.Button == MouseButtons.Left ? drawCol : undrawCol; for (int y = 0; y < penWidth * incY; y += 2) { tx = BitmapCpc.CalcTx(yReel); int nbCol = BitmapCpc.modeVirtuel == 6 ? 16 : 1 << tx; int realColor = GetPalCPC(BitmapCpc.Palette[pen % nbCol]); int yStart = zoom * (yReel - offsetY); for (int x = 0; x < penWidth * tx; x += tx) { int xReel = (x + offsetX + (e.X / zoom)) & -tx; if (xReel >= 0 && yReel >= 0 && xReel < BitmapCpc.TailleX && yReel < BitmapCpc.TailleY) { undo.MemoUndoRedo(xReel, yReel, BmpLock.GetPixel(xReel, yReel), realColor, doDraw); doDraw = true; BmpLock.SetHorLineDouble(xReel, yReel, tx, realColor); if (zoom != 1) { for (int yz = yStart; yz < Math.Min(tmpLock.Height, yStart + (zoom << 1)); yz += 2) { if (yz >= 0) { tmpLock.SetHorLineDouble(zoom * (xReel - offsetX), yz, zoom * tx, realColor); } } } } } yReel += 2; } Render(); } }
static public void GenerePaletteOld(StreamWriter sw, ImageCpc img) { sw.WriteLine("Palette:"); string line = "\tDB\t"; for (int i = 0; i < 17; i++) { line += "#" + ((int)BitmapCpc.CpcVGA[BitmapCpc.Palette[i < BitmapCpc.MaxPen() ? i : 0]]).ToString("X2") + ","; } line += "#" + ((BitmapCpc.modeVirtuel == 7 ? 1 : BitmapCpc.modeVirtuel & 3) | 0x8C).ToString("X2"); sw.WriteLine(line); }
// Copier la palette dans le presse-papier private void bpCopyPal_Click(object sender, EventArgs e) { string palTxt = ""; int maxPen = BitmapCpc.MaxPen(2); for (int i = 0; i < maxPen; i++) { int val = BitmapCpc.Palette[i]; string valStr = BitmapCpc.cpcPlus ? ("&" + val.ToString("X3")) : val.ToString(); palTxt += valStr + (i < maxPen - 1 ? "," : ""); } Clipboard.SetText(palTxt); MessageBox.Show("Palette copiée dans le presse-papier"); }
static public void GenerePalettePlus(StreamWriter sw, ImageCpc img) { sw.WriteLine("UnlockAsic:"); sw.WriteLine(" DB #FF,#00,#FF,#77,#B3,#51,#A8,#D4,#62,#39,#9C,#46,#2B,#15,#8A,#CD,#EE"); sw.WriteLine("Palette:"); string line = "\tDB\t#" + ((BitmapCpc.modeVirtuel == 7 ? 1 : BitmapCpc.modeVirtuel & 3) | 0x8C).ToString("X2"); for (int i = 0; i < 17; i++) { int c = BitmapCpc.Palette[i < BitmapCpc.MaxPen() ? i : 0]; line += ",#" + ((byte)(((c >> 4) & 0x0F) | (c << 4))).ToString("X2") + ",#" + ((byte)(c >> 8)).ToString("X2"); } sw.WriteLine(line); }
public void Render(bool forceDrawZoom = false) { UpdatePalette(); modeCaptureSprites.Visible = BitmapCpc.modeVirtuel == 11; modeEdition.Visible = BitmapCpc.modeVirtuel != 11; if (chkDoRedo.Checked && modeEdition.Checked) { Enabled = false; List <MemoPoint> lst = undo.lstUndoRedo; foreach (MemoPoint p in lst) { int Tx = BitmapCpc.CalcTx(p.posy); BmpLock.SetHorLineDouble(p.posx, p.posy, Tx, p.newColor); } forceDrawZoom = true; bpUndo.Enabled = undo.CanUndo; bpRedo.Enabled = undo.CanRedo; Enabled = true; } if (zoom != 1) { if (tmpLock == null) { tmpLock = new DirectBitmap(imgOrigine.Width, imgOrigine.Height); } if (forceDrawZoom) { for (int y = 0; y < imgOrigine.Height; y += 2) { int ySrc = Math.Min(offsetY + (y / zoom), BitmapCpc.TailleY - 1); for (int x = 0; x < imgOrigine.Width; x += zoom) { tmpLock.SetHorLineDouble(x, y, Math.Min(zoom, imgOrigine.Width - x - 1), BmpLock.GetPixel(offsetX + (x / zoom), ySrc)); } } } pictureBox.Image = tmpLock.Bitmap; } else { pictureBox.Image = imgCopy != null ? imgCopy.Bitmap : BmpLock.Bitmap; tmpLock = null; } pictureBox.Refresh(); if (fenetreRendu != null) { fenetreRendu.Picture.Refresh(); } }
private byte[] MakeSprite() { byte[] ret = new byte[(BitmapCpc.TailleX * BitmapCpc.TailleY) >> 4]; Array.Clear(ret, 0, ret.Length); for (int y = 0; y < BitmapCpc.TailleY; y += 2) { int tx = BitmapCpc.CalcTx(y); for (int x = 0; x < BitmapCpc.TailleX; x += 8) { byte pen = 0, octet = 0; for (int p = 0; p < 8; p++) { if ((p % tx) == 0) { RvbColor col = BmpLock.GetPixelColor(x + p, y); if (BitmapCpc.cpcPlus) { for (pen = 0; pen < 16; pen++) { if ((col.v >> 4) == (BitmapCpc.Palette[pen] >> 8) && (col.r >> 4) == ((BitmapCpc.Palette[pen] >> 4) & 0x0F) && (col.b >> 4) == (BitmapCpc.Palette[pen] & 0x0F)) { break; } } } else { for (pen = 0; pen < 16; pen++) { RvbColor fixedCol = BitmapCpc.RgbCPC[BitmapCpc.Palette[pen]]; if (fixedCol.r == col.r && fixedCol.b == col.b && fixedCol.v == col.v) { break; } } } if (pen > 15) { pen = 0; // Pb peut survenir si la palette n'est pas la même pour chaque image d'une animation... } octet |= (byte)(tabOctetMode[pen % 16] >> (p / tx)); } } ret[(x >> 3) + (y >> 1) * (BitmapCpc.TailleX >> 3)] = octet; } } return(ret); }
// Conversion "standard" static private void SetPixCol(DirectBitmap bitmap, Param prm, ImageCpc dest, int maxPen, RvbColor[,] tabCol) { int incY = BitmapCpc.modeVirtuel >= 8 && BitmapCpc.modeVirtuel <= 10 ? 8 : 2; RvbColor pix; for (int y = 0; y < BitmapCpc.TailleY; y += incY) { int Tx = BitmapCpc.CalcTx(y); maxPen = BitmapCpc.MaxPen(y); for (int x = 0; x < BitmapCpc.TailleX; x += Tx) { int oldDist = 0x7FFFFFFF; int r = 0, v = 0, b = 0; for (int j = 0; j < incY; j += 2) { pix = bitmap.GetPixelColor(x, y + j); r += pix.r; v += pix.v; b += pix.b; } r = r / (incY >> 1); v = v / (incY >> 1); b = b / (incY >> 1); pix = new RvbColor((byte)r, (byte)v, (byte)b); int choix = 0; for (int i = 0; i < maxPen; i++) { RvbColor c = tabCol[i, y >> 1]; if (c != null) { int dist = (c.r - pix.r) * (c.r - pix.r) * prm.coefR + (c.v - pix.v) * (c.v - pix.v) * prm.coefV + (c.b - pix.b) * (c.b - pix.b) * prm.coefB; if (dist < oldDist) { choix = i; oldDist = dist; if (dist == 0) { i = maxPen; } } } } for (int j = 0; j < incY; j += 2) { dest.SetPixelCpc(x, y + j, choix, Tx); } } } }
private void DrawCopy(MouseEventArgs e) { if (imgMotif != null && imgCopy != null) { imgCopy.CopyBits(BmpLock); int yReel = ((e.Y / zoom) & 0xFFE) * zoom; int tx = BitmapCpc.CalcTx(yReel); int xReel = ((e.X / zoom) & -tx) * zoom; if (xReel < BitmapCpc.NbCol << 3 && yReel < BitmapCpc.NbLig << 1) { Graphics g = Graphics.FromImage(pictureBox.Image); g.DrawImage(imgMotif.Bitmap, xReel, yReel); pictureBox.Refresh(); } } }
static void SetPixCol2(BitmapCpc dest) { int choix0 = 0, choix1 = 0; for (int y = 0; y < tailleY; y += 4) { int ynorm = y + 2 < tailleY ? y + 2 : y + 1; for (int x = 0; x < tailleX; x += Tx << 1) { int xnorm = x + Tx < tailleX ? x + Tx : x + 1; int OldDist = 0x7FFFFFFF; int totR = 0, totV = 0, totB = 0; bitmap.GetPixel(x, y, ref totR, ref totV, ref totB); bitmap.AddGetPixel(x, ynorm, ref totR, ref totV, ref totB); bitmap.AddGetPixel(xnorm, y, ref totR, ref totV, ref totB); bitmap.AddGetPixel(xnorm, ynorm, ref totR, ref totV, ref totB); totR >>= 1; totV >>= 1; totB >>= 1; for (int i1 = 0; i1 < MaxCol; i1++) { for (int i2 = 0; i2 < MaxCol; i2++) { int sr = tabCol[i1].red + tabCol[i2].red; int sv = tabCol[i1].green + tabCol[i2].green; int sb = tabCol[i1].blue + tabCol[i2].blue; int Dist = CalcDist(sr, sv, sb, totR, totV, totB); if (Dist < OldDist) { choix0 = i1; choix1 = i2; OldDist = Dist; if (Dist == 0) { i1 = i2 = MaxCol; } } } } dest.SetPixelCpc(x, y, choix0); dest.SetPixelCpc(xnorm, y, choix1); dest.SetPixelCpc(x, ynorm, choix1); dest.SetPixelCpc(xnorm, ynorm, choix0); } } }
// Conversion avec trames précalculées en mode 1 static private void SetPixTrameM1(DirectBitmap bitmap, Param prm, ImageCpc dest, int maxPen, RvbColor[,] tabCol) { for (int y = 0; y <= BitmapCpc.TailleY - 8; y += 8) { maxPen = BitmapCpc.MaxPen(y); for (int x = 0; x < BitmapCpc.TailleX; x += 8) { int choix = 0, oldDist = 0x7FFFFFFF; for (int i = 0; i < 16; i++) { int dist = 0, r1 = 0, v1 = 0, b1 = 0, r2 = 0, v2 = 0, b2 = 0; for (int ym = 0; ym < 4; ym++) { for (int xm = 0; xm < 4; xm++) { RvbColor pix = bitmap.GetPixelColor(x + (xm << 1), y + (ym << 1)); RvbColor c = tabCol[BitmapCpc.trameM1[i, xm, ym], ym + (y >> 1)]; r1 += pix.r; v1 += pix.v; b1 += pix.b; r2 += c.r; v2 += c.v; b2 += c.b; } } dist = Math.Abs(r1 - r2) * prm.coefR + Math.Abs(v1 - v2) * prm.coefV + Math.Abs(b1 - b2) * prm.coefB; if (dist < oldDist) { choix = i; oldDist = dist; if (dist == 0) { i = 16; } } } for (int ym = 0; ym < 4; ym++) { for (int xm = 0; xm < 4; xm++) { dest.SetPixelCpc(x + (xm << 1), y + (ym << 1), BitmapCpc.trameM1[choix, xm, ym], 2); } } } } }
public void InitBitmapCpc(int nbImage, int tps) { if (nbImage == 0) { nbImage++; } selImage = 0; maxImage = nbImage; TabBitmapCpc = new BitmapCpc[nbImage]; tabBmpLock = new DirectBitmap[nbImage]; for (int i = 0; i < nbImage; i++) { TabBitmapCpc[i] = new BitmapCpc(); tabBmpLock[i] = new DirectBitmap(pictureBox.Width, pictureBox.Height); tabBmpLock[i].Tps = tps; } }
static void SetPixColBigPixelM0(BitmapCpc dest) { int index = 0, pos = 0, choix0 = 0; for (int y = 0; y < tailleY; y += 8) { for (int x = 0; x < tailleX; x += 8) { int OldDist = 0x7FFFFFFF; int totR = 0, totV = 0, totB = 0; for (int i1 = 0; i1 < 4; i1++) { for (int i2 = 0; i2 < 4; i2++) { bitmap.AddGetPixel(x + 2 * i2 < tailleX ? x + 2 * i2 : x + 1, y + 2 * i1 < tailleY ? y + 2 * i1 : y + 1, ref totR, ref totV, ref totB); } } pos = 0; for (int i1 = 0; i1 < 16; i1++) { int Dist = CalcDist(tabCol[i1].red << 4, tabCol[i1].green << 4, tabCol[i1].blue << 4, totR, totV, totB); pos++; if (Dist < OldDist) { choix0 = i1; OldDist = Dist; if (Dist == 0) { i1 = 16; } } } resultTri[index++] = choix0; for (int i1 = 0; i1 < 4; i1++) { for (int i2 = 0; i2 < 4; i2++) { dest.SetPixelCpc(x + 2 * i2 < tailleX ? x + 2 * i2 : x + 1, y + 2 * i1 < tailleY ? y + 2 * i1 : y + 1, choix0); } } } } }
// // Passe 2 : réduit l'image à MaxCol couleurs. // static void Passe2(BitmapCpc dest, int[] CChoix, bool CpcPlus, int PixMode) { for (int i = 0; i < MaxCol; i++) { tabCol[i] = CpcPlus ? new RvbColor((byte)(((CChoix[i] & 0xF0) >> 4) * 17), (byte)(((CChoix[i] & 0xF00) >> 8) * 17), (byte)((CChoix[i] & 0x0F) * 17)) : BitmapCpc.RgbCPC[CChoix[i] < 27 ? CChoix[i] : 0]; } switch (PixMode) { case 1: SetPixCol1(dest); break; case 2: SetPixCol2(dest); break; case 3: SetPixCol3(dest); break; case 4: switch (dest.ModeCPC) { case 0: SetPixColBigPixelM0(dest); break; case 1: SetPixColTriangle(dest); break; default: SetPixCol0(dest); break; } break; default: SetPixCol0(dest); break; } }
public EditTrameAscii(Main m, ImageSource s, ImageCpc i, Param p) { InitializeComponent(); main = m; main.ChangeLanguage(Controls, "EditTrameAscii"); imgSrc = s; imgCpc = i; bmpCpc = i.bitmapCpc; param = p; bmpTrame = new DirectBitmap(pictEditMatrice.Width, pictEditMatrice.Height); pictEditMatrice.Image = bmpTrame.Bitmap; DrawMatrice(); DrawTrame(); lblPen0.BackColor = Color.FromArgb(bmpCpc.GetColorPal(0).GetColorArgb); lblPen1.BackColor = Color.FromArgb(bmpCpc.GetColorPal(1).GetColorArgb); lblPen2.BackColor = Color.FromArgb(bmpCpc.GetColorPal(2).GetColorArgb); lblPen3.BackColor = Color.FromArgb(bmpCpc.GetColorPal(3).GetColorArgb); DrawPens(); }
private void bpRedo_Click(object sender, System.EventArgs e) { Enabled = false; List <MemoPoint> lst = undo.Redo(); foreach (MemoPoint p in lst) { int tx = BitmapCpc.CalcTx(p.posy); BmpLock.SetHorLineDouble(p.posx, p.posy, tx, p.newColor); } if (imgCopy != null) { imgCopy.CopyBits(BmpLock); } Render(true); bpUndo.Enabled = undo.CanUndo; bpRedo.Enabled = undo.CanRedo; Enabled = true; }
// Sur déplacement de la souris... private void TrtMouseMove(object sender, MouseEventArgs e) { if (modeCaptureSprites.Checked) { CaptureSprites(e); // Capture de sprites hard } else if (modeEdition.Checked) { int incY = BitmapCpc.modeVirtuel >= 8 ? 8 : 2; int yReel = ((offsetY + (e.Y / zoom)) & -incY) >> 1; int tx = BitmapCpc.CalcTx(yReel); int xReel = (offsetX + (e.X / zoom)) & -tx; lblInfoPos.Text = "x:" + xReel.ToString("000") + " y:" + yReel.ToString("000"); switch (editToolMode) { case EditTool.Draw: ToolModeDraw(e); break; case EditTool.Zoom: ToolModeZoom(e); break; case EditTool.Copy: ToolModeCopy(e); break; } if (e.Button == MouseButtons.None) { bpUndo.Enabled = undo.CanUndo; bpRedo.Enabled = undo.CanRedo; } } else { MoveOrSize(e); // Déplacement/Zoom image } }
// // Passe 2 : réduit l'image à MaxPen couleurs. // static private void Passe2(DirectBitmap source, ImageCpc dest, Param p, ref int colSplit) { RvbColor[,] tabCol = new RvbColor[16, 272]; int[] MemoLockState = new int[16]; int i; int Tx = BitmapCpc.CalcTx(); int maxPen = BitmapCpc.MaxPen(2); for (i = 0; i < 16; i++) { MemoLockState[i] = p.lockState[i]; } if (BitmapCpc.modeVirtuel == 3 || BitmapCpc.modeVirtuel == 4) { int newMax = BitmapCpc.MaxPen(0); RechercheCMax(newMax, MemoLockState, p); for (i = 0; i < newMax; i++) { MemoLockState[i] = 1; } } if (BitmapCpc.modeVirtuel == 5 || BitmapCpc.modeVirtuel == 6) { if (BitmapCpc.modeVirtuel == 5) { colSplit = RechercheCMaxModeX(dest.colMode5, MemoLockState, BitmapCpc.TailleY, p); } else { colSplit = RechercheCMaxModeSplit(dest.colMode5, MemoLockState, BitmapCpc.TailleY, p); maxPen = 9; } // réduit l'image à MaxPen couleurs. for (int y = 0; y < BitmapCpc.TailleY >> 1; y++) { for (i = 0; i < maxPen; i++) { tabCol[i, y] = p.cpcPlus ? new RvbColor((byte)((dest.colMode5[y, i] & 0x0F) * 17), (byte)(((dest.colMode5[y, i] & 0xF00) >> 8) * 17), (byte)(((dest.colMode5[y, i] & 0xF0) >> 4) * 17)) : BitmapCpc.RgbCPC[dest.colMode5[y, i] < 27 ? dest.colMode5[y, i] : 0]; } } } else { RechercheCMax(maxPen, MemoLockState, p); // réduit l'image à MaxPen couleurs. for (int y = 0; y < BitmapCpc.TailleY; y += 2) { maxPen = BitmapCpc.MaxPen(y); for (i = 0; i < maxPen; i++) { tabCol[i, y >> 1] = dest.bitmapCpc.GetColorPal(i); } } } switch (BitmapCpc.modeVirtuel) { case 6: SetPixColSplit(source, p, dest, tabCol); break; case 7: SetPixTrameM1(source, p, dest, maxPen, tabCol); break; default: SetPixCol(source, p, dest, maxPen, tabCol); break; } }
private void ToolModeCopy(MouseEventArgs e) { int yReel = ((e.Y / zoom) & 0xFFE) * zoom; int tx = BitmapCpc.CalcTx(yReel); int xReel = ((e.X / zoom) & -tx) * zoom; if (e.Button == MouseButtons.Left && xReel >= 0 && yReel >= 0) { if (imgMotif != null) { for (int y = 0; y < imgMotif.Height; y += 2) { tx = BitmapCpc.CalcTx(y + yReel); for (int x = 0; x < imgMotif.Width; x += tx) { if (x + xReel < BitmapCpc.NbCol << 3 && y + yReel < BitmapCpc.NbLig << 1) { int c = imgMotif.GetPixel(x, y); undo.MemoUndoRedo(x + xReel, y + yReel, BmpLock.GetPixel(x + xReel, y + yReel), c, doDraw); BmpLock.SetHorLineDouble(x + xReel, y + yReel, tx, c); doDraw = true; } } } imgCopy.CopyBits(BmpLock); Render(); } else { if (!setCopyRect) { setCopyRect = true; copyRectx = xReel; copyRecty = yReel; copyRecth = copyRectw = 0; } else { Graphics g = Graphics.FromImage(pictureBox.Image); if (copyRecth != 0 || copyRectw != 0) { XorDrawing.DrawXorRectangle(g, (Bitmap)pictureBox.Image, copyRectx, copyRecty, copyRectx + copyRectw, copyRecty + copyRecth); } copyRectw = xReel - copyRectx; copyRecth = yReel - copyRecty; XorDrawing.DrawXorRectangle(g, (Bitmap)pictureBox.Image, copyRectx, copyRecty, copyRectx + copyRectw, copyRecty + copyRecth); pictureBox.Refresh(); } } } else { if (setCopyRect) { setCopyRect = false; if (copyRectw != 0 && copyRecth != 0) { Graphics g = Graphics.FromImage(pictureBox.Image); XorDrawing.DrawXorRectangle(g, (Bitmap)pictureBox.Image, copyRectx, copyRecty, copyRectx + copyRectw, copyRecty + copyRecth); imgMotif = new DirectBitmap(Math.Abs(copyRectw / zoom), Math.Abs(copyRecth / zoom)); for (int x = 0; x < imgMotif.Width; x++) { for (int y = 0; y < imgMotif.Height; y++) { imgMotif.SetPixel(x, y, BmpLock.GetPixel(offsetX + x + copyRectx / zoom, offsetY + y + copyRecty / zoom)); } } if (zoom != 1) { zoom = 1; DoZoom(); } imgCopy = new DirectBitmap(BmpLock.Width, BmpLock.Height); pictureBox.Image = imgCopy.Bitmap; } } if (doDraw) { doDraw = false; undo.EndUndoRedo(); } DrawCopy(e); pictureBox.Refresh(); } }
private void ReadScreen(string fileName, bool singlePicture = false) { FileStream fileScr = new FileStream(fileName, FileMode.Open, FileAccess.Read); byte[] tabBytes = new byte[fileScr.Length]; fileScr.Read(tabBytes, 0, tabBytes.Length); fileScr.Close(); int nbImg = 0; try { bool isImp = false, isScrImp = false; if (CpcSystem.CheckAmsdos(tabBytes)) { int nbImages = 1, width = 1, height = 1; CpcAmsdos enteteAms = CpcSystem.GetAmsdos(tabBytes); // Vérifier si type scr imp isScrImp = (enteteAms.FileName.EndsWith("SCR") && enteteAms.FileType == 0 && enteteAms.Adress == 0x170); if (!isScrImp) { // Vérifier si type imp if (enteteAms.FileName.EndsWith("IMP")) { int l = tabBytes.Length; nbImages = tabBytes[l - 3]; width = tabBytes[l - 2]; height = tabBytes[l - 1]; int animSize = nbImages * width * height; isImp = l - 131 == animSize; // 131 + 128 (Amsdos) + 3 (imp) } } if (isImp) { imgCpc.InitBitmapCpc(nbImages, imgSrc.tpsFrame); imgSrc.InitBitmap(nbImages); anim.SetNbImgs(nbImages, imgSrc.tpsFrame); SetInfo(multilingue.GetString("Main.Prg.TxtInfo2") + nbImages + " images."); BitmapCpc.TailleX = width << 3; BitmapCpc.TailleY = height << 1; int x = BitmapCpc.NbCol; int y = BitmapCpc.NbLig; int posData = 128; // Entête Amsdos for (int i = 0; i < nbImages; i++) { SelectImage(i, true); byte[] tempData = new byte[width * height]; Array.Copy(tabBytes, posData, tempData, 0, tempData.Length); posData += tempData.Length; BitmapCpc bmp = new BitmapCpc(tempData, width << 3, height << 1); imgSrc.ImportBitmap(bmp.CreateImageFromCpc(tabBytes.Length - 0x80, param, true), i); } } else if (isScrImp) { BitmapCpc bmp = new BitmapCpc(tabBytes, 0x110); if (singlePicture) { imgSrc.ImportBitmap(bmp.CreateImageFromCpc(tabBytes.Length - 0x80, param), imgCpc.selImage); } else { BitmapCpc.modeVirtuel = param.modeVirtuel = mode.SelectedIndex = tabBytes[0x94] - 0x0E; BitmapCpc.TailleX = 768; nbLignes.Value = param.nbLignes = BitmapCpc.NbLig; BitmapCpc.TailleY = 544; nbCols.Value = param.nbCols = BitmapCpc.NbCol; BitmapCpc.cpcPlus = tabBytes[0xBC] != 0; if (BitmapCpc.cpcPlus) { // Palette en 0x0711; for (int i = 0; i < 16; i++) { BitmapCpc.Palette[i] = ((tabBytes[0x0711 + (i << 1)] << 4) & 0xF0) + (tabBytes[0x0711 + (i << 1)] >> 4) + (tabBytes[0x0712 + (i << 1)] << 8); } } else { // Palette en 0x7E10 for (int i = 0; i < 16; i++) { BitmapCpc.Palette[i] = BitmapCpc.CpcVGA.IndexOf((char)tabBytes[0x7E10 + i]); } } imgSrc.InitBitmap(bmp.CreateImageFromCpc(tabBytes.Length - 0x80, param)); } } else { BitmapCpc bmp = new BitmapCpc(tabBytes, 0x80); if (singlePicture) { imgSrc.ImportBitmap(bmp.CreateImageFromCpc(tabBytes.Length - 0x80, param), imgCpc.selImage); } else { imgSrc.InitBitmap(bmp.CreateImageFromCpc(tabBytes.Length - 0x80, param)); nbCols.Value = param.nbCols = BitmapCpc.NbCol; BitmapCpc.TailleX = param.nbCols << 3; nbLignes.Value = param.nbLignes = BitmapCpc.NbLig; BitmapCpc.TailleY = param.nbLignes << 1; param.modeVirtuel = mode.SelectedIndex = BitmapCpc.modeVirtuel; } SetInfo(multilingue.GetString("Main.prg.TxtInfo3")); } } else { imageStream = new MemoryStream(tabBytes); imageStream.Position = 0; if (!singlePicture) { imgSrc.InitBitmap(imageStream); nbImg = imgSrc.NbImg; anim.SetNbImgs(nbImg, imgSrc.tpsFrame); chkAllPics.Visible = nbImg > 1; SetInfo(multilingue.GetString("Main.prg.TxtInfo4") + (nbImg > 0 ? (multilingue.GetString("Main.prg.TxtInfo5") + nbImg + " images.") : ".")); } else { imgSrc.ImportBitmap(new Bitmap(imageStream), imgCpc.selImage); SetInfo(multilingue.GetString("Main.prg.TxtInfo4")); } } radioUserSize.Enabled = radioOrigin.Enabled = true; Text = "ConvImgCPC - " + Path.GetFileName(fileName); if (radioOrigin.Checked) { tbxSizeX.Text = imgSrc.GetImage.Width.ToString(); tbxSizeY.Text = imgSrc.GetImage.Height.ToString(); tbxPosX.Text = "0"; tbxPosY.Text = "0"; } if (!singlePicture && !isImp) { imgCpc.InitBitmapCpc(nbImg, imgSrc.tpsFrame); } SelectImage(0); imgCpc.Reset(true); Convert(false); } catch { DisplayErreur(multilingue.GetString("Main.prg.TxtInfo6")); } }
private int PackWinDC(byte[] bufOut, ref int sizeDepack, int topBottom, bool razDiff, int modeLigne, bool optimSpeed) { int xFin = 0; int xDeb = BitmapCpc.NbCol; int yDeb = BitmapCpc.NbLig; int yFin = 0; int lStart = 0, lEnd = BitmapCpc.NbLig, xStart = 0, xEnd = BitmapCpc.NbCol; if (razDiff) { Array.Clear(BufPrec, 0, BufPrec.Length); } // Copier l'image cpc dans le buffer de travail img.bitmapCpc.CreeBmpCpc(img.BmpLock, null); if (chkZoneVert.Checked) { xStart = topBottom < 1 ? 0 : BitmapCpc.NbCol >> 1; xEnd = topBottom == 0 ? BitmapCpc.NbCol >> 1 : BitmapCpc.NbCol; } else { lStart = topBottom < 1 ? 0 : BitmapCpc.NbLig >> 1; lEnd = topBottom == 0 ? BitmapCpc.NbLig >> 1 : BitmapCpc.NbLig; } // Recherche les "coordonnées" de l'image différente par rapport à la précédente for (int l = lStart; l < lEnd; l += modeLigne) { int adr = BitmapCpc.GetAdrCpc(l << 1); for (int oct = xStart; oct < xEnd; oct++) { if (img.bitmapCpc.bmpCpc[adr + oct] != BufPrec[adr + oct]) { xDeb = Math.Min(xDeb, oct); xFin = Math.Max(xFin, oct); yDeb = Math.Min(yDeb, l); yFin = Math.Max(yFin, l); BufPrec[adr + oct] = img.bitmapCpc.bmpCpc[adr + oct]; } } } int tailleX = xFin > xDeb ? xFin - xDeb + 1 : 0; int tailleY = (yFin + 1 - yDeb) / modeLigne; int length = tailleX * tailleY; if (length > 0) { Array.Clear(bLigne, 0, bLigne.Length); int pos = 0, AdrEcr; bLigne[pos++] = (byte)tailleX; bLigne[pos++] = (byte)tailleY; if (!optimSpeed) { AdrEcr = 0xC000 + xDeb + (yDeb >> 3) * BitmapCpc.NbCol + (yDeb & 7) * 0x800; bLigne[pos++] = (byte)(AdrEcr & 0xFF); bLigne[pos++] = (byte)(AdrEcr >> 8); } if (chkCol.Checked) { // passage en mode "colonne par colonne" for (int x = xDeb; x <= xFin; x++) { for (int l = 0; l < tailleY * modeLigne; l += modeLigne) { int offsetEcr = ((l + yDeb) >> 3) * BitmapCpc.NbCol + ((l + yDeb) & 7) * 0x800 + x; if (optimSpeed) { AdrEcr = 0xC000 + offsetEcr; bLigne[pos++] = (byte)(AdrEcr & 0xFF); bLigne[pos++] = (byte)(AdrEcr >> 8); } bLigne[pos++] = BufPrec[offsetEcr]; } } } else { // Passage en mode "ligne à ligne" for (int l = yDeb; l <= yFin; l += modeLigne) { int offsetEcr = (l >> 3) * BitmapCpc.NbCol + (l & 7) * 0x800 + xDeb; if (optimSpeed) { AdrEcr = 0xC000 + offsetEcr; bLigne[pos++] = (byte)(AdrEcr & 0xFF); bLigne[pos++] = (byte)(AdrEcr >> 8); } Array.Copy(BufPrec, offsetEcr, bLigne, pos, tailleX); pos += tailleX; } } int lpack = PackDepack.Pack(bLigne, pos, bufOut, 0); sizeDepack = length + 4; return(lpack); } else { return(0); } }
static public int Convert(Bitmap source, BitmapCpc dest, Param p, bool triangle) { int[] CChoix = new int[16]; Tx = 4 >> (dest.ModeCPC == 3 ? 1 : dest.ModeCPC); MaxCol = 1 << Tx; for (int i = 0; i < 16; i++) { CChoix[i] = dest.Palette[i]; } tailleX = dest.TailleX; tailleY = dest.TailleY; double ratio = source.Width * tailleY / (double)(source.Height * tailleX); Bitmap tmp = new Bitmap(tailleX, tailleY); Graphics g = Graphics.FromImage(tmp); switch (p.sizeMode) { case Param.SizeMode.KeepSmaller: if (ratio < 1) { int newW = (int)(tailleX * ratio); g.DrawImage(source, (tailleX - newW) >> 1, 0, newW, tailleY); } else { int newH = (int)(tailleY / ratio); g.DrawImage(source, 0, (tailleY - newH) >> 1, tailleX, newH); } bitmap = new LockBitmap(tmp); break; case Param.SizeMode.KeepLarger: if (ratio < 1) { int newY = (int)(tailleY / ratio); g.DrawImage(source, 0, (tailleY - newY) >> 1, tailleX, newY); } else { int newX = (int)(tailleX * ratio); g.DrawImage(source, (tailleX - newX) >> 1, 0, newX, tailleY); } bitmap = new LockBitmap(tmp); break; case Param.SizeMode.Fit: bitmap = new LockBitmap(new Bitmap(source, tailleX, tailleY)); break; } bitmap.LockBits(); int nbCol = ConvertPasse1(tailleX, tailleY, p.methode, p.matrice, p.pct, p.cpcPlus, p.newMethode, dest.ModeCPC, p.cpcPlus, p.reductPal1, p.reductPal2, p.newReduct, p.pctLumi, p.pctSat, p.pctContrast); //Bitmap b = bitmap.UnlockBits(); //b.Save(@"C:\Users\deplanql\Desktop\Test.png",System.Drawing.Imaging.ImageFormat.Png); //bitmap.LockBits(); RechercheCMax(CChoix, p.lockState, p.cpcPlus, p.sortPal); Passe2(dest, CChoix, p.cpcPlus, triangle ? 4 : p.pixMode); for (int i = 0; i < 16; i++) { dest.SetPalette(i, CChoix[i]); } bitmap.UnlockBits(); return(nbCol); }
public byte[] GetCpcScr(Param param, bool spriteMode = false) { int maxSize = (BitmapCpc.TailleX >> 3) + ((BitmapCpc.TailleY - 2) >> 4) * (BitmapCpc.TailleX >> 3) + ((BitmapCpc.TailleY - 2) & 14) * 0x400; if (spriteMode) { maxSize = (BitmapCpc.TailleX * BitmapCpc.TailleY) >> 4; } else if (maxSize >= 0x4000) { maxSize += 0x3800; } byte[] ret = new byte[maxSize]; Array.Clear(ret, 0, ret.Length); int posRet = 0; for (int y = 0; y < BitmapCpc.TailleY; y += 2) { int adrCPC = BitmapCpc.GetAdrCpc(y); int tx = BitmapCpc.CalcTx(y); for (int x = 0; x < BitmapCpc.TailleX; x += 8) { byte pen = 0, octet = 0; for (int p = 0; p < 8; p++) { if ((p % tx) == 0) { RvbColor col = BmpLock.GetPixelColor(x + p, y); if (BitmapCpc.cpcPlus) { for (pen = 0; pen < 16; pen++) { if ((col.v >> 4) == (BitmapCpc.Palette[pen] >> 8) && (col.r >> 4) == ((BitmapCpc.Palette[pen] >> 4) & 0x0F) && (col.b >> 4) == (BitmapCpc.Palette[pen] & 0x0F)) { break; } } } else { for (pen = 0; pen < 16; pen++) { RvbColor fixedCol = BitmapCpc.RgbCPC[BitmapCpc.Palette[pen]]; if (fixedCol.r == col.r && fixedCol.b == col.b && fixedCol.v == col.v) { break; } } } octet |= (byte)(tabOctetMode[pen] >> (p / tx)); } } if (!spriteMode) { posRet = BitmapCpc.GetAdrCpc(y) + (x >> 3); } ret[posRet++] = octet; } } return(ret); }
static public int SauveScr(string fileName, BitmapCpc bitmapCpc, ImageCpc img, Param param, bool compact, string version = null, int[,] colMode5 = null) { byte[] bufPack = new byte[0x8000]; bool overscan = (BitmapCpc.NbLig * BitmapCpc.NbCol > 0x3F00); if (param.withPalette && version == null) { if (param.cpcPlus) { ModePal[0] = (byte)(BitmapCpc.modeVirtuel | 0x8C); int k = 1; for (int i = 0; i < 16; i++) { ModePal[k++] = (byte)(((BitmapCpc.Palette[i] >> 4) & 0x0F) | (BitmapCpc.Palette[i] << 4)); ModePal[k++] = (byte)(BitmapCpc.Palette[i] >> 8); } } else { ModePal[0] = (byte)BitmapCpc.modeVirtuel; for (int i = 0; i < 16; i++) { ModePal[1 + i] = (byte)BitmapCpc.Palette[i]; } } } byte[] imgCpc = bitmapCpc.bmpCpc; if (!overscan) { Buffer.BlockCopy(ModePal, 0, imgCpc, 0x17D0, ModePal.Length); if (param.withCode && version == null) { if (param.cpcPlus) { Buffer.BlockCopy(CodeP0, 0, imgCpc, 0x07D0, CodeP0.Length); Buffer.BlockCopy(CodeP1, 0, imgCpc, 0x0FD0, CodeP1.Length); Buffer.BlockCopy(CodeP3, 0, imgCpc, 0x1FD0, CodeP3.Length); } else { Buffer.BlockCopy(CodeStd, 0, imgCpc, 0x07D0, CodeStd.Length); } if (BitmapCpc.modeVirtuel == 3 || BitmapCpc.modeVirtuel == 4) { Buffer.BlockCopy(codeEgx0, 0, imgCpc, 0x37D0, codeEgx0.Length); Buffer.BlockCopy(codeEgx1, 0, imgCpc, 0x2FD0, codeEgx1.Length); imgCpc[0x07F2] = 0xD0; imgCpc[0x07F3] = 0xF7; // CALL 0xF7D0 imgCpc[0x37FA] = 0xEF; // Call 0xEFD0 } } } else { if (BitmapCpc.NbLig * BitmapCpc.NbCol > 0x4000) { Buffer.BlockCopy(ModePal, 0, imgCpc, 0x600, ModePal.Length); if (param.withCode && version == null) { if (param.cpcPlus) { Buffer.BlockCopy(CodeOvP, 0, imgCpc, 0x621, CodeOvP.Length); } else { Buffer.BlockCopy(CodeOv, 0, imgCpc, 0x611, CodeOv.Length); } if (BitmapCpc.modeVirtuel == 3 || BitmapCpc.modeVirtuel == 4) { Buffer.BlockCopy(codeEgx0, 0, imgCpc, 0x1600, codeEgx0.Length); Buffer.BlockCopy(codeEgx1, 0, imgCpc, 0x1640, codeEgx1.Length); if (param.cpcPlus) { imgCpc[0x669] = 0xCD; imgCpc[0x66A] = 0x00; imgCpc[0x66B] = 0x18; // CALL #1800 } else { imgCpc[0x631] = 0x00; imgCpc[0x632] = 0x18; // CALL #1800 } imgCpc[0x1629] = 0x40; imgCpc[0x162A] = 0x18; // CALL #1840 } } } } short startAdr = (short)(overscan ? 0x200 : 0xC000); short exec = (short)(overscan ? param.cpcPlus ? 0x821 : 0x811 : 0xC7D0); CpcAmsdos entete; int lg = BitmapCpc.BitmapSize; if (compact) { lg = PackDepack.Pack(bitmapCpc.bmpCpc, lg, bufPack, 0) + 1; // Prendre 1 octet de marge ? if (param.withCode && version == null) { Buffer.BlockCopy(codeDepack, 0, bufPack, lg, codeDepack.Length); bufPack[lg + 4] = (byte)(startAdr & 0xFF); bufPack[lg + 5] = (byte)(startAdr >> 8); startAdr = (short)(0xA657 - (lg + codeDepack.Length)); bufPack[lg + 1] = (byte)(startAdr & 0xFF); bufPack[lg + 2] = (byte)(startAdr >> 8); bufPack[lg + 32] = (byte)(exec & 0xFF); bufPack[lg + 33] = (byte)(exec >> 8); lg += codeDepack.Length; exec = (short)(0xA657 - codeDepack.Length); } else { startAdr = (short)(0xA657 - lg); exec = 0; } } if (version != null) { // Sauvegarde source assembleur StreamWriter sw = SaveAsm.OpenAsm(fileName, version); int org = 0xA500 - lg - (BitmapCpc.modeVirtuel == 5 ? 600 : 0); sw.WriteLine(" ORG #"+ org.ToString("X4")); sw.WriteLine(" Nolist"); sw.WriteLine("ImageCmp:"); SaveAsm.GenereDatas(sw, bufPack, lg, 16); sw.WriteLine(" List"); if (param.withCode) { sw.WriteLine(" RUN $"); sw.WriteLine("_StartDepack:"); if (BitmapCpc.modeVirtuel == 3 || BitmapCpc.modeVirtuel == 4) { SaveAsm.GenereAfficheModeEgx(sw, BitmapCpc.Palette, overscan); } else { SaveAsm.GenereFormatEcran(sw); if (BitmapCpc.modeVirtuel == 5) { SaveAsm.GenereAfficheModeX(sw, colMode5, overscan); } else { SaveAsm.GenereAfficheStd(sw, img, BitmapCpc.modeVirtuel, BitmapCpc.Palette, overscan); } } } SaveAsm.CloseAsm(sw); } else { entete = CpcSystem.CreeEntete(fileName, startAdr, (short)lg, exec); BinaryWriter fp = new BinaryWriter(new FileStream(fileName, FileMode.Create)); fp.Write(CpcSystem.AmsdosToByte(entete)); fp.Write(compact ? bufPack : bitmapCpc.bmpCpc, 0, lg); fp.Close(); } return(lg); }
static void SetPixColTriangle(BitmapCpc dest) { int[,] matTri = new int[4, 4] { { 0, 0, 0, 1 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 1, 0, 0, 0 } }; int index = 0, pos = 0, nb1 = 0; for (int i1 = 0; i1 < 4; i1++) { for (int i2 = 0; i2 < 4; i2++) { if (matTri[i1, i2] == 1) { nb1++; } } } for (int i1 = 0; i1 < 4; i1++) { for (int i2 = 0; i2 < 4; i2++) { int sr = tabCol[i1].red * (16 - nb1) + tabCol[i2].red * nb1; int sv = tabCol[i1].green * (16 - nb1) + tabCol[i2].green * nb1; int sb = tabCol[i1].blue * (16 - nb1) + tabCol[i2].blue * nb1; tabMelange[pos++] = new RvbColor(sr, sv, sb); } } int choix0 = 0, choix1 = 0; for (int y = 0; y < tailleY; y += 8) { for (int x = 0; x < tailleX; x += 8) { int OldDist = 0x7FFFFFFF; int totR = 0, totV = 0, totB = 0; for (int i1 = 0; i1 < 4; i1++) { for (int i2 = 0; i2 < 4; i2++) { bitmap.AddGetPixel(x + 2 * i2 < tailleX ? x + 2 * i2 : x + 1, y + 2 * i1 < tailleY ? y + 2 * i1 : y + 1, ref totR, ref totV, ref totB); } } pos = 0; for (int i1 = 0; i1 < 4; i1++) { for (int i2 = 0; i2 < 4; i2++) { int Dist = CalcDist(tabMelange[pos].red, tabMelange[pos].green, tabMelange[pos].blue, totR, totV, totB); pos++; if (Dist < OldDist) { choix0 = i1; choix1 = i2; OldDist = Dist; if (Dist == 0) { i1 = i2 = 4; } } } } resultTri[index++] = choix0 + (choix1 << 2); for (int i1 = 0; i1 < 4; i1++) { for (int i2 = 0; i2 < 4; i2++) { dest.SetPixelCpc(x + 2 * i2 < tailleX ? x + 2 * i2 : x + 1, y + 2 * i1 < tailleY ? y + 2 * i1 : y + 1, matTri[i1, i2] == 0 ? choix0 : choix1); } } } } }
static void SetPixCol3(BitmapCpc dest) { int pos = 0; for (int i1 = 0; i1 < MaxCol; i1++) { for (int i2 = 0; i2 < MaxCol; i2++) { for (int i3 = 0; i3 < MaxCol; i3++) { for (int i4 = 0; i4 < MaxCol; i4++) { int sr = tabCol[i1].red + tabCol[i2].red + tabCol[i3].red + tabCol[i4].red; int sv = tabCol[i1].green + tabCol[i2].green + tabCol[i3].green + tabCol[i4].green; int sb = tabCol[i1].blue + tabCol[i2].blue + tabCol[i3].blue + tabCol[i4].blue; tabMelange[pos++] = new RvbColor(sr, sv, sb); } } } } int choix0 = 0, choix2 = 0, choix3 = 0, choix1 = 0; for (int y = 0; y < tailleY; y += 4) { int ynorm = y + 2 < tailleY ? y + 2 : y + 1; for (int x = 0; x < tailleX; x += Tx << 1) { int xnorm = x + Tx < tailleX ? x + Tx : x + 1; int OldDist = 0x7FFFFFFF; int totR = 0, totV = 0, totB = 0; bitmap.GetPixel(x, y, ref totR, ref totV, ref totB); bitmap.AddGetPixel(x, ynorm, ref totR, ref totV, ref totB); bitmap.AddGetPixel(xnorm, y, ref totR, ref totV, ref totB); bitmap.AddGetPixel(xnorm, ynorm, ref totR, ref totV, ref totB); pos = 0; for (int i1 = 0; i1 < MaxCol; i1++) { for (int i2 = 0; i2 < MaxCol; i2++) { for (int i3 = 0; i3 < MaxCol; i3++) { for (int i4 = 0; i4 < MaxCol; i4++) { int Dist = CalcDist(tabMelange[pos].red, tabMelange[pos].green, tabMelange[pos].blue, totR, totV, totB); pos++; if (Dist < OldDist) { choix0 = i1; choix1 = i2; choix2 = i3; choix3 = i4; OldDist = Dist; if (Dist == 0) { i1 = i2 = i3 = i4 = MaxCol; } } } } } } dest.SetPixelCpc(x, y, choix0); dest.SetPixelCpc(x, ynorm, choix2); dest.SetPixelCpc(xnorm, y, choix3); dest.SetPixelCpc(xnorm, ynorm, choix1); } } }