public byte[] doRequest(byte type, byte[] data = null, File f = null)
        {
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            if (data == null)
            {
                bout.writeInt(1);
                bout.writeByte(type);
            }
            else
            {
                bout.writeInt(data.Length+1);
                bout.writeByte(type);
                bout.write(data);
            }
            byte[] aout = bout.getArray();
            stream.Write(aout, 0, aout.Length);
            stream.Flush();

            byte[] resp = readBytes(8);
            ByteArrayInputStream bin = new ByteArrayInputStream(resp);
            int error = bin.readInt();
            int len = bin.readInt();
            resp = readBytes(len);

            if (error == 2) throw new AlreadyEditingException(f);
            if (error != 0)
            {
                ByteArrayInputStream i = new ByteArrayInputStream(resp);
                string s = i.ReadString();
                throw new Exception("Network error: " + s);
            }

            return resp;
        }
Exemple #2
0
        public byte[] doRequest(byte type, byte[] data = null, File f = null)
        {
            ByteArrayOutputStream bout = new ByteArrayOutputStream();

            if (data == null)
            {
                bout.writeInt(1);
                bout.writeByte(type);
            }
            else
            {
                bout.writeInt(data.Length + 1);
                bout.writeByte(type);
                bout.write(data);
            }
            byte[] aout = bout.getArray();
            stream.Write(aout, 0, aout.Length);
            stream.Flush();

            byte[] resp = readBytes(8);
            ByteArrayInputStream bin = new ByteArrayInputStream(resp);
            int error = bin.readInt();
            int len   = bin.readInt();

            resp = readBytes(len);

            if (error == 2)
            {
                throw new AlreadyEditingException(f);
            }
            if (error != 0)
            {
                ByteArrayInputStream i = new ByteArrayInputStream(resp);
                string s = i.ReadString();
                throw new Exception("Network error: " + s);
            }

            return(resp);
        }
Exemple #3
0
        /*public ImageTexeler(Bitmap img, int paletteMaxNum)
         * {
         *  this.img = img;
         *
         *  int tx = img.Width / 4;
         *  int ty = img.Height / 4;
         *  palettes = new Color[tx * ty][];
         *  paletteCounts = new int[tx * ty];
         *  paletteNumbers = new int[tx, ty];
         *  paletteDiffs = new float[tx * ty, tx * ty];
         *
         *  int palNum = 0;
         *  for (int x = 0; x < tx; x++)
         *      for (int y = 0; y < ty; y++)
         *      {
         *          ImageIndexerFast iif = new ImageIndexerFast(img, x * 4, y * 4);
         *          palettes[palNum] = iif.palette;
         *          paletteNumbers[x, y] = palNum;
         *          paletteCounts[palNum] = 1;
         *          int similar = calcPaletteDiffs(palNum);
         *          /*                    if (similar != -1)
         *                              {
         *                                  paletteCounts[palNum] = 0;
         *                                  paletteCounts[similar]++;
         *                                  paletteNumbers[x, y] = similar;
         *                              }
         *
         *          palNum++;
         *      }
         *
         *  while (countUsedPalettes() > paletteMaxNum)
         *  {
         *      Console.Out.WriteLine(countUsedPalettes());
         *      int besta = -1;
         *      int bestb = -1;
         *      float bestDif = float.MaxValue;
         *
         *
         *      //Find the two most similar palettes
         *      for (int i = 0; i < palettes.Length; i++)
         *      {
         *          if (paletteCounts[i] == 0) continue;
         *          for (int j = 0; j < palettes.Length; j++)
         *          {
         *              if (i == j) continue;
         *              if (paletteCounts[j] == 0) continue;
         *
         *              if (paletteDiffs[i, j] < bestDif)
         *              {
         *                  bestDif = paletteDiffs[i, j];
         *                  besta = j;
         *                  bestb = i;
         *              }
         *          }
         *      }
         *
         *      //Merge the Palettes!!!
         *      palettes[besta] = palMerge(palettes[besta], palettes[bestb]);
         *      calcPaletteDiffs(besta);
         *      paletteCounts[besta] += paletteCounts[bestb];
         *      paletteCounts[bestb] = 0;
         *
         *      for (int x = 0; x < tx; x++)
         *          for (int y = 0; y < ty; y++)
         *              if (paletteNumbers[x, y] == bestb)
         *                  paletteNumbers[x, y] = besta;
         *  }
         *
         *
         *
         *  //CREATE THE FINAL PAL
         *  int currNum = 0;
         *  finalPalette = new Color[paletteMaxNum * 4];
         *  int[] newPalNums = new int[palettes.Length];
         *  for (int i = 0; i < palettes.Length; i++)
         *  {
         *      if (paletteCounts[i] != 0)
         *      {
         *          transparentToTheEnd(palettes[i]);//
         *          newPalNums[i] = currNum;
         *          Array.Copy(palettes[i], 0, finalPalette, currNum * 4, 4);
         *          currNum++;
         *      }
         *  }
         *
         *  ByteArrayOutputStream texDat = new ByteArrayOutputStream();
         *  ByteArrayOutputStream f5Dat = new ByteArrayOutputStream();
         *  for (int y = 0; y < ty; y++)
         *      for (int x = 0; x < tx; x++)
         *      {
         *          //Find out if texel has transparent.
         *
         *          bool hasTransparent = false;
         *          for (int yy = 0; yy < 4; yy++)
         *              for (int xx = 0; xx < 4; xx++)
         *              {
         *                  Color coll = img.GetPixel(x * 4 + xx, y * 4 + yy);
         *                  if (coll.A < 128)
         *                      hasTransparent = true;
         *              }
         *
         *          //WRITE THE IMAGE DATA
         *          for (int yy = 0; yy < 4; yy++)
         *          {
         *              byte b = 0;
         *              byte pow = 1;
         *              for (int xx = 0; xx < 4; xx++)
         *              {
         *                  Color coll = img.GetPixel(x * 4 + xx, y * 4 + yy);
         *                  byte col;
         *                  if (coll.A < 128)
         *                  {
         *                      col = 3;
         *                  }
         *                  else
         *                  {
         *                      col = (byte)ImageIndexer.closest(coll, palettes[paletteNumbers[x, y]]);
         *                      if (col == 3) { col = 2; }
         *                  }
         *                  b |= (byte)(pow * col);
         *                  pow *= 4;
         *              }
         *              texDat.writeByte(b);
         *          }
         *
         *
         *          //WRITE THE FORMAT-5 SPECIFIC DATA
         *          ushort dat = (ushort)(newPalNums[paletteNumbers[x, y]] * 2);
         *          if (!hasTransparent || !ContainsTransparent(img))
         *          {
         *              dat |= 2 << 14;
         *          }
         *          f5Dat.writeUShort(dat);
         *      }
         *
         *  f5data = f5Dat.getArray();
         *  texdata = texDat.getArray();
         *
         * }*/
        public ImageTexeler(Bitmap img, int paletteMaxNum, ref System.ComponentModel.BackgroundWorker bw, bool color2 = false)
        {
            this.color2 = false;
            color2      = false;
            //this.color2 = color2;
            //bool trans = true;//ContainsTransparent(img);
            Bitmap im = new Bitmap(img.Width, img.Height, System.Drawing.Imaging.PixelFormat.Format64bppPArgb);

            using (Graphics gr = Graphics.FromImage(im))
            {
                gr.SmoothingMode      = System.Drawing.Drawing2D.SmoothingMode.None;
                gr.InterpolationMode  = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
                gr.PixelOffsetMode    = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                gr.DrawImage(img, 0, 0);
            }
            this.img = im;
            LockBitmap iii = new LockBitmap(img);

            iii.LockBits();
            int tx = img.Width / 4;
            int ty = img.Height / 4;

            palettes       = new List <Color[]>(); //[tx * ty][];
            paletteCounts  = new List <int>();     //new int[tx * ty];
            paletteNumbers = new int[tx, ty];
            paletteDiffs   = new float[tx * ty, tx *ty];
            double add      = 18d / (double)(tx * ty);
            double Progress = 10;
            int    palNum   = 0;
            double percent  = 0;
            double add2     = 100d / (double)(tx * ty);

            for (int x = 0; x < tx; x++)
            {
                for (int y = 0; y < ty; y++)
                {
                    Bitmap ni = new Bitmap(4, 4 /*, System.Drawing.Imaging.PixelFormat.Format16bppRgb555*/);

                    /*using (Graphics gr = Graphics.FromImage(ni))
                     * {
                     *  //gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                     *  //gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                     *  //gr.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                     *  //gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                     *  gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;//.AntiAlias;
                     *  gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
                     *  gr.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                     *  gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                     *
                     *  gr.DrawImage(this.img, new Rectangle(0, 0, 4, 4), new Rectangle(x * 4, y * 4, 4, 4), GraphicsUnit.Pixel);
                     * }*/
                    LockBitmap nn = new LockBitmap(ni);
                    nn.LockBits();
                    bool haveTransparent = false;
                    for (int x1 = 0; x1 < 4; x1++)
                    {
                        for (int y1 = 0; y1 < 4; y1++)
                        {
                            Color c = iii.GetPixel(x * 4 + x1, y * 4 + y1);
                            nn.SetPixel(x1, y1, c);
                            if (c.A < 128)
                            {
                                haveTransparent = true;
                                //goto end;
                            }
                        }
                    }
                    //end:
                    nn.UnlockBits();
                    List <Color> pal1 = new List <Color>();
                    pal1.AddRange(ImageIndexer.createPaletteForImage(ni, 4, haveTransparent));
                    //if(haveTransparent){pal1.Add(Color.Transparent);}
                    Color[] pal = pal1.ToArray(); //ImageIndexer.createPaletteForImage(ni, 4, false);
                    transparentToTheEnd(pal);
                    //if (haveTransparent)
                    //{
                    //    pal[0] = Color.Transparent;
                    //}
                    //ImageIndexerFast iif = new ImageIndexerFast(img, x * 4, y * 4);

                    int con = contains(palettes.ToArray(), pal);
                    if (con != -1)
                    {
                        paletteNumbers[x, y] = con;
                        //paletteCounts.Add(1);
                    }
                    else
                    {
                        palettes.Add(pal);    //[palNum] = pal;//iif.palette;
                        paletteNumbers[x, y] = palettes.Count - 1;
                        paletteCounts.Add(1); //[palNum] = 1;
                        calcPaletteDiffs(palettes.Count - 1);
                    }
                    //int similar = calcPaletteDiffs(palNum);
                    //                    if (similar != -1)
                    //                    {
                    //                        paletteCounts[palNum] = 0;
                    //                        paletteCounts[similar]++;
                    //                        paletteNumbers[x, y] = similar;
                    //                    }

                    palNum++;
                    Progress += add;
                    bw.ReportProgress((int)Progress, "Generating Picture " + percent.ToString("000") + "%");
                    percent += add2;
                    if (bw.CancellationPending)
                    {
                        bw.ReportProgress(0, "Canceled"); return;
                    }
                }
            }
            percent = 0;
            add2    = 100d / (((double)countUsedPalettes() - (double)paletteMaxNum));
            add     = 74d / (((double)countUsedPalettes() - (double)paletteMaxNum));
            //double iw = 0;
            while (countUsedPalettes() > paletteMaxNum)
            {
                //iw += 1;
                //Console.Out.WriteLine(countUsedPalettes());
                int   besta   = -1;
                int   bestb   = -1;
                float bestDif = float.MaxValue;

                //Find the two most similar palettes
                for (int i = 0; i < palettes.Count; i++)
                {
                    if (paletteCounts[i] == 0)
                    {
                        continue;
                    }
                    for (int j = 0; j < palettes.Count; j++)
                    {
                        if (i == j)
                        {
                            continue;
                        }
                        if (paletteCounts[j] == 0)
                        {
                            continue;
                        }

                        if (paletteDiffs[i, j] < bestDif)
                        {
                            bestDif = paletteDiffs[i, j];
                            besta   = j;
                            bestb   = i;
                        }
                    }
                }

                //Merge the Palettes!!!
                palettes[besta] = palMerge(palettes[besta], palettes[bestb]);
                calcPaletteDiffs(besta);
                paletteCounts[besta] += paletteCounts[bestb];
                paletteCounts[bestb]  = 0;

                for (int x = 0; x < tx; x++)
                {
                    for (int y = 0; y < ty; y++)
                    {
                        if (paletteNumbers[x, y] == bestb)
                        {
                            paletteNumbers[x, y] = besta;
                        }
                    }
                }
                Progress += add;
                percent  += add2;
                bw.ReportProgress((int)Progress, "Generating Palette " + percent.ToString("000") + "%");

                if (bw.CancellationPending)
                {
                    bw.ReportProgress(0, "Canceled"); return;
                }
            }



            //CREATE THE FINAL PAL
            int currNum = 0;

            finalPalette = new Color[countUsedPalettes() * 4];
            int[] newPalNums = new int[palettes.Count];
            for (int i = 0; i < palettes.Count; i++)
            {
                if (paletteCounts[i] != 0)
                {
                    transparentToTheEnd(palettes[i]);//
                    newPalNums[i] = currNum;
                    Array.Copy(palettes[i], 0, finalPalette, currNum * 4, 4);
                    currNum++;
                }
            }

            ByteArrayOutputStream texDat = new ByteArrayOutputStream();
            ByteArrayOutputStream f5Dat  = new ByteArrayOutputStream();

            for (int y = 0; y < ty; y++)
            {
                for (int x = 0; x < tx; x++)
                {
                    //Find out if texel has transparent.

                    bool hasTransparent = false;
                    for (int yy = 0; yy < 4; yy++)
                    {
                        for (int xx = 0; xx < 4; xx++)
                        {
                            Color coll = iii.GetPixel(x * 4 + xx, y * 4 + yy);
                            if (coll.A < 128)
                            {
                                hasTransparent = true;
                                goto End;
                            }
                        }
                    }
End:

                    //WRITE THE IMAGE DATA
                    for (int yy = 0; yy < 4; yy++)
                    {
                        byte b   = 0;
                        byte pow = 1;
                        for (int xx = 0; xx < 4; xx++)
                        {
                            Color coll = iii.GetPixel(x * 4 + xx, y * 4 + yy);
                            byte  col;
                            if (coll.A < 128)
                            {
                                col = 3;
                            }
                            else
                            {
                                List <Color> colo = new List <Color>();
                                colo.AddRange(palettes[paletteNumbers[x, y]]);
                                if (hasTransparent)
                                {
                                    colo.RemoveAt(3);
                                }
                                col = (byte)ImageIndexer.closest(coll, colo.ToArray());
                                //if (col == 3) { col = 2; }
                            }
                            b   |= (byte)(pow * col);
                            pow *= 4;
                        }
                        texDat.writeByte(b);
                    }


                    //WRITE THE FORMAT-5 SPECIFIC DATA
                    ushort dat = (ushort)(newPalNums[paletteNumbers[x, y]] * 2);
                    if (!hasTransparent /* || !ContainsTransparent(img)*/)
                    {
                        dat |= 2 << 14;
                    }
                    f5Dat.writeUShort(dat);
                }
            }
            iii.UnlockBits();

            f5data  = f5Dat.getArray();
            texdata = texDat.getArray();
        }
        static void Main(string[] args)
        {
            Console.WriteLine("Image to ENPG Batch Encoder - v1.0");
            Console.WriteLine("By Mariomaster using NSMBe's Image Indexer and LZ77 compressor");
            Console.WriteLine();

            if (args.Length == 0)
            {
                Console.WriteLine("Drag 256x256 Image files onto this application to convert them to NSMB's ENPG format.");
                Console.WriteLine();
                Console.Write("Press any key to exit...");
                Console.ReadKey();
                return;
            }

            bool compress   = false;
            bool forCredits = false;

checkCompress:
            Console.Write("Do you want to LZ77 compress the ENPGs? (y/n): ");
            char rc = Console.ReadKey().KeyChar;

            Console.WriteLine();

            if (rc == 'y' || rc == 'Y')
            {
                compress = true;
            }
            else if (rc == 'n' || rc == 'N')
            {
                compress = false;
            }
            else
            {
                goto checkCompress;
            }


checkForCredits:
            Console.Write("Are the Images intended as Credit Images (Reserve first 5 Palette slots)? (y/n): ");
            char rcr = Console.ReadKey().KeyChar;

            Console.WriteLine();

            if (rcr == 'y' || rcr == 'Y')
            {
                forCredits = true;
            }
            else if (rcr == 'n' || rcr == 'N')
            {
                forCredits = false;
            }
            else
            {
                goto checkForCredits;
            }

            Console.WriteLine();
            Console.WriteLine("Encoding " + args.Length + " images.");
            Console.WriteLine();

            int successCount = 0;

            foreach (string path in args)
            {
                if (!File.Exists(path))
                {
                    Console.WriteLine("The file " + path + " does not exist!");
                    continue;
                }

                if (!System.Web.MimeMapping.GetMimeMapping(path).StartsWith("image/"))
                {
                    Console.WriteLine("The file " + path + " is not an Image!");
                    continue;
                }

                Bitmap bmp = (Bitmap)Image.FromFile(path);

                if (bmp.Width != 256 || bmp.Height != 256)
                {
                    Console.WriteLine("The Image " + path + " is not 256x256!");
                    continue;
                }

                string folder = Path.GetDirectoryName(path);
                string name   = Path.GetFileNameWithoutExtension(path);

                Console.Write("Encoding " + path + "...");

                bmp.RotateFlip(RotateFlipType.Rotate90FlipX);

                int cCount = 256;
                if (forCredits)
                {
                    cCount = 251;
                }

                Color[] pal = ImageIndexer.createPaletteForImage(bmp, cCount);

                ByteArrayOutputStream b = new ByteArrayOutputStream();

                for (int x = 0; x < bmp.Width; x++)
                {
                    for (int y = 0; y < bmp.Height; y++)
                    {
                        Color c = bmp.GetPixel(x, y);
                        int   i = getClosestColor(pal, c);

                        int writeColor = i;

                        if (forCredits)
                        {
                            if (writeColor > 0)
                            {
                                writeColor += 5;
                            }
                        }

                        b.writeByte((byte)writeColor);
                    }
                }

                b.writeUShort(toRGB15(pal[0]));

                if (forCredits)
                {
                    for (int i = 0; i < 5; i++)
                    {
                        b.writeUShort(0x0);
                    }
                }

                for (int i = 1; i < pal.Length; i++)
                {
                    b.writeUShort(toRGB15(pal[i]));
                }

                if (!Directory.Exists(folder + "\\convert"))
                {
                    Directory.CreateDirectory(folder + "\\convert");
                }

                var bw = new BinaryWriter(File.Open(folder + "\\convert\\" + name + ".enpg", FileMode.OpenOrCreate));

                if (compress)
                {
                    bw.Write(lz77.LZ77_Compress(b.getArray()));
                }
                else
                {
                    bw.Write(b.getArray());
                }

                bw.Flush();
                bw.Close();

                successCount++;
                Console.WriteLine("\rEncoding " + path + " done.");
            }

            Console.WriteLine();
            Console.Write("Successfully encoded " + successCount + " of " + args.Length + " images. Press any key to exit...");
            Console.ReadKey();
        }
Exemple #5
0
        public ImageTexeler(Bitmap img, int paletteMaxNum)
        {
            this.img = img;

            int tx = img.Width / 4;
            int ty = img.Height / 4;

            palettes       = new Color[tx * ty][];
            paletteCounts  = new int[tx * ty];
            paletteNumbers = new int[tx, ty];
            paletteDiffs   = new float[tx * ty, tx *ty];

            int palNum = 0;

            for (int x = 0; x < tx; x++)
            {
                for (int y = 0; y < ty; y++)
                {
                    ImageIndexerFast iif = new ImageIndexerFast(img, x * 4, y * 4);
                    palettes[palNum]      = iif.palette;
                    paletteNumbers[x, y]  = palNum;
                    paletteCounts[palNum] = 1;
                    int similar = calcPaletteDiffs(palNum);

/*                    if (similar != -1)
 *                  {
 *                      paletteCounts[palNum] = 0;
 *                      paletteCounts[similar]++;
 *                      paletteNumbers[x, y] = similar;
 *                  }
 */
                    palNum++;
                }
            }

            while (countUsedPalettes() > paletteMaxNum)
            {
                Console.Out.WriteLine(countUsedPalettes());
                int   besta   = -1;
                int   bestb   = -1;
                float bestDif = float.MaxValue;


                //Find the two most similar palettes
                for (int i = 0; i < palettes.Length; i++)
                {
                    if (paletteCounts[i] == 0)
                    {
                        continue;
                    }
                    for (int j = 0; j < palettes.Length; j++)
                    {
                        if (i == j)
                        {
                            continue;
                        }
                        if (paletteCounts[j] == 0)
                        {
                            continue;
                        }

                        if (paletteDiffs[i, j] < bestDif)
                        {
                            bestDif = paletteDiffs[i, j];
                            besta   = j;
                            bestb   = i;
                        }
                    }
                }

                //Merge the Palettes!!!
                palettes[besta] = palMerge(palettes[besta], palettes[bestb]);
                calcPaletteDiffs(besta);
                paletteCounts[besta] += paletteCounts[bestb];
                paletteCounts[bestb]  = 0;

                for (int x = 0; x < tx; x++)
                {
                    for (int y = 0; y < ty; y++)
                    {
                        if (paletteNumbers[x, y] == bestb)
                        {
                            paletteNumbers[x, y] = besta;
                        }
                    }
                }
            }



            //CREATE THE FINAL PAL
            int currNum = 0;

            finalPalette = new Color[paletteMaxNum * 4];
            int[] newPalNums = new int[palettes.Length];
            for (int i = 0; i < palettes.Length; i++)
            {
                if (paletteCounts[i] != 0)
                {
                    //transparentToTheEnd(palettes[i]);
                    newPalNums[i] = currNum;
                    Array.Copy(palettes[i], 0, finalPalette, currNum * 4, 4);
                    currNum++;
                }
            }

            ByteArrayOutputStream texDat = new ByteArrayOutputStream();
            ByteArrayOutputStream f5Dat  = new ByteArrayOutputStream();

            for (int y = 0; y < ty; y++)
            {
                for (int x = 0; x < tx; x++)
                {
                    //Find out if texel has transparent.

                    bool hasTransparent = false;
                    for (int yy = 0; yy < 4; yy++)
                    {
                        for (int xx = 0; xx < 4; xx++)
                        {
                            Color coll = img.GetPixel(x * 4 + xx, y * 4 + yy);
                            if (coll.A < 128)
                            {
                                hasTransparent = true;
                            }
                        }
                    }

                    //WRITE THE IMAGE DATA
                    for (int yy = 0; yy < 4; yy++)
                    {
                        byte b   = 0;
                        byte pow = 1;
                        for (int xx = 0; xx < 4; xx++)
                        {
                            Color coll = img.GetPixel(x * 4 + xx, y * 4 + yy);
                            byte  col;
                            if (coll.A < 128)
                            {
                                col = 3;
                            }
                            else
                            {
                                col = (byte)ImageIndexer.closest(coll, palettes[paletteNumbers[x, y]]);
                                if (col == 3)
                                {
                                    col = 2;
                                }
                            }
                            b   |= (byte)(pow * col);
                            pow *= 4;
                        }
                        texDat.writeByte(b);
                    }


                    //WRITE THE FORMAT-5 SPECIFIC DATA
                    ushort dat = (ushort)(newPalNums[paletteNumbers[x, y]] * 2);
                    if (!hasTransparent)
                    {
                        dat |= 2 << 14;
                    }
                    f5Dat.writeUShort(dat);
                }
            }

            f5data  = f5Dat.getArray();
            texdata = texDat.getArray();
        }
Exemple #6
0
        public ImageTexeler(Bitmap img, int paletteMaxNum)
        {
            this.img = img;

            int tx = img.Width / 4;
            int ty = img.Height / 4;
            palettes = new Color[tx*ty][];
            paletteCounts = new int[tx*ty];
            paletteNumbers = new int[tx, ty];
            paletteDiffs = new float[tx*ty, tx*ty];

            int palNum = 0;
            for(int x = 0; x < tx; x++)
                for (int y = 0; y < ty; y++)
                {
                    ImageIndexerFast iif = new ImageIndexerFast(img, x * 4, y * 4);
                    palettes[palNum] = iif.palette;
                    paletteNumbers[x, y] = palNum;
                    paletteCounts[palNum] = 1;
                    int similar = calcPaletteDiffs(palNum);
            /*                    if (similar != -1)
                    {
                        paletteCounts[palNum] = 0;
                        paletteCounts[similar]++;
                        paletteNumbers[x, y] = similar;
                    }
                    */
                    palNum++;
                }

            while (countUsedPalettes() > paletteMaxNum)
            {
                Console.Out.WriteLine(countUsedPalettes());
                int besta = -1;
                int bestb = -1;
                float bestDif = float.MaxValue;

                //Find the two most similar palettes
                for (int i = 0; i < palettes.Length; i++)
                {
                    if (paletteCounts[i] == 0) continue;
                    for (int j = 0; j < palettes.Length; j++)
                    {
                        if (i == j) continue;
                        if (paletteCounts[j] == 0) continue;

                        if (paletteDiffs[i, j] < bestDif)
                        {
                            bestDif = paletteDiffs[i, j];
                            besta = j;
                            bestb = i;
                        }
                    }
                }

                //Merge the Palettes!!!
                palettes[besta] = palMerge(palettes[besta], palettes[bestb]);
                calcPaletteDiffs(besta);
                paletteCounts[besta] += paletteCounts[bestb];
                paletteCounts[bestb] = 0;

                for (int x = 0; x < tx; x++)
                    for (int y = 0; y < ty; y++)
                        if (paletteNumbers[x, y] == bestb)
                            paletteNumbers[x, y] = besta;
            }

            //CREATE THE FINAL PAL
            int currNum = 0;
            finalPalette = new Color[paletteMaxNum*4];
            int[] newPalNums = new int[palettes.Length];
            for(int i = 0; i < palettes.Length; i++)
            {
                if(paletteCounts[i] != 0)
                {
                    //transparentToTheEnd(palettes[i]);
                    newPalNums[i] = currNum;
                    Array.Copy(palettes[i], 0, finalPalette, currNum*4, 4);
                    currNum++;
                }
            }

            ByteArrayOutputStream texDat = new ByteArrayOutputStream();
            ByteArrayOutputStream f5Dat = new ByteArrayOutputStream();
            for (int y = 0; y < ty; y++)
                for (int x = 0; x < tx; x++)
                {
                    //Find out if texel has transparent.

                    bool hasTransparent = false;
                    for (int yy = 0; yy < 4; yy++)
                        for (int xx = 0; xx < 4; xx++)
                        {
                            Color coll = img.GetPixel(x * 4 + xx, y * 4 + yy);
                            if (coll.A < 128)
                                hasTransparent = true;
                        }

                    //WRITE THE IMAGE DATA
                    for (int yy = 0; yy < 4; yy++)
                    {
                        byte b = 0;
                        byte pow = 1;
                        for (int xx = 0; xx < 4; xx++)
                        {
                            Color coll = img.GetPixel(x*4+xx, y*4+yy);
                            byte col;
                            if (coll.A < 128)
                            {
                                col = 3;
                            }
                            else
                            {
                                col = (byte)ImageIndexer.closest(coll, palettes[paletteNumbers[x, y]]);
                                if (col == 3) col = 2;
                            }
                            b |= (byte)(pow * col);
                            pow *= 4;
                        }
                        texDat.writeByte(b);
                    }

                    //WRITE THE FORMAT-5 SPECIFIC DATA
                    ushort dat = (ushort)(newPalNums[paletteNumbers[x, y]] * 2);
                    if(!hasTransparent)
                        dat |= 2 << 14;
                    f5Dat.writeUShort(dat);
                }

            f5data = f5Dat.getArray();
            texdata = texDat.getArray();
        }
Exemple #7
0
        /*public ImageTexeler(Bitmap img, int paletteMaxNum)
        {
            this.img = img;

            int tx = img.Width / 4;
            int ty = img.Height / 4;
            palettes = new Color[tx * ty][];
            paletteCounts = new int[tx * ty];
            paletteNumbers = new int[tx, ty];
            paletteDiffs = new float[tx * ty, tx * ty];

            int palNum = 0;
            for (int x = 0; x < tx; x++)
                for (int y = 0; y < ty; y++)
                {
                    ImageIndexerFast iif = new ImageIndexerFast(img, x * 4, y * 4);
                    palettes[palNum] = iif.palette;
                    paletteNumbers[x, y] = palNum;
                    paletteCounts[palNum] = 1;
                    int similar = calcPaletteDiffs(palNum);
                    /*                    if (similar != -1)
                                        {
                                            paletteCounts[palNum] = 0;
                                            paletteCounts[similar]++;
                                            paletteNumbers[x, y] = similar;
                                        }

                    palNum++;
                }

            while (countUsedPalettes() > paletteMaxNum)
            {
                Console.Out.WriteLine(countUsedPalettes());
                int besta = -1;
                int bestb = -1;
                float bestDif = float.MaxValue;

                //Find the two most similar palettes
                for (int i = 0; i < palettes.Length; i++)
                {
                    if (paletteCounts[i] == 0) continue;
                    for (int j = 0; j < palettes.Length; j++)
                    {
                        if (i == j) continue;
                        if (paletteCounts[j] == 0) continue;

                        if (paletteDiffs[i, j] < bestDif)
                        {
                            bestDif = paletteDiffs[i, j];
                            besta = j;
                            bestb = i;
                        }
                    }
                }

                //Merge the Palettes!!!
                palettes[besta] = palMerge(palettes[besta], palettes[bestb]);
                calcPaletteDiffs(besta);
                paletteCounts[besta] += paletteCounts[bestb];
                paletteCounts[bestb] = 0;

                for (int x = 0; x < tx; x++)
                    for (int y = 0; y < ty; y++)
                        if (paletteNumbers[x, y] == bestb)
                            paletteNumbers[x, y] = besta;
            }

            //CREATE THE FINAL PAL
            int currNum = 0;
            finalPalette = new Color[paletteMaxNum * 4];
            int[] newPalNums = new int[palettes.Length];
            for (int i = 0; i < palettes.Length; i++)
            {
                if (paletteCounts[i] != 0)
                {
                    transparentToTheEnd(palettes[i]);//
                    newPalNums[i] = currNum;
                    Array.Copy(palettes[i], 0, finalPalette, currNum * 4, 4);
                    currNum++;
                }
            }

            ByteArrayOutputStream texDat = new ByteArrayOutputStream();
            ByteArrayOutputStream f5Dat = new ByteArrayOutputStream();
            for (int y = 0; y < ty; y++)
                for (int x = 0; x < tx; x++)
                {
                    //Find out if texel has transparent.

                    bool hasTransparent = false;
                    for (int yy = 0; yy < 4; yy++)
                        for (int xx = 0; xx < 4; xx++)
                        {
                            Color coll = img.GetPixel(x * 4 + xx, y * 4 + yy);
                            if (coll.A < 128)
                                hasTransparent = true;
                        }

                    //WRITE THE IMAGE DATA
                    for (int yy = 0; yy < 4; yy++)
                    {
                        byte b = 0;
                        byte pow = 1;
                        for (int xx = 0; xx < 4; xx++)
                        {
                            Color coll = img.GetPixel(x * 4 + xx, y * 4 + yy);
                            byte col;
                            if (coll.A < 128)
                            {
                                col = 3;
                            }
                            else
                            {
                                col = (byte)ImageIndexer.closest(coll, palettes[paletteNumbers[x, y]]);
                                if (col == 3) { col = 2; }
                            }
                            b |= (byte)(pow * col);
                            pow *= 4;
                        }
                        texDat.writeByte(b);
                    }

                    //WRITE THE FORMAT-5 SPECIFIC DATA
                    ushort dat = (ushort)(newPalNums[paletteNumbers[x, y]] * 2);
                    if (!hasTransparent || !ContainsTransparent(img))
                    {
                        dat |= 2 << 14;
                    }
                    f5Dat.writeUShort(dat);
                }

            f5data = f5Dat.getArray();
            texdata = texDat.getArray();

        }*/
        public ImageTexeler(Bitmap img, int paletteMaxNum, ref System.ComponentModel.BackgroundWorker bw, bool color2 = false)
        {
            this.color2 = false;
            color2 = false;
            //this.color2 = color2;
            //bool trans = true;//ContainsTransparent(img);
            Bitmap im = new Bitmap(img.Width, img.Height, System.Drawing.Imaging.PixelFormat.Format64bppPArgb);
            using (Graphics gr = Graphics.FromImage(im))
            {
                gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
                gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
                gr.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                gr.DrawImage(img, 0, 0);
            }
            this.img = im;
            LockBitmap iii = new LockBitmap(img);
            iii.LockBits();
            int tx = img.Width / 4;
            int ty = img.Height / 4;
            palettes = new List<Color[]>();//[tx * ty][];
            paletteCounts = new List<int>();//new int[tx * ty];
            paletteNumbers = new int[tx, ty];
            paletteDiffs = new float[tx * ty, tx * ty];
            double add = 18d / (double)(tx * ty);
            double Progress = 10;
            int palNum = 0;
            double percent = 0;
            double add2 = 100d / (double)(tx * ty);
            for (int x = 0; x < tx; x++)
                for (int y = 0; y < ty; y++)
                {

                    Bitmap ni = new Bitmap(4, 4/*, System.Drawing.Imaging.PixelFormat.Format16bppRgb555*/);
                    /*using (Graphics gr = Graphics.FromImage(ni))
                    {
                        //gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                        //gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                        //gr.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                        //gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                        gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;//.AntiAlias;
                        gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
                        gr.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                        gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;

                        gr.DrawImage(this.img, new Rectangle(0, 0, 4, 4), new Rectangle(x * 4, y * 4, 4, 4), GraphicsUnit.Pixel);
                    }*/
                    LockBitmap nn = new LockBitmap(ni);
                    nn.LockBits();
                    bool haveTransparent = false;
                    for (int x1 = 0; x1 < 4; x1++)
                        for (int y1 = 0; y1 < 4; y1++)
                        {
                            Color c = iii.GetPixel(x * 4 + x1, y * 4 + y1);
                            nn.SetPixel(x1, y1, c);
                            if (c.A < 128)
                            {
                                haveTransparent = true;
                                //goto end;
                            }
                        }
                //end:
                    nn.UnlockBits();
                    List<Color> pal1 = new List<Color>();
                    pal1.AddRange(ImageIndexer.createPaletteForImage(ni, 4, haveTransparent));
                    //if(haveTransparent){pal1.Add(Color.Transparent);}
                    Color[] pal = pal1.ToArray(); //ImageIndexer.createPaletteForImage(ni, 4, false);
                    transparentToTheEnd(pal);
                    //if (haveTransparent)
                    //{
                    //    pal[0] = Color.Transparent;
                    //}
                    //ImageIndexerFast iif = new ImageIndexerFast(img, x * 4, y * 4);

                    int con = contains(palettes.ToArray(), pal);
                    if (con != -1)
                    {
                        paletteNumbers[x, y] = con;
                        //paletteCounts.Add(1);
                    }
                    else
                    {
                        palettes.Add(pal);//[palNum] = pal;//iif.palette;
                        paletteNumbers[x, y] = palettes.Count - 1;
                        paletteCounts.Add(1);//[palNum] = 1;
                        calcPaletteDiffs(palettes.Count - 1);
                    }
                    //int similar = calcPaletteDiffs(palNum);
                    //                    if (similar != -1)
                    //                    {
                    //                        paletteCounts[palNum] = 0;
                    //                        paletteCounts[similar]++;
                    //                        paletteNumbers[x, y] = similar;
                    //                    }

                    palNum++;
                    Progress += add;
                    bw.ReportProgress((int)Progress, "Generating Picture " + percent.ToString("000") + "%");
                    percent += add2;
                    if (bw.CancellationPending) { bw.ReportProgress(0, "Canceled"); return; }
                }
            percent = 0;
            add2 = 100d / (((double)countUsedPalettes() - (double)paletteMaxNum));
            add = 74d / (((double)countUsedPalettes() - (double)paletteMaxNum));
            //double iw = 0;
            while (countUsedPalettes() > paletteMaxNum)
            {
                //iw += 1;
                //Console.Out.WriteLine(countUsedPalettes());
                int besta = -1;
                int bestb = -1;
                float bestDif = float.MaxValue;

                //Find the two most similar palettes
                for (int i = 0; i < palettes.Count; i++)
                {
                    if (paletteCounts[i] == 0) continue;
                    for (int j = 0; j < palettes.Count; j++)
                    {
                        if (i == j) continue;
                        if (paletteCounts[j] == 0) continue;

                        if (paletteDiffs[i, j] < bestDif)
                        {
                            bestDif = paletteDiffs[i, j];
                            besta = j;
                            bestb = i;
                        }
                    }
                }

                //Merge the Palettes!!!
                palettes[besta] = palMerge(palettes[besta], palettes[bestb]);
                calcPaletteDiffs(besta);
                paletteCounts[besta] += paletteCounts[bestb];
                paletteCounts[bestb] = 0;

                for (int x = 0; x < tx; x++)
                    for (int y = 0; y < ty; y++)
                        if (paletteNumbers[x, y] == bestb)
                            paletteNumbers[x, y] = besta;
                Progress += add;
                percent += add2;
                bw.ReportProgress((int)Progress, "Generating Palette " + percent.ToString("000") + "%");

                if (bw.CancellationPending) { bw.ReportProgress(0, "Canceled"); return; }
            }

            //CREATE THE FINAL PAL
            int currNum = 0;
            finalPalette = new Color[countUsedPalettes() * 4];
            int[] newPalNums = new int[palettes.Count];
            for (int i = 0; i < palettes.Count; i++)
            {
                if (paletteCounts[i] != 0)
                {
                    transparentToTheEnd(palettes[i]);//
                    newPalNums[i] = currNum;
                    Array.Copy(palettes[i], 0, finalPalette, currNum * 4, 4);
                    currNum++;
                }
            }

            ByteArrayOutputStream texDat = new ByteArrayOutputStream();
            ByteArrayOutputStream f5Dat = new ByteArrayOutputStream();
            for (int y = 0; y < ty; y++)
                for (int x = 0; x < tx; x++)
                {
                    //Find out if texel has transparent.

                    bool hasTransparent = false;
                    for (int yy = 0; yy < 4; yy++)
                        for (int xx = 0; xx < 4; xx++)
                        {
                            Color coll = iii.GetPixel(x * 4 + xx, y * 4 + yy);
                            if (coll.A < 128)
                            {
                                hasTransparent = true;
                                goto End;
                            }
                        }
                End:

                    //WRITE THE IMAGE DATA
                    for (int yy = 0; yy < 4; yy++)
                    {
                        byte b = 0;
                        byte pow = 1;
                        for (int xx = 0; xx < 4; xx++)
                        {
                            Color coll = iii.GetPixel(x * 4 + xx, y * 4 + yy);
                            byte col;
                            if (coll.A < 128)
                            {
                                col = 3;
                            }
                            else
                            {
                                List<Color> colo = new List<Color>();
                                colo.AddRange(palettes[paletteNumbers[x, y]]);
                                if (hasTransparent)
                                {
                                    colo.RemoveAt(3);
                                }
                                col = (byte)ImageIndexer.closest(coll, colo.ToArray());
                                //if (col == 3) { col = 2; }
                            }
                            b |= (byte)(pow * col);
                            pow *= 4;
                        }
                        texDat.writeByte(b);
                    }

                    //WRITE THE FORMAT-5 SPECIFIC DATA
                    ushort dat = (ushort)(newPalNums[paletteNumbers[x, y]] * 2);
                    if (!hasTransparent/* || !ContainsTransparent(img)*/)
                    {
                        dat |= 2 << 14;
                    }
                    f5Dat.writeUShort(dat);
                }
            iii.UnlockBits();

            f5data = f5Dat.getArray();
            texdata = texDat.getArray();
        }