public CImage(CImage inp) // copy-constructor
 {
     this.width  = inp.width;
     this.height = inp.height;
     this.N_Bits = inp.N_Bits;
     this.Grid   = new byte[width * height * (N_Bits / 8)];
     for (int i = 0; i < width * height * (N_Bits / 8); i++)
     {
         Grid[i] = inp.Grid[i];
     }
 }
示例#2
0
        private void button2_Click(object sender, EventArgs e) // Restore
        {
            int    nBits     = LiCod.nBits;
            int    width     = LiCod.width;
            int    height    = LiCod.height;
            CImage RestoreIm = new CImage(width, height, nBits);
            CImage Mask      = new CImage(width, height, 8);

            LiCod.Restore(ref RestoreIm, ref Mask, this);

            RestoreIm.Smooth(ref Mask, this);
            RestoreBMP = new Bitmap(width, height, PixelFormat.Format24bppRgb);
            GridToBitmapNew(RestoreBMP, RestoreIm);

            progressBar1.Visible = false;
            pictureBox1.Image    = RestoreBMP;
            button2.Visible      = false;
            label2.Visible       = true;
        } //******************************** end Restore ********************************
示例#3
0
        } //****************************** end Open file **************************************

        public void GridToBitmapNew(Bitmap bmp, CImage Image)
        {
            int nbyteI = Image.N_Bits / 8;

            if (bmp.PixelFormat != PixelFormat.Format24bppRgb)
            {
                MessageBox.Show("GridToBitmapNew: Inappropriate pixel format=" + bmp.PixelFormat);
                return;
            }

            int jump, Len = bmp.Height, nStep = 30;

            if (Len > 2 * nStep)
            {
                jump = Len / nStep;
            }
            else
            {
                jump = 2;
            }
            for (int y = 0; y < bmp.Height; y++)
            {
                if ((y % jump) == jump - 1)
                {
                    progressBar1.PerformStep();
                }
                for (int x = 0; x < bmp.Width; x++)
                {
                    if (nbyteI == 3)
                    {
                        bmp.SetPixel(x, y, Color.FromArgb(Image.Grid[nbyteI * (x + bmp.Width * y) + 2],
                                                          Image.Grid[nbyteI * (x + bmp.Width * y) + 1], Image.Grid[nbyteI * (x + bmp.Width * y) + 0]));
                    }
                    else
                    {
                        bmp.SetPixel(x, y, Color.FromArgb(Image.Grid[x + bmp.Width * y],
                                                          Image.Grid[x + bmp.Width * y], Image.Grid[x + bmp.Width * y]));
                    }
                }
            }
            progressBar1.Visible = false;
        } //****************************** end GridToBitmapNew ****************************************
      public int AverageSmall(CImage Inp)
      // Filters the image "Inp" with the weights "Weight" in a 3x3 window and saves the results
      // in "this.Grid".
      {
          N_Bits = Inp.N_Bits; width = Inp.width; height = Inp.height;
          int[] Weight = { 1, 2, 1, 2, 4, 2, 1, 2, 1 };

          int SumWeight = 0, Sum = 0;

          for (int y = 0; y < height; y++)    //============================================================================
          {
              for (int x = 0; x < width; x++) //========================================================================
              {
                  if (Inp.N_Bits == 8)        //----------------------------------------------------------------------
                  {
                      Sum = 0; SumWeight = 0;

                      for (int j = -1; j < 2; j++)
                      {
                          for (int i = -1; i < 2; i++)
                          {
                              int xx = x + i; int yy = y + j;
                              if (xx >= 0 && xx < width && yy >= 0 && yy < height)
                              {
                                  Sum       += Weight[i + 1 + 3 * (j + 1)] * Inp.Grid[xx + width * yy];
                                  SumWeight += Weight[i + 1 + 3 * (j + 1)];

                                  if (SumWeight <= 0)
                                  {
                                      return(-1);
                                  }
                              }
                          }
                      }
                      Grid[x + width * y] = (byte)((Sum + SumWeight / 2) / SumWeight);
                  }           //-------------------------------------- end if (Inp.N_Bits... --------------------------
                  else        //Inp.N_Bits==24
                  {
                      int[] SumC = new int[3];
                      for (int c = 0; c < 3; c++)
                      {
                          SumC[c] = 0;
                      }

                      for (int j = -1; j < 2; j++)
                      {
                          for (int i = -1; i < 2; i++)
                          {
                              int xx = x + i; int yy = y + j;
                              if (xx >= 0 && xx < width && yy >= 0 && yy < height)
                              {
                                  for (int c = 0; c < 3; c++)
                                  {
                                      SumC[c] += Weight[i + 1 + 3 * (j + 1)] * Inp.Grid[3 * (xx + width * yy) + c];
                                  }
                                  SumWeight += Weight[i + 1 + 3 * (j + 1)];
                                  if (SumWeight <= 0)
                                  {
                                      return(-1);
                                  }
                              }
                          }
                      }
                      for (int c = 0; c < 3; c++)
                      {
                          Grid[3 * (x + width * y) + c] = (byte)((SumC[c] + SumWeight / 2) / SumWeight);
                      }
                  } //-------------------------------------- end if (Inp.N_Bits... --------------------------
              }     //======================================== end for (x... ====================================
          }         //========================================== end for (y... ======================================
          return(1);
      } //******************************************** end AverageSmall *************************************
      } //******************************************** end AverageSmall *************************************

      public int Smooth(ref CImage Mask, Form1 fm1)
      // Calculates the average colors between "gvbeg" and "gvend" and saves them in the image "this".
      // This is a digital automaton with the states S=1 at Mask>0 and S=2 at Mask==0, but S is not used.
      // The variable "mpre" has the value of "Mask" in the previouse pixel.
      {
          int c, cnt, LabMask = 250, msk, mpre, x, xx, xbeg, xend, ybeg, yend, y, yy;

          int[] Col = new int[3], ColBeg = new int[3], ColEnd = new int[3];

          int nbyte;

          if (N_Bits == 24)
          {
              nbyte = 3;
          }
          else
          {
              nbyte = 1;
          }

          // Smoothing the borders:
          // Border at y=0:
          y = 0; cnt = 0; xbeg = 0; mpre = 200;
          for (c = 0; c < nbyte; c++)
          {
              ColBeg[c] = Grid[c];
          }

          int jump, Len = width, nStep = 4;

          if (Len > 2 * nStep)
          {
              jump = Len / nStep;
          }
          else
          {
              jump = 2;
          }
          for (x = 0; x < width; x++) //==========================================================
          {
              if ((x % jump) == jump - 1)
              {
                  fm1.progressBar1.PerformStep();
              }
              msk = Mask.Grid[x + width * y];
              if (mpre > 0 && msk == 0) //----------------------------------------
              {
                  cnt = 1; xbeg = x - 1;
                  for (c = 0; c < nbyte; c++)
                  {
                      ColBeg[c] = Grid[nbyte * (x - 1 + width * y) + c];
                  }
              }
              if (mpre == 0 && msk == 0) //----------------------------------------
              {
                  cnt++;
              }
              if (mpre == 0 && msk > 0) //----------------------------------------
              {
                  cnt++; xend = x;
                  for (c = 0; c < nbyte; c++)
                  {
                      ColEnd[c] = Grid[nbyte * (x + width * y) + c];
                  }
                  for (xx = xbeg + 1; xx < xend; xx++) //==========================================
                  {
                      for (c = 0; c < nbyte; c++)
                      {
                          Grid[nbyte * (xx + width * y) + c] = (byte)((ColBeg[c] * (xend - xx) + ColEnd[c] * (xx - xbeg)) / cnt);
                      }
                      Mask.Grid[xx + width * y] = (byte)LabMask;
                  } //============== end for (xx... ========================================
              }
              mpre = msk;
          } //=============== end for (x=0; ... ===========================================

          // Border at y=height-1:
          y = height - 1; cnt = 0; xbeg = 0; mpre = 200;
          for (c = 0; c < nbyte; c++)
          {
              ColBeg[c] = Grid[nbyte * width * y + c];
          }

          Len   = width;
          nStep = 4;
          if (Len > 2 * nStep)
          {
              jump = Len / nStep;
          }
          else
          {
              jump = 2;
          }
          for (x = 0; x < width; x++) //==========================================================
          {
              if ((x % jump) == jump - 1)
              {
                  fm1.progressBar1.PerformStep();
              }
              msk = Mask.Grid[x + width * y];
              if (mpre > 0 && msk == 0) //----------------------------------------
              {
                  cnt = 1; xbeg = x - 1;
                  for (c = 0; c < nbyte; c++)
                  {
                      ColBeg[c] = Grid[nbyte * (x - 1 + width * y) + c];
                  }
              }
              if (mpre == 0 && msk == 0) //----------------------------------------
              {
                  cnt++;
              }
              if (mpre == 0 && msk > 0) //----------------------------------------
              {
                  cnt++; xend = x;
                  for (c = 0; c < nbyte; c++)
                  {
                      ColEnd[c] = Grid[nbyte * (x + width * y) + c];
                  }
                  for (xx = xbeg + 1; xx < xend; xx++)
                  {
                      for (c = 0; c < nbyte; c++)
                      {
                          Grid[nbyte * (xx + width * y) + c] = (byte)((ColBeg[c] * (xend - xx) + ColEnd[c] * (xx - xbeg)) / cnt);
                      }
                      Mask.Grid[xx + width * y] = (byte)LabMask;
                  }
              }
              mpre = msk;
          } //=============== end for (x=0; ... ===========================================


          // Border at x=0
          x = 0; cnt = 0; ybeg = 0; mpre = 200;
          for (c = 0; c < nbyte; c++)
          {
              ColBeg[c] = Grid[nbyte * (x + width * 0) + c];
          }

          Len   = height;
          nStep = 4;
          if (Len > 2 * nStep)
          {
              jump = Len / nStep;
          }
          else
          {
              jump = 2;
          }
          for (y = 0; y < height; y++) //=================================================
          {
              if ((y % jump) == jump - 1)
              {
                  fm1.progressBar1.PerformStep();
              }
              msk = Mask.Grid[x + width * y];
              if (mpre > 0 && msk == 0) //----------------------------------------
              {
                  cnt = 1; ybeg = y - 1;
                  for (c = 0; c < nbyte; c++)
                  {
                      ColBeg[c] = Grid[nbyte * (x + width * (y - 1)) + c];
                  }
              }
              if (mpre == 0 && msk == 0) //----------------------------------------
              {
                  cnt++;
              }
              if (mpre == 0 && msk > 0) //----------------------------------------
              {
                  cnt++; yend = y;
                  for (c = 0; c < nbyte; c++)
                  {
                      ColEnd[c] = Grid[nbyte * (x + width * y) + c];
                  }
                  for (yy = ybeg + 1; yy < yend; yy++)
                  {
                      for (c = 0; c < nbyte; c++)
                      {
                          Col[c] = (ColBeg[c] * (yend - yy) + ColEnd[c] * (yy - ybeg)) / cnt;
                          Grid[nbyte * (x + width * yy) + c] = (byte)Col[c];
                      }
                      Mask.Grid[x + width * yy] = (byte)LabMask;
                  }
              }
              mpre = msk;
          } //=============== end for (y=0; ... ==================================

          // Border at x=width-1
          x = width - 1; cnt = 0; ybeg = 0; mpre = 200;
          for (c = 0; c < nbyte; c++)
          {
              ColBeg[c] = Grid[nbyte * (x + width * 0) + c];
          }
          Len   = height;
          nStep = 4;
          if (Len > 2 * nStep)
          {
              jump = Len / nStep;
          }
          else
          {
              jump = 2;
          }
          for (y = 0; y < height; y++) //=================================================
          {
              if ((y % jump) == jump - 1)
              {
                  fm1.progressBar1.PerformStep();
              }
              msk = Mask.Grid[x + width * y];
              if (mpre > 0 && msk == 0) //----------------------------------------
              {
                  cnt = 1; ybeg = y - 1;
                  for (c = 0; c < nbyte; c++)
                  {
                      ColBeg[c] = Grid[nbyte * (x + width * (y - 1)) + c];
                  }
              }
              if (mpre == 0 && msk == 0) //----------------------------------------
              {
                  cnt++;
              }
              if (mpre == 0 && msk > 0) //----------------------------------------
              {
                  cnt++; yend = y;
                  for (c = 0; c < nbyte; c++)
                  {
                      ColEnd[c] = Grid[nbyte * (x + width * y) + c];
                  }
                  for (yy = ybeg + 1; yy < yend; yy++)
                  {
                      for (c = 0; c < nbyte; c++)
                      {
                          Col[c] = (ColBeg[c] * (yend - yy) + ColEnd[c] * (yy - ybeg)) / cnt;
                          Grid[nbyte * (x + width * yy) + c] = (byte)Col[c];
                      }
                      Mask.Grid[x + width * yy] = (byte)LabMask;
                  }
              }
              mpre = msk;
          } //=============== end for (y=0; ... ==================================

          // End smoothin border; Smooth on "x":
          Len   = height;
          nStep = 4;
          if (Len > 2 * nStep)
          {
              jump = Len / nStep;
          }
          else
          {
              jump = 2;
          }
          for (y = 0; y < height; y++) //========================================================
          {
              if ((y % jump) == jump - 1)
              {
                  fm1.progressBar1.PerformStep();
              }
              cnt = 0; xbeg = 0; mpre = 200;
              for (c = 0; c < nbyte; c++)
              {
                  ColBeg[c] = Grid[nbyte * width * y + c];
              }
              for (x = 0; x < width; x++) //=====================================================
              {
                  msk = Mask.Grid[x + width * y];
                  if (mpre > 0 && msk == 0) //----------------------------------------
                  {
                      cnt = 1; xbeg = x - 1;
                      for (c = 0; c < nbyte; c++)
                      {
                          ColBeg[c] = Grid[nbyte * (x - 1 + width * y) + c];
                      }
                  }
                  if (mpre == 0 && msk == 0) //----------------------------------------
                  {
                      cnt++;
                  }
                  if (mpre == 0 && msk > 0) //----------------------------------------
                  {
                      cnt++; xend = x;
                      for (c = 0; c < nbyte; c++)
                      {
                          ColEnd[c] = Grid[nbyte * (x + width * y) + c];
                      }
                      for (xx = xbeg + 1; xx < xend; xx++)
                      {
                          for (c = 0; c < nbyte; c++)
                          {
                              Grid[nbyte * (xx + width * y) + c] = (byte)((ColBeg[c] * (xend - xx) + ColEnd[c] * (xx - xbeg)) / cnt);
                          }
                      }
                  }
                  mpre = msk;
              } //=============== end for (x=0; ... ========================================
          }     //================= end for (y=0; ... ==========================================

          // Smooth on "y":
          Len   = width;
          nStep = 4;
          if (Len > 2 * nStep)
          {
              jump = Len / nStep;
          }
          else
          {
              jump = 2;
          }
          for (x = 0; x < width; x++) //=====================================================
          {
              if ((x % jump) == jump - 1)
              {
                  fm1.progressBar1.PerformStep();
              }
              cnt = 0; ybeg = 0; mpre = 200;
              for (c = 0; c < nbyte; c++)
              {
                  ColBeg[c] = Grid[nbyte * (x + width * 0) + c];
              }
              for (y = 0; y < height; y++) //=================================================
              {
                  msk = Mask.Grid[x + width * y];
                  if (mpre > 0 && msk == 0) //----------------------------------------
                  {
                      cnt = 1; ybeg = y - 1;
                      for (c = 0; c < nbyte; c++)
                      {
                          ColBeg[c] = Grid[nbyte * (x + width * (y - 1)) + c];
                      }
                  }
                  if (mpre == 0 && msk == 0) //----------------------------------------
                  {
                      cnt++;
                  }
                  if (mpre == 0 && msk > 0) //---------------------------------------------------------------
                  {
                      cnt++; yend = y; for (c = 0; c < nbyte; c++)
                      {
                          ColEnd[c] = Grid[nbyte * (x + width * y) + c];
                      }
                      for (yy = ybeg + 1; yy < yend; yy++)
                      {
                          for (c = 0; c < nbyte; c++)
                          {
                              Col[c] = (Grid[nbyte * (x + width * yy) + c] + (ColBeg[c] * (yend - yy) + ColEnd[c] * (yy - ybeg)) / cnt) / 2;
                              Grid[nbyte * (x + width * yy) + c] = (byte)Col[c];
                          }
                      }
                  }
                  mpre = msk;
              } //=============== end for (y=0; ... ===================================================
          }     //================= end for (x=0; ... =====================================================

          // Solving the Laplace's equation:
          int    i;
          double fgv, omega = 1.4 / 4.0, dMaxLap = 0.0, dTH = 1.0;

          double[] dGrid = new double[width * height * nbyte];
          double[] Lap   = new double[3];
          for (i = 0; i < width * height * nbyte; i++)
          {
              dGrid[i] = (double)Grid[i];
          }

          Len   = 50;
          nStep = 6;
          if (Len > 2 * nStep)
          {
              jump = Len / nStep;
          }
          else
          {
              jump = 2;
          }
          for (int iter = 0; iter < 50; iter++) //-----------------------------------------------------------------------------
          {
              if ((iter % jump) == jump - 1)
              {
                  fm1.progressBar1.PerformStep();
              }
              for (y = 1; y < height - 1; y++)
              {
                  for (x = 1; x < width - 1; x++)
                  {
                      if (Mask.Grid[x + width * y] == 0 && Math.Abs((x - y)) % 2 == 0)
                      {
                          for (c = 0; c < nbyte; c++)
                          {
                              Lap[c]  = 0.0;
                              Lap[c] += dGrid[nbyte * (x + width * (y - 1)) + c];
                              Lap[c] += dGrid[nbyte * (x - 1 + width * y) + c];
                              Lap[c] += dGrid[nbyte * (x + 1 + width * y) + c];
                              Lap[c] += dGrid[nbyte * (x + width * (y + 1)) + c];
                              Lap[c] -= 4.0 * dGrid[nbyte * (x + width * y) + c];
                              fgv     = dGrid[nbyte * (x + width * y) + c] + omega * Lap[c];
                              if (fgv > 255.0)
                              {
                                  fgv = 255.0;
                              }
                              if (fgv < 0.0)
                              {
                                  fgv = 0;
                              }
                              dGrid[nbyte * (x + width * y) + c] = fgv;
                          }
                      }
                  }
              }
              // Smooth at Math.Abs((x - y)) % 2 == 1
              for (y = 1; y < height - 1; y++)
              {
                  for (x = 1; x < width - 1; x++)
                  {
                      if (Mask.Grid[x + width * y] == 0 && Math.Abs((x - y)) % 2 == 1)
                      {
                          for (c = 0; c < nbyte; c++)
                          {
                              Lap[c]  = 0.0;
                              Lap[c] += dGrid[nbyte * (x + width * (y - 1)) + c];
                              Lap[c] += dGrid[nbyte * (x - 1 + width * y) + c];
                              Lap[c] += dGrid[nbyte * (x + 1 + width * y) + c];
                              Lap[c] += dGrid[nbyte * (x + width * (y + 1)) + c];
                              Lap[c] -= 4.0 * dGrid[nbyte * (x + width * y) + c];
                              fgv     = dGrid[nbyte * (x + width * y) + c] + omega * Lap[c];
                              if (fgv > 255.0)
                              {
                                  fgv = 255.0;
                              }
                              if (fgv < 0.0)
                              {
                                  fgv = 0;
                              }
                              dGrid[nbyte * (x + width * y) + c] = fgv; //(int)(fgv);
                          }
                      }
                  }
              }

              dMaxLap = 0.0; // Calculating MaxLap:
              for (y = 1; y < height - 1; y++)
              {
                  for (x = 1; x < width - 1; x++)        //===================================
                  {
                      if (Mask.Grid[x + width * y] == 0) //----------------------------
                      {
                          for (c = 0; c < nbyte; c++)    //==========================
                          {
                              Lap[c]  = 0.0;
                              Lap[c] += dGrid[nbyte * (x + width * (y - 1)) + c];
                              Lap[c] += dGrid[nbyte * (x - 1 + width * y) + c];
                              Lap[c] += dGrid[nbyte * (x + 1 + width * y) + c];
                              Lap[c] += dGrid[nbyte * (x + width * (y + 1)) + c];
                              Lap[c] -= 4.0 * dGrid[nbyte * (x + width * y) + c];
                              if (Math.Abs(Lap[c]) > dMaxLap)
                              {
                                  dMaxLap = Math.Abs(Lap[c]);
                              }
                          } //================= end for (c=0; =================
                      }     //------------------- end if (Mask... -----------------
                  }         //===================== end for (x=1; ... =================
              }
              int ii;
              for (ii = 0; ii < width * height * nbyte; ii++)
              {
                  Grid[ii] = (byte)dGrid[ii];
              }

              if (dMaxLap < dTH)
              {
                  break;
              }
          } //------------------------------------ end for (iter... ------------------------------------------

          return(0);
      } //************************************* end Smooth ***********************************************
示例#6
0
            } //***************************** end constructor **************************************

            public int Restore(ref CImage Image, ref CImage Mask, Form1 fm1)
            {
                int  dir, nbyte, x, y;
                byte LabMask = 250;

                if (nBits == 24)
                {
                    nbyte = 3;
                }
                else
                {
                    nbyte = 1;
                }

                fm1.progressBar1.Value   = 0;
                fm1.progressBar1.Visible = true;
                for (int i = 0; i < width * height * (nBits / 8); i++)
                {
                    Image.Grid[i] = 0;
                }

                for (int i = 0; i < width * height; i++)
                {
                    Mask.Grid[i] = 0;
                }

                if (nBits == 24)
                {
                    for (int c = 0; c < nbyte; c++)
                    {
                        Image.Grid[c] = (byte)((Palette[Corner[0]] >> 8 * (2 - c)) & 0XFF);                                  // left below
                        Image.Grid[nbyte * (width - 1) + c]            = (byte)((Palette[Corner[1]] >> 8 * (2 - c)) & 0XFF); // right below
                        Image.Grid[nbyte * width * height - nbyte + c] = (byte)((Palette[Corner[2]] >> 8 * (2 - c)) & 0XFF); // right on top
                        Image.Grid[nbyte * width * (height - 1) + c]   = (byte)((Palette[Corner[3]] >> 8 * (2 - c)) & 0XFF); // left on top
                    }
                }
                else
                {
                    Image.Grid[0]                        = Corner[0];
                    Image.Grid[width - 1]                = Corner[1];
                    Image.Grid[width * height - 1]       = Corner[2];
                    Image.Grid[0 + width * (height - 1)] = Corner[3];
                }
                Mask.Grid[0] = Mask.Grid[width - 1] = Mask.Grid[width * height - 1] = Mask.Grid[width * (height - 1)] = LabMask;

                // Short lines:
                fm1.progressBar1.Maximum = 100;
                fm1.progressBar1.Step    = 1;
                fm1.progressBar1.Value   = 0;
                int jump, Len = nLine1, nStep = 20;

                if (Len > 2 * nStep)
                {
                    jump = Len / nStep;
                }
                else
                {
                    jump = 2;
                }
                for (int il = 0; il < nLine1; il++) //=====================================================
                {
                    if ((il % jump) == jump - 1)
                    {
                        fm1.progressBar1.PerformStep();
                    }
                    dir = ((Line1[il].x >> 14) & 2) | (Line1[il].y >> 15);
                    x   = Line1[il].x & 0X7FFF;                   y = Line1[il].y & 0X7FFF;
                    if (nBits == 24)
                    {
                        switch (dir)
                        {
                        case 0: if (y > 0)
                            {
                                for (int c = 0; c < nbyte; c++)
                                {
                                    int  Index = Line1[il].Ind1;
                                    byte col   = (byte)(Palette[Index] >> 8 * c);
                                    Image.Grid[nbyte * (x + width * y) + 2 - c]       = col;
                                    Image.Grid[nbyte * (x + width * (y - 1)) + 2 - c] = (byte)((Palette[Line1[il].Ind0] >> 8 * c) & 0XFF);
                                }
                                Mask.Grid[x + width * y] = Mask.Grid[x + width * (y - 1)] = LabMask;
                            }
                            break;

                        case 1: for (int c = 0; c < nbyte; c++)
                            {
                                Image.Grid[nbyte * (x + width * y) + 2 - c]     = (byte)((Palette[Line1[il].Ind0] >> 8 * c) & 0XFF);
                                Image.Grid[nbyte * (x - 1 + width * y) + 2 - c] = (byte)((Palette[Line1[il].Ind1] >> 8 * c) & 0XFF);
                            }
                            Mask.Grid[x + width * y] = Mask.Grid[x - 1 + width * y] = LabMask;
                            break;

                        case 2: for (int c = 0; c < nbyte; c++)
                            {
                                Image.Grid[nbyte * (x - 1 + width * y) + 2 - c]       = (byte)((Palette[Line1[il].Ind0] >> 8 * c) & 0XFF);
                                Image.Grid[nbyte * (x - 1 + width * (y - 1)) + 2 - c] = (byte)((Palette[Line1[il].Ind1] >> 8 * c) & 0XFF);
                            }
                            Mask.Grid[x - 1 + width * y] = Mask.Grid[x - 1 + width * (y - 1)] = LabMask;
                            break;

                        case 3: for (int c = 0; c < nbyte; c++)
                            {
                                Image.Grid[nbyte * (x + width * (y - 1)) + 2 - c]     = (byte)((Palette[Line1[il].Ind1] >> 8 * c) & 0XFF);
                                Image.Grid[nbyte * (x - 1 + width * (y - 1)) + 2 - c] = (byte)((Palette[Line1[il].Ind0] >> 8 * c) & 0XFF);
                            }
                            Mask.Grid[x + width * (y - 1)] = Mask.Grid[x - 1 + width * (y - 1)] = LabMask;
                            break;
                        } //::::::::::::: end switch ::::::::::::::::::::::::::::::::::::::::::
                    }
                    else
                    {
                        switch (dir)
                        {
                        case 0: Image.Grid[x + width * y]   = Line1[il].Ind1;
                            Image.Grid[x + width * (y - 1)] = Line1[il].Ind0;
                            Mask.Grid[x + width * y]        = Mask.Grid[x + width * (y - 1)] = LabMask;
                            break;

                        case 1: Image.Grid[x + width * y] = Line1[il].Ind0;
                            Image.Grid[x - 1 + width * y] = Line1[il].Ind1;
                            Mask.Grid[x + width * y]      = Mask.Grid[x - 1 + width * y] = LabMask;
                            break;

                        case 2: Image.Grid[x - 1 + width * y]   = Line1[il].Ind0;
                            Image.Grid[x - 1 + width * (y - 1)] = Line1[il].Ind1;
                            Mask.Grid[x - 1 + width * y]        = Mask.Grid[x - 1 + width * (y - 1)] = LabMask;
                            break;

                        case 3: Image.Grid[x + width * (y - 1)] = Line1[il].Ind1;
                            Image.Grid[x - 1 + width * (y - 1)] = Line1[il].Ind0;
                            Mask.Grid[x + width * (y - 1)]      = Mask.Grid[x - 1 + width * (y - 1)] = LabMask;
                            break;
                        }       //::::::::::::: end switch ::::::::::::::::::::::::::::::::::::::::::
                    } //--------------- end if (nBits==24) ------------------------------------------
                } //================= end for (il < nLine1 ==========================================

                int first, last;

                int[] Shift = new int[] { 0, 2, 4, 6 };
                Len   = nLine2;
                nStep = 20;
                if (Len > 2 * nStep)
                {
                    jump = Len / nStep;
                }
                else
                {
                    jump = 2;
                }
                for (int il = 0; il < nLine2; il++) //====================================================================================================
                {
                    if ((il % jump) == jump - 1)
                    {
                        fm1.progressBar1.PerformStep();
                    }
                    if (il == 0)
                    {
                        first = 0;
                    }
                    else
                    {
                        first = Line2[il - 1].EndByte + 1;
                    }

                    last = Line2[il].EndByte;
                    x    = Line2[il].x;
                    y    = Line2[il].y;
                    int    iByte = first, iShift = 0;
                    iVect2 P = new iVect2(), PixelP = new iVect2(), PixelN = new iVect2(); // comb. coordinates

                    byte[] ColN      = new byte[3], ColP = new byte[3];
                    byte[] ColStartN = new byte[3], ColStartP = new byte[3],
                    ColLastN = new byte[3], ColLastP = new byte[3]; // Colors
                    for (int c = 0; c < 3; c++)
                    {
                        ColN[c] = ColP[c] = ColStartN[c] = ColStartP[c] = ColLastN[c] = ColLastP[c] = 0;
                    }

                    if (nBits == 24)
                    {
                        for (int c = 0; c < nbyte; c++)
                        {
                            ColStartN[2 - c] = (byte)((Palette[Line2[il].Ind0] >> 8 * c) & 255);
                            ColStartP[2 - c] = (byte)((Palette[Line2[il].Ind1] >> 8 * c) & 255);
                            ColLastN[2 - c]  = (byte)((Palette[Line2[il].Ind2] >> 8 * c) & 255);
                            ColLastP[2 - c]  = (byte)((Palette[Line2[il].Ind3] >> 8 * c) & 255);
                        }
                    }
                    else
                    {
                        ColStartN[0] = Line2[il].Ind0;
                        ColStartP[0] = Line2[il].Ind1;
                        ColLastN[0]  = Line2[il].Ind2;
                        ColLastP[0]  = Line2[il].Ind3;
                    }
                    P.X = Line2[il].x; P.Y = Line2[il].y;

                    int nCrack = Line2[il].nCrack;
                    int xx, yy;
                    // Interpolation:
                    for (int iC = 0; iC < nCrack; iC++) //=======================================================
                    {
                        dir = (Byte[iByte] & (3 << Shift[iShift])) >> Shift[iShift];
                        switch (dir)      // Standard coordinates
                        {
                        case 0: PixelP = P; PixelN = P + Step[3];     break;

                        case 1: PixelP = P + Step[2]; PixelN = P;       break;

                        case 2: PixelP = P + Step[2] + Step[3]; PixelN = P + Step[2];       break;

                        case 3: PixelP = P + Step[3]; PixelN = P + Step[2] + Step[3]; break;
                        }
                        if (PixelP.Y < 0 || PixelN.Y < 0 || PixelP.Y > height - 1 || PixelN.Y > height - 1)
                        {
                            MessageBox.Show("Restore: Bad 'PixelP' or 'PixelN'. This means 'Byte' is bad. iByte=" +
                                            iByte + "; dir=" + dir + "; Byte=" + Byte[iByte]);
                            MessageBox.Show("Restore: PixelP=(" + PixelP.X + "," + PixelP.Y + "); PixelN=(" + PixelN.X + ","
                                            + PixelN.Y + "); P=(" + P.X + "," + P.Y + ")");
                        }
                        for (int c = 0; c < nbyte; c++)                                                             //===================================================
                        {
                            ColN[c] = (byte)((ColLastN[c] * iC + ColStartN[c] * (nCrack - iC - 1)) / (nCrack - 1)); // Interpolation
                            ColP[c] = (byte)((ColLastP[c] * iC + ColStartP[c] * (nCrack - iC - 1)) / (nCrack - 1));
                        }                                                                                           //========================== end for (c... ================================

                        // Assigning colors to intermediate pixels of a line:
                        xx = PixelP.X; yy = PixelP.Y;
                        if (xx + width * yy > width * height - 1 || xx + width * yy < 0)
                        {
                            MessageBox.Show("Restore: Bad 'xx,yy'=" + (xx + width * yy) + "; This means 'Byte' is bad.");
                        }

                        if (xx + width * yy < width * height && xx + width * yy >= 0)
                        {
                            for (int c = 0; c < nbyte; c++)
                            {
                                Image.Grid[c + nbyte * xx + nbyte * width * yy] = ColP[c];                 // Assertion
                            }
                            Mask.Grid[xx + width * yy] = LabMask;
                        }
                        xx = PixelN.X; yy = PixelN.Y;
                        if (xx + width * yy > width * height - 1 || xx + width * yy < 0)
                        {
                            return(-1);
                        }

                        if (xx + width * yy < width * height && xx + width * yy >= 0)
                        {
                            for (int c = 0; c < nbyte; c++)
                            {
                                Image.Grid[c + nbyte * xx + nbyte * width * yy] = ColN[c];
                            }
                            Mask.Grid[xx + width * yy] = LabMask;
                        }
                        P = P + Step[dir];

                        iShift++;
                        if (iShift == 4)
                        {
                            iShift = 0;
                            iByte++;
                        }
                    }   //=============================== end for (iC... ==============================
                } //================================= end for (il < nLine2 ===============================================
                Mask.Grid[0] = Mask.Grid[width - 1] = Mask.Grid[width * height - 1] = Mask.Grid[width * (height - 1)] = LabMask;
                return(1);
            } //*********************** end Restore **********************************************************************