Exemplo n.º 1
0
        static int Main(string[] astrArgs)
        {
            if (astrArgs.Length != 2) {
                Usage();
                return 1;
            }

            Palette pal;
            try {
                pal = new Palette(astrArgs[0]);
            } catch (Exception ex) {
                Console.WriteLine(ex);
                return 1;
            }

            BinaryWriter binw = new BinaryWriter(new FileStream(astrArgs[1], FileMode.Create));
            binw.Write((byte)((pal.Length & 0xff00) >> 8));
            binw.Write((byte)(pal.Length & 0xff));

            for (int i = 0; i < pal.Length; i++) {
                binw.Write(pal[i].R);
                binw.Write(pal[i].G);
                binw.Write(pal[i].B);
            }

            binw.Close();

            return 0;
        }
Exemplo n.º 2
0
        static int Main(string[] astrArgs)
        {
            if (astrArgs.Length < 3) {
                Console.WriteLine("Usage:\nbscale -scale <scale> -pal <palette.pal> <file(s) ...> -out <outdir>\n");
                return -1;
            }

            double nScale = 1.0;
            string strOutDir = null, strPalette = null;
            ArrayList alFileSpecs = new ArrayList();

            for (int iarg = 0; iarg < astrArgs.Length; iarg++) {
                if (astrArgs[iarg][0] == '-') {
                    switch (astrArgs[iarg]) {
                    case "-scale":
                        nScale = double.Parse(astrArgs[++iarg]);
                        break;

                    case "-out":
                        strOutDir = astrArgs[++iarg];
                        break;

                    case "-pal":
                        strPalette = astrArgs[++iarg];
                        break;
                    }
                } else {
                    alFileSpecs.Add(astrArgs[iarg]);
                }
            }

            // Read in the palette

            Palette pal = new Palette(strPalette);
            if (pal == null) {
                Console.WriteLine("Error: unable to read the palette file {0}\n", strPalette);
                return -1;
            }

            foreach (string strFileSpec in alFileSpecs) {
                Console.WriteLine("dir = " + Path.GetDirectoryName(strFileSpec) + ", file = " + Path.GetFileName(strFileSpec));
                string[] astrFiles = Directory.GetFiles(Path.GetDirectoryName(strFileSpec), Path.GetFileName(strFileSpec));

                foreach (string strFile in astrFiles) {
                    Console.WriteLine(strFile);
                    Bitmap bm = new Bitmap(strFile);
                    Bitmap bmScaled = TBitmapTools.ScaleBitmap(bm, nScale, pal);
                    if (!Directory.Exists(strOutDir))
                        Directory.CreateDirectory(strOutDir);

                    bmScaled.Save(strOutDir + Path.DirectorySeparatorChar +
                            Path.GetFileName(strFile), bm.RawFormat);
                }
            }

            return 0;
        }
Exemplo n.º 3
0
        public static Bitmap ScaleBitmap(Bitmap bm, double nScale, Palette palFixed)
        {
            Color[] aclrSpecial = new Color[] {
                // side colors
                Color.FromArgb(0, 116, 232),
                Color.FromArgb(0, 96, 196),
                Color.FromArgb(0, 64, 120),
                Color.FromArgb(0, 48, 92),
                Color.FromArgb(0, 32, 64),
                // transparent
                Color.FromArgb(255, 0, 255),
                // shadow
                Color.FromArgb(156, 212, 248),
            };

            Bitmap bmNew = new Bitmap((int)Math.Floor(bm.Width * nScale + 0.5), (int)Math.Floor(bm.Height * nScale + 0.5));
            for (int y = 0; y < bmNew.Height; y++) {
                for (int x = 0; x < bmNew.Width; x++) {
                    double nWidthRatio = (double)bm.Width / (double)bmNew.Width;
                    double xLeft = (double)x * nWidthRatio;
                    double nHeightRatio = (double)bm.Height / (double)bmNew.Height;
                    double yTop = (double)y * nHeightRatio;
                    double xRight = xLeft + 1.0 * nWidthRatio;
                    if (xRight > bm.Width)
                        xRight = bm.Width;
                    double yBottom = yTop + 1.0 * nHeightRatio;
                    if (yBottom > bm.Height)
                        yBottom = bm.Height;
                    DoubleRect drc = new DoubleRect(xLeft, yTop, xRight, yBottom);
                    Color clrSample = SampleGobBitmap(bm, drc, aclrSpecial, 4);
                    if (palFixed != null) {
                        bool fSpecial = false;
                        foreach (Color clrSpecial in aclrSpecial) {
                            if (clrSample == clrSpecial) {
                                fSpecial = true;
                                break;
                            }
                        }
                        if (!fSpecial)
                            clrSample = palFixed[palFixed.FindClosestEntry(clrSample)];
                    }

                    bmNew.SetPixel(x, y, clrSample);
                }
            }

            return bmNew;
        }
Exemplo n.º 4
0
        static int Main(string[] astrArgs)
        {
            if (astrArgs.Length < 1) {
                Console.WriteLine("pal2act usage:\npal2act <palette.pal> [out.act]");
                return -1;
            }
            string strIn = astrArgs[0];

            string strOut;
            if (astrArgs.Length < 2) {
                strOut = Path.ChangeExtension(strIn, ".act");
            } else {
                strOut = astrArgs[1];
            }

            Palette pal = new Palette(strIn);
            pal.SavePhotoshopAct(strOut);

            return 0;
        }
Exemplo n.º 5
0
        public static unsafe void Save(string strFile, Palette pal, string strFileOut)
        {
            Bitmap bm = new Bitmap(strFile);

            // Find the palette index for black
            int iclrBlack = pal.FindClosestEntry(Color.FromArgb(0, 0, 0));

            // Lock down bits for speed
            Rectangle rc = new Rectangle(0, 0, bm.Width, bm.Height);
            BitmapData bmd = bm.LockBits(rc, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            byte *pbBase = (byte *)bmd.Scan0.ToPointer();

            // Map all the pixels in the bitmap to 'nearest' color palette indices
            byte[] ab = new byte[((bm.Width + 1) & ~1) * bm.Height];
            int i = 0;
            for (int y = 0; y < bm.Height; y++) {
                for (int x = 0; x < bm.Width; x++) {
                    byte *pb = pbBase + y * bmd.Stride + x * 3;
                    Color clr = Color.FromArgb(pb[2], pb[1], pb[0]);
                    if (clr == Color.FromArgb(156, 212, 248))
                        clr = Color.FromArgb(0, 0, 0);
                    ab[i++] = (byte)pal.FindClosestEntry(clr);
                }
                if ((bm.Width & 1) == 1)
                    ab[i++] = (byte)iclrBlack;
            }
            bm.UnlockBits(bmd);

            // Write bitmap header, bits
            BinaryWriter bwtr = new BinaryWriter(new FileStream(strFileOut, FileMode.Create, FileAccess.Write));
            bwtr.Write(Misc.SwapUShort((ushort)((bm.Width + 1) & ~1)));
            bwtr.Write(Misc.SwapUShort((ushort)bm.Height));
            bwtr.Write(ab);
            bwtr.Close();

            // Done
            bm.Dispose();
        }
Exemplo n.º 6
0
        static unsafe void Main(string[] args)
        {
            // Get parameters
            Palette palIn = new Palette(args[0]);
            string strFileOut = args[1];
            double dAlpha = Double.Parse(args[2]);

            // Create mapping
            byte[] ab = new byte[palIn.Length];
            Palette palInHSB = new Palette(palIn.Length);
            for (int iclr = 0; iclr < palIn.Length; iclr++) {
                Color clr = palIn[iclr];
                double h = clr.GetHue();
                double s = clr.GetSaturation();
                double l = clr.GetBrightness();
                double r;
                double g;
                double b;
                MyHSLtoRGB(h, s, l * dAlpha, &r, &g, &b);
                Color clrShadow = Color.FromArgb((int)(r * 255.0), (int)(g * 255.0), (int)(b * 255.0));
                ab[iclr] = (byte)palIn.FindClosestEntry(clrShadow);
            }

            // Write palette mapping
            Stream stm = new FileStream(strFileOut, FileMode.Create, FileAccess.Write, FileShare.None);
            BinaryWriter bwtr = new BinaryWriter(stm);
            bwtr.Write(ab);
            bwtr.Close();

            #if false
            // Check it
            Palette palCheck = new Palette(palIn.Length);
            for (int iclr = 0; iclr < palIn.Length; iclr++)
                palCheck[iclr] = palIn[ab[iclr]];
            palCheck.SaveJasc("shadow.pal");
            #endif
        }
Exemplo n.º 7
0
        static Palette QuantizeColors2(ArrayList alsColors, Palette palFixed, int cPalEntries, int cPalEntriesFixed)
        {
            // If no quantization needed (4 bit grayscale), return

            if (cPalEntriesFixed >= cPalEntries)
                return palFixed;

            MedianCut mcut = new MedianCut(alsColors);
            mcut.convert(cPalEntries - cPalEntriesFixed);
            Palette palUpper = mcut.GetPalette();
            palUpper.Pad(cPalEntries, Color.FromArgb(255, 0, 255));

            Color[] aclr = new Color[cPalEntries];
            for (int iclr = 0; iclr < cPalEntriesFixed; iclr++)
                aclr[iclr] = palFixed[iclr];
            for (int iclr = cPalEntriesFixed; iclr < cPalEntries; iclr++) {
                Color clr = palUpper[iclr - cPalEntriesFixed];
                Color clrT = Color.FromArgb(clr.R & 0xfc, clr.G & 0xfc, clr.B & 0xfc);
                aclr[iclr] = clrT;
            }
            return new Palette(aclr);
        }
Exemplo n.º 8
0
        public static void QuantizeTemplates(TemplateDoc tmpd, Palette palFixed, int cPalEntries, int cPalEntriesFixed, int cPalEntriesBackground)
        {
            // Load the fixed palette. The result will be 24 bit templates normalized to a palette of 256 colors,
            // the "fixed" palette plus a quantized palette.

            if (palFixed == null) {
                palFixed = Palette.OpenDialog(null);
                if (palFixed == null) {
                    MessageBox.Show(DocManager.GetFrameParent(), "Must have the fixed color palette to continue!");
                    return;
                }

                switch (palFixed.Length) {
                case 16:
                    cPalEntries = 16;
                    cPalEntriesFixed = 16;
                    cPalEntriesBackground = 0;
                    break;

                case 256:
                    cPalEntries = 256;
                    cPalEntriesFixed = 128;
                    cPalEntriesBackground = 32;
                    break;
                }
            }

            // Quantize loop. Designed to make optimal use of the lower 128 fixed colors

            // Quantize background separately from foreground

            Template tmplBackground = tmpd.GetBackgroundTemplate();
            if (tmplBackground != null && cPalEntriesBackground != 0) {
                // Create a despeckled hue map of the background. We'll use this to
                // subtract background from foreground so we can quantize foreground separately

                Bitmap bmHueBackground = MakeHueMap(tmplBackground.Bitmap);
                DespeckleGrayscaleBitmap(bmHueBackground, 9, 50);

                // Calc mean and standard deviation for filtering purposes

                double nMean = CalcGrayscaleMean(bmHueBackground);
                double nStdDev = CalcGrayscaleStandardDeviation(bmHueBackground, nMean);

                // Add extract & quantize the background pixels

                ArrayList alsColorsBackground = new ArrayList();
                AddTemplateColors(alsColorsBackground, tmplBackground.Bitmap);
                palFixed = QuantizeColors(alsColorsBackground, palFixed, cPalEntriesFixed + cPalEntriesBackground, cPalEntriesFixed);
                cPalEntriesFixed += cPalEntriesBackground;

                // Now extract foreground pixels by first subtracting background pixels

                ArrayList alsColorsForeground = new ArrayList();
                Template[] atmpl = tmpd.GetTemplates();
                foreach (Template tmpl in atmpl) {
                    if (tmpl == tmplBackground)
                        continue;
                    Bitmap bmT = MakeHueMap(tmpl.Bitmap);
                    DespeckleGrayscaleBitmap(bmT, 9, 50);
                    SubtractGrayscaleDistribution(bmT, nMean, nStdDev);
                    for (int y = 0; y < bmT.Height; y++) {
                        for (int x = 0; x < bmT.Width; x++) {
                            Color clr = bmT.GetPixel(x, y);
                            if (clr != Color.FromArgb(255, 0, 255))
                                bmT.SetPixel(x, y, tmpl.Bitmap.GetPixel(x, y));
                        }
                    }
                    AddTemplateColors(alsColorsForeground, bmT);
                }

                // Now quantize foreground pixels
                // Set the palette and color match

                Palette palNew = QuantizeColors(alsColorsForeground, palFixed, cPalEntries, cPalEntriesFixed);
                tmpd.SetPalette(palNew, true);
            } else {
                // No background template; just quantize everything together

                Template[] atmpl = tmpd.GetTemplates();
                ArrayList alsColors = new ArrayList();
                foreach (Template tmpl in atmpl)
                    AddTemplateColors(alsColors, tmpl.Bitmap);

                // Now quantize foreground pixels
                // Set the palette and color match

                Palette palNew = QuantizeColors(alsColors, palFixed, cPalEntries, cPalEntriesFixed);
                tmpd.SetPalette(palNew, true);
            }
        }
Exemplo n.º 9
0
 public TBitmap(Bitmap bm, Palette pal)
 {
     m_pal = pal;
     Init(bm);
 }
Exemplo n.º 10
0
        public static void SaveFont(string strFileBitmap, Palette pal, string strFileAscii, string strFileSave)
        {
            // Get the character order
            TextReader tr = new StreamReader(strFileAscii);
            string strAscii = tr.ReadLine();
            tr.Close();

            // Get the character count
            int cch = strAscii.Length;

            // Load the image, lose scaling factor
            Bitmap bmFile = new Bitmap(strFileBitmap);
            Bitmap bm = Misc.NormalizeBitmap(bmFile);
            bmFile.Dispose();

            // Turn this on to see the character -> glyph mapping as it happens (help for
            // finding 'font bugs'). Set a breakpoint below on frm.Dispose().

            #if SHOWFONT
            Form frm = new Form();
            frm.Height = 1000;
            frm.Show();
            Graphics gT = frm.CreateGraphics();
            gT.InterpolationMode = InterpolationMode.NearestNeighbor;
            int yDst = 0;
            int xDst = 0;
            #endif
            // Scan the bitmap for widths
            int xLast = 0;
            int ich = 0;
            byte[] acxChar = new byte[256];
            for (int x = 0; x < bm.Width; x++) {
                if (bm.GetPixel(x, 0) != Color.FromArgb(255, 0, 255)) {
                    Debug.Assert(ich < cch);
                    acxChar[strAscii[ich]] = (byte)(x - xLast);
            #if SHOWFONT
                    gT.DrawString(strAscii[ich].ToString(), frm.Font, new SolidBrush(frm.ForeColor), new PointF(xDst, yDst));
                    Rectangle rcDst = new Rectangle(xDst + 20, yDst + 2, (x - xLast), bm.Height);
                    Rectangle rcSrc = new Rectangle(xLast, 1, x - xLast, bm.Height);
                    gT.DrawImage(bm, rcDst, rcSrc, GraphicsUnit.Pixel);
                    yDst += Math.Max(bm.Height, frm.Font.Height);
                    if (yDst > frm.ClientRectangle.Height) {
                        xDst += 50;
                        yDst = 0;
                    }

                    gT.Flush();
                    Application.DoEvents();
            #endif
                    ich++;
                    xLast = x;
                }
            }
            #if SHOWFONT
            gT.Dispose();
            frm.Dispose();
            #endif

            if (ich != cch) {
                MessageBox.Show(String.Format("Expecting {0} characters but found {2}{1}.",
                        cch, ich, ich < cch ? "only " : ""), "bcr2 - Font Compilation Error");
                Debug.Assert(ich == cch - 1);
            }
            int cy = bm.Height - 1;

            // Save serialization
            ArrayList alsSdEven = new ArrayList();
            int xT = 0;
            int ichDefault = -1;
            for (ich = 0; ich < cch; ich++) {
                // ? is the default "no glyph" character
                if (strAscii[ich] == '?')
                    ichDefault = ich;

                // Get subimage
                int cx = acxChar[strAscii[ich]];
                Rectangle rcT = new Rectangle(xT, 1, cx, cy);
                xT += cx;
                Bitmap bmT = new Bitmap(cx, cy, PixelFormat.Format24bppRgb);
                Graphics g = Graphics.FromImage(bmT);
                g.DrawImage(bm, 0, 0, rcT, GraphicsUnit.Pixel);
                g.Dispose();

                // Compile scan data
                TBitmap tbm = new TBitmap(bmT, pal);
                bmT.Dispose();

                // Save scan data serialization
                alsSdEven.Add(tbm.SerializeScanData());
            }

            //FontHeader {
            //	word cy;
            //	byte acxChar[256];
            //	word mpchibsdEven[256];
            //	ScanData asd[1];
            //};

            // First serialize scan data

            ArrayList alsIbsdEven = new ArrayList();
            ArrayList alsSd = new ArrayList();
            foreach (byte[] absd in alsSdEven) {
                if ((alsSd.Count & 1) != 0)
                    alsSd.Add((byte)0);
                alsIbsdEven.Add(alsSd.Count);
                alsSd.AddRange(absd);
            }

            // Write out to file
            BinaryWriter bwtr = new BinaryWriter(new FileStream(strFileSave, FileMode.Create, FileAccess.Write));

            // Height
            bwtr.Write(Misc.SwapUShort((ushort)cy));

            // Ascii ordered char widths in bytes. First init 0's to width of '?'

            if (ichDefault != -1) {
                for (ich = 0; ich < acxChar.Length; ich++) {
                    if (acxChar[ich] == 0) {
                        acxChar[ich] = acxChar[strAscii[ichDefault]];
                    }
                }
            }
            bwtr.Write(acxChar);

            // Ascii ordered offsets to even scan data (even)
            // Fill unused entries to entry for '?'
            int[] aibsdEven = new int[256];
            for (int ibsd = 0; ibsd < aibsdEven.Length; ibsd++)
                aibsdEven[ibsd] = -1;
            for (int i = 0; i < cch; i++)
                aibsdEven[strAscii[i]] = (int)alsIbsdEven[i];
            if (ichDefault != -1) {
                for (int ibsd = 0; ibsd < aibsdEven.Length; ibsd++) {
                    if (aibsdEven[ibsd] == -1) {
                        aibsdEven[ibsd] = (int)alsIbsdEven[ichDefault];
                    }
                }
            }

            // Write it out
            int cbHeader = 2 + 256 + 512;
            for (int i = 0; i < 256; i++)
                bwtr.Write(Misc.SwapUShort((ushort)(cbHeader + aibsdEven[i])));

            // Now save scan data
            bwtr.Write((byte[])alsSd.ToArray(typeof(byte)));

            // Done
            bwtr.Close();
        }
Exemplo n.º 11
0
        private void mniExport_Click(object sender, System.EventArgs e)
        {
            if (exportFileDialog.ShowDialog() != DialogResult.OK)
                return;
            string strExportDir = Path.GetDirectoryName(exportFileDialog.FileName);
            #if false
            if (m_strPaletteFileName == null) {
                if (openPaletteFileDialog.ShowDialog() != DialogResult.OK)
                    return;
                m_strPaletteFileName = openPaletteFileDialog.FileName;
                m_pal = new Palette(m_strPaletteFileName);
            }
            #endif

            AED.Export(m_anis, strExportDir, m_pal, false, false);
        }
Exemplo n.º 12
0
        public static int Main(string[] astrArgs)
        {
            bool fGui, fLoad = false, fImport = false, fSaveAs = false, fExport = false;
            bool fCrunch = false, fPalette = false, fValidateColors = false;
            string strLoadFileName = null, strImportFileSpec = null, strSaveAsFileName = null, strExportPath = null;
            string strPaletteFileName = null;

            fGui = astrArgs.Length == 0;

            // Parse command line arguments. Commands can be in any order.

            for (int i = 0; i < astrArgs.Length; i++) {
                switch (astrArgs[i]) {
                case "-g":
                    fGui = true;
                    break;

                case "-p":
                    fPalette = true;
                    if (i + 1 >= astrArgs.Length) {
                        Console.WriteLine("Error: -p command requires a filename argument");
                        return -1;
                    }
                    strPaletteFileName = astrArgs[++i];
                    break;

                case "-v":
                    gfVerbose = true;
                    break;

                case "-v2":
                    gfVerbose = true;
                    gfSuperVerbose = true;
                    break;

                case "-validatecolors":
                    fValidateColors = true;
                    break;

                case "-c":
                    fCrunch = true;
                    break;

                case "-l":
                    fLoad = true;
                    if (i + 1 >= astrArgs.Length) {
                        Console.WriteLine("Error: -f command requires a filename argument");
                        return -1;
                    }
                    strLoadFileName = astrArgs[++i];
                    break;

                case "-i":
                    fImport = true;
                    if (i + 1 >= astrArgs.Length) {
                        Console.WriteLine("Error: -i command requires a filespec argument");
                        return -1;
                    }
                    strImportFileSpec = astrArgs[++i];
                    break;

                case "-s":
                    fSaveAs = true;
                    if (i + 1 < astrArgs.Length && !astrArgs[i + 1].StartsWith("-"))
                        strSaveAsFileName = astrArgs[++i];
                    break;

                case "-x":
                    fExport = true;
                    if (i + 1 < astrArgs.Length && !astrArgs[i + 1].StartsWith("-"))
                        strExportPath = astrArgs[++i];
                    break;

                case "-?":
                case "-help":
                case "/?":
                case "/help":
                    Console.WriteLine(
                            "Usage:\nAED [-v] [-c] [-p palette.pal] <-l <filename> | -i <filespec>> [-s [filename]] [-x [dir]]\n" +
                            "-v: verbose\n" +
                            "-v2: super verbose!\n" +
                            "-c: crunch (compile to runtime format) when exporting\n" +
                            "-p palette.pal: specify the palette to be matched to when crunching to 8-bpp\n" +
                            "-l filename: load a .ani animation\n" +
                            "-s filename: save a .ani animation\n" +
                            "-i filespec: import a set of bitmaps\n" +
                            "-x dir: export a set of bitmaps to the specified directory\n" +
                            "-validatecolors: during crunch, validate that all pixel colors are in\n" +
                            "   the specified palette\n");
                    return 0;

                default:
                    Console.WriteLine("Error: Unknown command line argument \"{0}\"", astrArgs[i]);
                    return -1;
                }
            }

            // Additional command validation

            if (fLoad && fImport) {
                Console.WriteLine("Error: Can't use -l and -i commands together, they're ambiguous");
                return -1;
            }

            if (!fGui && !fLoad && !fImport) {
                Console.WriteLine("Error: Must specify either -l or -i command so AED has something to work with");
                return -1;
            }

            // Execute the specified commands

            AnimSet anis = new AnimSet();

            if (fLoad) {
                if (gfVerbose)
                    Console.WriteLine("Loading {0}...", strLoadFileName);
                if (!Load(anis, strLoadFileName))
                    return -1;
            }

            if (fImport) {
                if (gfVerbose)
                    Console.WriteLine("Importing {0}...", strImportFileSpec);
                if (!Import(anis, strImportFileSpec))
                    return -1;
            }

            if (fGui) {
                // This is modal and won't return until the MainForm is closed

                Application.Run(new Gui(anis.Items.Count != 0 ? anis : null));
            }

            if (fSaveAs) {
                if (gfVerbose)
                    Console.WriteLine("Saving {0}...", strSaveAsFileName);
                if (!SaveAs(anis, strSaveAsFileName))
                    return -1;
            }

            if (fExport) {
                if (gfVerbose)
                    Console.WriteLine("Exporting {1} to {0}...", strExportPath, anis.Name);
                Palette pal = null;
                if (fPalette)
                    pal = new Palette(strPaletteFileName);
                if (!Export(anis, strExportPath, pal, fCrunch, fValidateColors))
                    return -1;
            }

            return 0;
        }
Exemplo n.º 13
0
 public void SetPalette(Palette pal, bool fColorMatch)
 {
     m_pal = pal;
     SetModified(true);
     if (!fColorMatch)
         return;
     ArrayList alsColors = new ArrayList();
     foreach (Template tmpl in m_alsTemplates) {
         Bitmap bm = tmpl.Bitmap;
         bool[,] afOccupancy = tmpl.OccupancyMap;
         int ctx = afOccupancy.GetLength(1);
         int cty = afOccupancy.GetLength(0);
         for (int ty = 0; ty < cty; ty++) {
             for (int tx = 0; tx < ctx; tx++) {
                 if (!afOccupancy[ty, tx])
                     continue;
                 int xOrigin = tx * m_sizTile.Width;
                 int yOrigin = ty * m_sizTile.Height;
                 for (int y = yOrigin; y < yOrigin + m_sizTile.Height; y++) {
                     for (int x = xOrigin; x < xOrigin + m_sizTile.Width; x++) {
                         Color clrOld = bm.GetPixel(x, y);
                         Color clrNew = pal[pal.FindClosestEntry(clrOld)];
                         bm.SetPixel(x, y, clrNew);
                     }
                 }
             }
         }
         TemplateDocTemplate doct = (TemplateDocTemplate)m_doct;
         doct.OnTemplateChanged(this, "Bitmap", tmpl.Name, null);
     }
 }
Exemplo n.º 14
0
        void WriteMiniTiles(BinaryWriter bwtr, Palette pal, TemplateDoc tmpd, int cx, bool fNext, double nAreaBackgroundThreshold, double nLuminanceMultBackground, double nSaturationMultBackground, double nLuminanceMultForeground, double nSaturationMultForeground)
        {
            // struct MiniTileSetHeader { // mtshdr
            //  ushort offNext;
            //    ushort cTiles;
            //    ushort cxTile;
            //    ushort cyTile;
            // };

            ushort offNext = 0;
            if (fNext)
                offNext = (ushort)(8 + m_alsTileData.Count * cx * cx);
            bwtr.Write(Misc.SwapUShort(offNext));
            bwtr.Write(Misc.SwapUShort((ushort)m_alsTileData.Count));
            bwtr.Write(Misc.SwapUShort((ushort)cx));
            bwtr.Write(Misc.SwapUShort((ushort)cx));

            // If a background template exists, use it to distinguish foreground from background objects for better minimaps

            Size sizTile = tmpd.TileSize;
            ArrayList alsColors = new ArrayList();
            Template tmplBackground = tmpd.GetBackgroundTemplate();
            if (tmplBackground != null && nAreaBackgroundThreshold >= 0.0) {
                // Get despeckled hue map of background, calc mean and
                // std dev for filtering purposes

                Bitmap bmHueBackground = TemplateTools.MakeHueMap(tmplBackground.Bitmap);
                TemplateTools.DespeckleGrayscaleBitmap(bmHueBackground, 9, 50);
                double nMean = TemplateTools.CalcGrayscaleMean(bmHueBackground);
                double nStdDev = TemplateTools.CalcGrayscaleStandardDeviation(bmHueBackground, nMean);

                // Go through each tile, first make a mask that'll delineate foreground from background

                Bitmap bmTile = new Bitmap(sizTile.Width, sizTile.Height);
                foreach (TileData td in m_alsTileData) {
                    // Need to turn data back into a bitmap - doh!

                    for (int y = 0; y < sizTile.Height; y++) {
                        for (int x = 0; x < sizTile.Width; x++) {
                            Color clr = (Color)td.aclr[y * sizTile.Width + x];
                            bmTile.SetPixel(x, y, clr);
                        }
                    }

                    // Create mask which'll replace background with transparent color (255, 0, 255)

                    Bitmap bmMask = TemplateTools.MakeHueMap(bmTile);
                    TemplateTools.DespeckleGrayscaleBitmap(bmMask, 9, 50);
                    TemplateTools.SubtractGrayscaleDistribution(bmMask, nMean, nStdDev);

                    // Now scale tile down to desired size, using mask as input

                    Bitmap bmScaled = TemplateTools.ScaleTemplateBitmap(bmTile, bmMask, cx, cx, nAreaBackgroundThreshold, nLuminanceMultBackground, nSaturationMultBackground, nLuminanceMultForeground, nSaturationMultForeground);

                    // Grab the data

                    for (int y = 0; y < cx; y++) {
                        for (int x = 0; x < cx; x++) {
                            alsColors.Add(bmScaled.GetPixel(x, y));
                        }
                    }
                    bmScaled.Dispose();
                    bmMask.Dispose();
                }
            } else {
                // No background template; just scale

                Bitmap bmTile = new Bitmap(sizTile.Width, sizTile.Height);
                foreach (TileData td in m_alsTileData) {
                    // Need to turn data back into a bitmap - doh!

                    for (int y = 0; y < sizTile.Height; y++) {
                        for (int x = 0; x < sizTile.Width; x++) {
                            Color clr = (Color)td.aclr[y * sizTile.Width + x];
                            bmTile.SetPixel(x, y, clr);
                        }
                    }

                    // Now scale tile down to desired size, using mask as input

                    Bitmap bmScaled = TemplateTools.ScaleTemplateBitmap(bmTile, null, cx, cx, 1.0, 1.0, 1.0, 1.0, 1.0);

                    // Grab the data

                    for (int y = 0; y < cx; y++) {
                        for (int x = 0; x < cx; x++) {
                            alsColors.Add(bmScaled.GetPixel(x, y));
                        }
                    }
                    bmScaled.Dispose();
                }
            }

            // Palette match and write results

            foreach (Color clr in alsColors)
                bwtr.Write((byte)pal.FindClosestEntry(clr));
        }
Exemplo n.º 15
0
 public TileSet(TemplateDoc tmpd, string strFile, string strFilePal, int nDepth, Size sizTile)
 {
     TemplateDoc = tmpd;
     m_pal = new Palette(strFilePal + "_" + nDepth.ToString() + "bpp.pal");
     TileCollectionFileName = strFile;
     FileName = strFile.Replace(".tc", ".tset");
     PalBinFileName = Path.GetFileName(strFilePal) + ".palbin";
     m_sizTile = sizTile;
     SuckTemplates();
 }
Exemplo n.º 16
0
 public TileSet(TemplateDoc tmpd, string strFile)
 {
     TemplateDoc = tmpd;
     m_pal = tmpd.GetPalette();
     m_sizTile = tmpd.TileSize;
     FileName = strFile.Replace(".tc", ".tset");
     SuckTemplates();
 }
Exemplo n.º 17
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="bm"></param>
 /// <param name="pal"></param>
 public TBitmap(Bitmap bm, Palette pal)
 {
     m_bm = new Bitmap(bm);
     m_pal = pal;
 }
Exemplo n.º 18
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="strFile"></param>
 /// <param name="pal"></param>
 public TBitmap(string strFile, Palette pal)
 {
     m_bm = new Bitmap(strFile);
     m_pal = pal;
 }
Exemplo n.º 19
0
 public TBitmap(Palette pal)
 {
     m_pal = pal;
 }
Exemplo n.º 20
0
 public TBitmap(Bitmap bm, Palette pal)
 {
     m_pal = pal;
     Init(bm);
 }
Exemplo n.º 21
0
        public TemplateDoc(SerializationInfo info, StreamingContext ctx)
            : base((DocTemplate)(((Hashtable)ctx.Context)["DocTemplate"]), (string)(((Hashtable)ctx.Context)["Filename"]))
        {
            m_cookie = info.GetInt32("Cookie");

            // Backwards compat

            try {
                m_strNameBackground = info.GetInt32("CookieBackground").ToString();
            } catch {
                m_strNameBackground = "0";
                try {
                    m_strNameBackground = info.GetString("NameBackground");
                } catch {
                }
            }

            // Get tile size. If none, default 16,16

            try {
                m_sizTile = (Size)info.GetValue("TileSize", typeof(Size));
            } catch {
                m_sizTile = new Size(16, 16);
            }

            // Get palette

            try {
                m_pal = (Palette)info.GetValue("Palette", typeof(Palette));
            } catch {
                m_pal = null;
            }

            m_alsTemplates = (ArrayList)info.GetValue("TileTemplates", typeof(ArrayList));
        }
Exemplo n.º 22
0
        public static void MakePalette(string[] astr)
        {
            // -makepal 16 templates.tc palsize fixpalsize backgroundpalsize fixed.pal out.pal

            // tile size

            Size sizTile = new Size(0, 0);
            sizTile.Width = int.Parse(astr[1]);
            sizTile.Height = sizTile.Width;

            // Load template collection

            TemplateDoc tmpd = (TemplateDoc)DocManager.OpenDocument(astr[2]);

            // palette size

            int cPalEntries = int.Parse(astr[3]);

            // entries fixed

            int cPalEntriesFixed = int.Parse(astr[4]);

            // entries for background

            int cPalEntriesBackground = int.Parse(astr[5]);

            // fixed palette

            Palette palFixed = new Palette(astr[6]);

            // output palette

            string strFilePalOut = astr[7];

            // If this template collection already has a palette it has already been quantized; we don't
            // want that.

            if (tmpd.GetPalette() != null)
                new Exception("Template collection has already been quantized!");

            // Scale templates if needed

            if (sizTile.Width != tmpd.TileSize.Width || sizTile.Height != tmpd.TileSize.Height)
                TemplateTools.ScaleTemplates(tmpd, sizTile);

            // Quantize

            TemplateTools.QuantizeTemplates(tmpd, palFixed, cPalEntries, cPalEntriesFixed, cPalEntriesBackground);

            // Save the new palette out

            Palette palNew = tmpd.GetPalette();
            palNew.SaveJasc(strFilePalOut);
        }
Exemplo n.º 23
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="bm"></param>
 /// <param name="pal"></param>
 public TBitmap(Bitmap bm, Palette pal)
 {
     m_bm  = new Bitmap(bm);
     m_pal = pal;
 }
Exemplo n.º 24
0
 public TBitmap(string strFile, Palette pal)
 {
     m_pal = pal;
     Init(new Bitmap(strFile));
 }
Exemplo n.º 25
0
        // Write the .anir file and .bmps or .tbms, depending on fCrunch
        public static bool Export(AnimSet anis, string strExportPath, Palette pal, bool fCrunch, bool fValidateColors)
        {
            Color clrTransparent = Color.FromArgb(0xff, 0, 0xff);
            SolidBrush brTransparent = new SolidBrush(clrTransparent);

            if (strExportPath == null)
                strExportPath = ".";

            ASCIIEncoding enc = new ASCIIEncoding();

            FileStream stm = new FileStream(strExportPath + @"\" + anis.Name + ".anir", FileMode.Create, FileAccess.Write);
            BinaryWriter stmw = new BinaryWriter(stm);

            // Count the number of FrameSets (aka Strips)

            ushort cstpd = 0;
            foreach (DictionaryEntry deAnimSet in anis.Items) {
                Anim ani = (Anim)deAnimSet.Value;
                cstpd += (ushort)ani.Items.Count;
            }

            // Write AnimationFileHeader.cstpd

            stmw.Write(Misc.SwapUShort(cstpd));

            // Write array of offsets to StripDatas (AnimationFileHeader.aoffStpd)

            ushort offStpd = (ushort)(2 + (2 * cstpd));
            byte ibm = 0;
            ArrayList albm = new ArrayList();

            foreach (DictionaryEntry deAnimSet in anis.Items) {
                Anim ani = (Anim)deAnimSet.Value;
                foreach (DictionaryEntry deAnim in ani.Items) {
                    FrameSet frms = (FrameSet)deAnim.Value;
                    stmw.Write(Misc.SwapUShort(offStpd));

                    // Advance offset to where the next StripData will be

                    offStpd += (ushort)((26+1+1+2) /* sizeof(StripData) - sizeof(FrameData) */ +
                            ((1+1+1+1+1+1) /* sizeof(FrameData) */ * frms.Count));
                }
            }

            // Write array of StripDatas

            foreach (DictionaryEntry deAnimSet in anis.Items) {
                Anim ani = (Anim)deAnimSet.Value;
                foreach (DictionaryEntry deAnim in ani.Items) {
                    FrameSet frms = (FrameSet)deAnim.Value;

                    // Write StripData.Name

                    string strName = ani.Name + " " + frms.Name;
                    byte[] abT = new byte[26];
                    enc.GetBytes(strName, 0, Math.Min(strName.Length, 25), abT, 0);
                    abT[25] = 0;
                    stmw.Write(abT);

                    // Write StripData.cDelay

                    stmw.Write((byte)0);

                    // Write StripData.bfFlags

                    stmw.Write((byte)0);

                    // Write StripData.cfrmd

                    ushort cfrmd = (ushort)frms.Count;
                    stmw.Write(Misc.SwapUShort(cfrmd));

                    // Write array of FrameDatas

                    foreach (Frame frm in frms) {

                        // Write FrameData.ibm (the index of the Bitmap as it will be in the Bitmap array)

                        stmw.Write((byte)ibm);
                        ibm++;

                        // Add the Frame's Bitmap for output

                        Bitmap bm = frm.Bitmap;
                        if (fCrunch) {
                            albm.Add(bm);
                        } else {
                            // If not crunching then we need to go through some special work to preserve
                            // the origin point. Since the origin point is determined by finding the center
                            // of the imported bitmap we preserve it at export by creating a new bitmap
                            // sized so that he origin will be in its center.

                            // The '+2' at the end gives us a pixel of transparent space padding the left
                            // and right sides of the bitmap. We don't require this for any particular
                            // reason but it comes in handy.

                            int cxNew = (Math.Max(frm.OriginX, bm.Width - frm.OriginX) * 2) + 2;

                            // The '+2' at the end is to ensure a single blank scanline at the top
                            // which Import relies on to determine the transparent color.

                            int cyNew = (Math.Max(frm.OriginY, bm.Height - frm.OriginY) * 2) + 2;

                            using (Bitmap bmNew = new Bitmap(cxNew, cyNew, bm.PixelFormat)) {
                                using (Graphics g = Graphics.FromImage(bmNew)) {
                                    g.FillRectangle(brTransparent, 0, 0, cxNew, cyNew);
                                    g.DrawImage(bm, cxNew / 2 - frm.OriginX, cyNew / 2 - frm.OriginY);
                                }
                                strName = anis.Name + "_" + ani.Name + "_" + frms.Name + "_" + frm.Index.ToString();
                                bmNew.Save(strExportPath + @"\" + strName + ".png", ImageFormat.Png);
                            }
                        }

                        // Write FrameData.xOrigin, FrameData.yOrigin

                        stmw.Write((byte)frm.OriginX);
                        stmw.Write((byte)frm.OriginY);

                        // Write FrameData.bCustomData1, FrameData.bCustomData2, FrameData.bCustomData3

                        stmw.Write((byte)0);
                        stmw.Write((byte)0);
                        stmw.Write((byte)0);
                    }
                }
            }

            stmw.Close();

            // Write out .tbm

            if (albm.Count != 0) {
                string strFileName = strExportPath + @"\" + anis.Name + ".tbm";
                if (gfSuperVerbose)
                    Console.WriteLine("Crunching and writing " + strFileName);
                TBitmap.Save((Bitmap[])albm.ToArray(typeof(Bitmap)), pal, strFileName);
            }

            return true;
        }
Exemplo n.º 26
0
        static Strip MakeHighlightStrip(AnimDoc doc, int cxTile,
                Palette palFixed)
        {
            Strip stpHelp = doc.StripSet["help"];
            if (stpHelp == null) {
                return null;
            }

            // This does a deep copy
            Strip stpHighlight = (Strip)stpHelp.Clone();
            stpHighlight.Name = "highlight";

            // Figure out the scaling. It would be better to pass this in as
            // a parameter.

            Frame frT = stpHighlight[0];
            Rectangle rcUnion = new Rectangle();
            foreach (BitmapPlacer plc in frT.BitmapPlacers) {
                Rectangle rc = new Rectangle();
                rc.X = -plc.X;
                rc.Y = -plc.Y;
                rc.Width = plc.XBitmap.Width;
                rc.Height = plc.XBitmap.Height;
                if (rcUnion.IsEmpty) {
                    rcUnion = rc;
                } else {
                    rcUnion = Rectangle.Union(rcUnion, rc);
                }
            }

            // Needs to be 4 tiles high. Keep aspect ratio

            int cy = rcUnion.Height;
            if (cy < cxTile * 4) {
                cy = cxTile * 4;
            }
            double nScale = 1.0;
            if (cy > rcUnion.Height) {
                nScale = (double)cy / (double)rcUnion.Height;
            }

            // Scale

            if (nScale != 1.0) {
                foreach (Frame fr in stpHighlight) {
                    foreach (BitmapPlacer plc in fr.BitmapPlacers) {
                        plc.XBitmap.Bitmap = TBitmapTools.ScaleBitmap(
                            plc.XBitmap.Bitmap, nScale, palFixed);
                        plc.X = (int)Math.Round(plc.X * nScale);
                        plc.Y = (int)Math.Round(plc.Y * nScale);
                    }

                    Point pt = new Point();
                    pt.X = (int)Math.Round(fr.SpecialPoint.X * nScale);
                    pt.Y = (int)Math.Round(fr.SpecialPoint.Y * nScale);
                    fr.SpecialPoint = pt;
                }
            }

            return stpHighlight;
        }
Exemplo n.º 27
0
        public static void Save(Bitmap[] abm, Palette pal, string strFile)
        {
            // Open file for writing
            BinaryWriter bwtr = new BinaryWriter(new FileStream(strFile, FileMode.Create, FileAccess.Write));

            // Convert into tbm's
            TBitmap[] atbm = new TBitmap[abm.Length];
            for (int ibm = 0; ibm < abm.Length; ibm++)
                atbm[ibm] = new TBitmap(abm[ibm], pal);

            // Serialize the whole thing
            bwtr.Write(Serialize(atbm));

            // All done
            bwtr.Close();
        }
Exemplo n.º 28
0
        static void Scale(AnimDoc doc, double nScale, Palette palFixed, bool fScaleIcon)
        {
            if (nScale >= 1.5)
                doc.Hires = true;

            // If not scaling icon, make a clone of it so it doesn't get scaled,
            // then after scaling set this clone back in.

            Strip stpIcon = doc.StripSet["icon"];
            Strip stpIconClone = null;
            if (!fScaleIcon && stpIcon != null) {
                stpIconClone = (Strip)stpIcon.Clone();
            }

            // Scale all the bitmaps

            foreach (XBitmap xbm in doc.XBitmapSet) {
                // Scale

                xbm.Bitmap = TBitmapTools.ScaleBitmap(xbm.Bitmap, nScale, palFixed);

                // Scale the points in the frames that use this bitmap

                foreach (Strip stp in doc.StripSet) {
                    foreach (Frame fr in stp) {
                        foreach (BitmapPlacer plc in fr.BitmapPlacers) {
                            if (plc.XBitmap == xbm) {
                                plc.X = (int)Math.Round(plc.X * nScale);
                                plc.Y = (int)Math.Round(plc.Y * nScale);
                            }
                        }
                    }
                }
            }

            // Scale all special points too

            foreach (Strip stp in doc.StripSet) {
                foreach (Frame fr in stp) {
                    Point pt = new Point();
                    pt.X = (int)Math.Round(fr.SpecialPoint.X * nScale);
                    pt.Y = (int)Math.Round(fr.SpecialPoint.Y * nScale);
                    fr.SpecialPoint = pt;
                }
            }

            // Put the strip icon back in if it shouldn't be scaled

            if (!fScaleIcon && stpIconClone != null) {
                // Patch in the clone and add the images to the XBitmapSet
                // (they are not added auto-magically).

                doc.StripSet[doc.StripSet.IndexOf(stpIcon)] = stpIconClone;
                foreach (Frame fr in stpIconClone) {
                    foreach (BitmapPlacer plc in fr.BitmapPlacers) {
                        doc.XBitmapSet.Add(plc.XBitmap);
                    }
                }
            }
        }
Exemplo n.º 29
0
 public TBitmap(string strFile, Palette pal)
 {
     m_pal = pal;
     Init(new Bitmap(strFile));
 }
Exemplo n.º 30
0
        static int Main(string[] astrArgs)
        {
            if (astrArgs.Length < 3 || astrArgs.Length > 10) {
                Console.WriteLine("Usage:\nacrunch [-scale N] [-save] [-noscaleicon] [-noshrinkwrap] [-highlight <cxTile>] [-stats] <palette.pal> <input.amx> <outdir>\n");
                return -1;
            }

            double nScale = 1.0;
            bool fSave = false;
            bool fNoShrinkWrap = false;
            bool fDumpStats = false;
            bool fScaleIcon = true;
            bool fMakeHighlight = true;
            int cxTile = 0;

            int iarg = 0;
            while (astrArgs[iarg][0] == '-') {
                switch (astrArgs[iarg]) {
                case "-scale":
                    nScale = double.Parse(astrArgs[++iarg]);
                    break;

                case "-noscaleicon":
                    fScaleIcon = false;
                    break;

                case "-save":
                    fSave = true;
                    break;

                case "-noshrinkwrap":
                    fNoShrinkWrap = true;
                    break;

                case "-stats":
                    fDumpStats = true;
                    break;

                case "-highlight":
                    fMakeHighlight = true;
                    cxTile = Int32.Parse(astrArgs[++iarg]);
                    break;
                }

                iarg++;
            }

            // Read in the palette

            string strFilePal = astrArgs[iarg++];
            Palette pal = new Palette(strFilePal);
            if (pal == null) {
                Console.WriteLine("Error: unable to read the palette file {0}\n", strFilePal);
                return -1;
            }

            // Read in the animation file (.amx)

            string strFileAmx = astrArgs[iarg++];
            AnimDoc doc = AnimDoc.Load(strFileAmx);
            if (doc == null) {
                Console.WriteLine("Error: unable to read animation file {0}\n", strFileAmx);
                return -1;
            }

            // Get directory

            string strDir = astrArgs[iarg++];

            // Reduce the Bitmaps down to the tightest rectangular boundary around the
            // non-transparent pixels.

            if (!fNoShrinkWrap)
                ShrinkWrap(doc);

            // Make highlight if asked. This uses existing images, so do this
            // before scaling.

            Strip stpHighlight = null;
            if (fMakeHighlight) {
                stpHighlight = MakeHighlightStrip(doc, cxTile, pal);
            }

            // Scale if asked

            if (nScale != 1.0) {
                Scale(doc, nScale, pal, fScaleIcon);
            }

            // Add in highlight strip

            if (stpHighlight != null) {
                doc.StripSet.Add(stpHighlight);
                foreach (Frame fr in stpHighlight) {
                    foreach (BitmapPlacer plc in fr.BitmapPlacers) {
                        doc.XBitmapSet.Add(plc.XBitmap);
                    }
                }
            }

            // If dump stats, we're *only* dumping stats

            if (fDumpStats) {
                DumpStats(doc);
                return 0;
            }

            // Write the runtime animation file (.anir) and crunched bitmaps

            if (fSave)
                doc.Save(strDir + Path.DirectorySeparatorChar + Path.GetFileName(strFileAmx));
            else
                doc.WriteAnir(pal, strDir, Path.GetFileNameWithoutExtension(strFileAmx));
            return 0;
        }
Exemplo n.º 31
0
 public TBitmap(Palette pal)
 {
     m_pal = pal;
 }
Exemplo n.º 32
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="strFile"></param>
 /// <param name="pal"></param>
 public TBitmap(string strFile, Palette pal)
 {
     m_bm  = new Bitmap(strFile);
     m_pal = pal;
 }
Exemplo n.º 33
0
 static Palette QuantizeColors(ArrayList alsColors, Palette palFixed, int cPalEntries, int cPalEntriesFixed)
 {
     Palette palNew = null;
     while (true) {
         palNew = QuantizeColors2(alsColors, palFixed, cPalEntries, cPalEntriesFixed);
         ArrayList alsColorsNew = new ArrayList();
         foreach (Color clr in alsColors) {
             int iclr = palNew.FindClosestEntry(clr);
             if (iclr >= cPalEntriesFixed)
                 alsColorsNew.Add(clr);
         }
         if (alsColorsNew.Count == alsColors.Count)
             break;
         alsColors = alsColorsNew;
     }
     return palNew;
 }
Exemplo n.º 34
0
        static unsafe int Main(string[] astrArgs)
        {
            // Command-line argument processing

            if (astrArgs.Length == 0) {
                PrintHelp();
                return 0;
            }

            for (int i = 0; i < astrArgs.Length; i++) {
                switch (astrArgs[i]) {
                case "-?":
                    PrintHelp();
                    return 0;

                case "-i":
                    giclrInsert = Int32.Parse(astrArgs[++i]);
                    break;

                case "-p":
                    gcPaletteEntries = Int32.Parse(astrArgs[++i]);
                    break;

                case "-c":
                    gcColorEntries = Int32.Parse(astrArgs[++i]);
                    break;

                case "-t":
                    gfEliminateTransparentColor = true;
                    break;

                case "-s":
                    gfEliminateShadowColor = true;
                    break;

                case "-v":
                    gfVerbose = true;
                    break;

                case "-u":
                    gfPrintColorUsers = true;
                    break;

                case "-6":
                    gf6bitRGB = true;
                    break;

                case "-h":
                    gfPrintHistogram = true;
                    break;

                case "-a":
                    gfAnalyse = true;
                    break;

                case "-n":
                    gfPhotoshopPad = true;
                    break;

                case "-f":
                    AddFilesFromFile(astrArgs[++i]);
                    break;

                case "-o":
                    if (i + 1 >= astrArgs.Length) {
                        Console.WriteLine("Error: -o command requires a filename argument");
                        return -1;
                    }
                    gstrOutputFileName = astrArgs[++i];
                    break;

                default:
                    if (astrArgs[i][0] == '-') {
                        Console.WriteLine("Error: invalid flag '{0}'", astrArgs[i]);
                        return -1;
                    }

                    // Assume all 'unassociated' arguments are input filenames (potentially wildcarded)

                    AddFiles(astrArgs[i]);
                    break;
                }
            }

            if (gstrcFileNames.Count == 0) {
                Console.WriteLine("Error: no files specified");
                return -1;
            }

            // Build a list of the colors used and count of uses for each bitmap

            ArrayList alstBitmapColorInfos = new ArrayList();

            foreach (string strFileName in gstrcFileNames) {

                BitmapColorInfo bci = new BitmapColorInfo();
                bci.strFileName = strFileName;
                bci.htColorCount = new Hashtable();

                // Handle .PALs

                if (strFileName.ToLower().EndsWith(".pal")) {
                    Palette pal = new Palette(strFileName);

                    int i = 0;
                    foreach (Color clr in pal.Colors) {
                        Color clrT = clr;
                        if (gf6bitRGB)
                            clrT = Color.FromArgb(clr.R & 0xfc, clr.G & 0xfc, clr.B & 0xfc);

                        // This hack causes the .PAL colors to be sorted at the head of the
                        // combined palette while retaining the order they were found in the .PAL.

                        if (!bci.htColorCount.Contains(clrT))
                            bci.htColorCount[clrT] = (Int32.MaxValue / 2) - i++;
                    }

                // Handle everything else (bitmaps)

                } else {
                    Bitmap bm = null;
                    try {
                        bm = new Bitmap(strFileName);
                    } catch {
                        Console.WriteLine("Error: {0} is not a recognized bitmap or palette file", strFileName);
                        continue;
                    }

                    // Prep to filter out the transparent color

                    Color clrTransparent = Color.GhostWhite;
                    if (gfEliminateTransparentColor)
                        clrTransparent = bm.GetPixel(0, 0);

                    // Prep to filter out the shadow color

                    Color clrShadow = Color.GhostWhite;
                    if (gfEliminateShadowColor)
                        clrShadow = Color.FromArgb(156, 212, 248);

                    // Keep a per-bitmap list of unique colors and how many times they're used

                    Hashtable ht = bci.htColorCount;

                    // Lock down bits for speed

                    Rectangle rc = new Rectangle(0, 0, bm.Width, bm.Height);
                    BitmapData bmd = bm.LockBits(rc, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                    byte *pbBase = (byte *)bmd.Scan0.ToPointer();

                    for (int y = 0; y < bm.Height; y++) {
                        for (int x = 0; x < bm.Width; x++) {
                            byte *pb = pbBase + y * bmd.Stride + x * 3;
                            Color clr = Color.FromArgb(pb[2], pb[1], pb[0]);
                            if (gfEliminateTransparentColor && clr == clrTransparent)
                                continue;

                            if (gfEliminateShadowColor && clr == clrShadow)
                                continue;

                            if (gf6bitRGB)
                                clr = Color.FromArgb(clr.R & 0xfc, clr.G & 0xfc, clr.B & 0xfc);

                            object obT = ht[clr];
                            if (obT == null)
                                ht[clr] = 1;
                            else
                                ht[clr] = 1 + (int)obT;
                        }
                    }
                    bm.UnlockBits(bmd);
                }

                if (gfVerbose)
                    Console.WriteLine("{0} uses {1} colors", strFileName, bci.htColorCount.Count);

                if (gfPrintHistogram && gfVerbose) {
                    foreach (DictionaryEntry de in bci.htColorCount) {
                        Color clr = (Color)de.Key;
                        Console.WriteLine("{0},{1},{2} : {3} occurances", clr.R, clr.G, clr.B, (int)de.Value);
                    }
                    Console.WriteLine();
                }

                alstBitmapColorInfos.Add(bci);
            }

            if (alstBitmapColorInfos.Count == 0) {
                Console.WriteLine("Error: no valid bitmap files to process, terminating");
                return -1;
            }

            // Combine all the color tables and count data

            Hashtable htCombined = new Hashtable();

            foreach (BitmapColorInfo bci in alstBitmapColorInfos) {
                foreach (DictionaryEntry de in bci.htColorCount) {
                    Color clr = (Color)de.Key;
                    ColorCounter clrc = (ColorCounter)htCombined[clr];
                    if (clrc == null) {
                        clrc = new ColorCounter();
                        clrc.cclr = (int)de.Value;
                        htCombined[clr] = clrc;
                    } else {
                        int nAdd = (int)de.Value;
                        if (nAdd > Int32.MaxValue / 3)
                            clrc.cclr = (int)de.Value;
                        else if (clrc.cclr < Int32.MaxValue / 3)
                            clrc.cclr += nAdd;
                    }
                    clrc.alBitmaps.Add(bci.strFileName);
                }
            }

            int cclrCombined = htCombined.Count;
            Console.WriteLine("Combined palette has {0} unique colors", cclrCombined);

            // Sort everything by # colors used

            ColorCounter[] aclrcSorted = new ColorCounter[cclrCombined];
            //			int i = 0;
            //			foreach (ColorCounter clrc in htCombined.Values)
            //				acOccurancesSorted[i++] = clrc.cclr;
            htCombined.Values.CopyTo(aclrcSorted, 0);
            Color[] aclrSorted = new Color[cclrCombined];
            htCombined.Keys.CopyTo(aclrSorted, 0);

            Array.Sort(aclrcSorted, aclrSorted);

            // Reverse so most-used colors come first
            // OPT: could do this inside the Sort above by specifying a custom IComparer

            Array.Reverse(aclrcSorted);
            Array.Reverse(aclrSorted);

            if (gfPrintHistogram || gfPrintColorUsers) {
                for (int i = 0; i < cclrCombined; i++) {
                    Color clr = aclrSorted[i];
                    int cOccurances = aclrcSorted[i].cclr;
                    if (cOccurances >= Int32.MaxValue / 3)
                        Console.WriteLine("{0},{1},{2} : preloaded", clr.R, clr.G, clr.B);
                    else
                        Console.WriteLine("{0},{1},{2} : {3} occurances", clr.R, clr.G, clr.B, cOccurances);

                    if (gfPrintColorUsers) {
                        foreach (string strFileName in aclrcSorted[i].alBitmaps) {
                            Console.WriteLine("    {0}", strFileName);
                        }
                    }
                }
            }

            // Print warning if # of unique colors is greater than the desired palette size
            // Truncate to match the requested size since other tools depend on this

            if (cclrCombined > gcColorEntries) {
                Console.WriteLine("Warning! {0} unique colors, {1} palette entries reserved. Truncating...",  cclrCombined, gcColorEntries);
                Color[] aclrSortedT = new Color[gcColorEntries];
                Array.Copy(aclrSorted, 0, aclrSortedT, 0, gcColorEntries);
                aclrSorted = aclrSortedT;
                ColorCounter[] aclrcSortedT = new ColorCounter[gcColorEntries];
                Array.Copy(aclrcSorted, 0, aclrcSortedT, 0, gcColorEntries);
                aclrcSorted = aclrcSortedT;
                cclrCombined = gcColorEntries;
            }

            // Create the palette. Presorted colors start at 0. New colors start at giclrInsert.
            // giclrInsert == -1 means new colors are simply appended to the presorted colors.

            Color[] aclrPalette = aclrSorted;

            if (giclrInsert != -1) {
                // Init to transparent

                aclrPalette = new Color[gcColorEntries];
                for (int i = 0; i < aclrPalette.Length; i++)
                    aclrPalette[i] = Color.FromArgb(255, 0, 255);

                // Insert new colors appropriately

                int iclrBase = -1;
                for (int i = 0; i < cclrCombined; i++) {
                    if (aclrcSorted[i].cclr >= Int32.MaxValue / 3) {
                        aclrPalette[i] = aclrSorted[i];
                        continue;
                    }
                    if (iclrBase == -1)
                        iclrBase = i;
                    int iclrNew = giclrInsert + (i - iclrBase);
                    if (iclrNew < aclrPalette.Length)
                        aclrPalette[iclrNew] = aclrSorted[i];
                }
            }

            // Write the output palette file, if requested

            if (gstrOutputFileName != null) {
                Palette pal = new Palette(aclrPalette);
                if (gfPhotoshopPad)
                    pal.Pad(gcPaletteEntries, pal[pal.Length - 1]);
                else
                    pal.Pad(gcPaletteEntries, Color.FromArgb(255, 0, 255));
                pal.SaveJasc(gstrOutputFileName);
            }

            if (gfAnalyse) {
                Palette pal = new Palette(aclrPalette);

                // For each color find the nearest color in RGB space and print
                // the pair as well as the distance between them.

                for (int iclrA = 0; iclrA < aclrPalette.Length; iclrA++) {
                    Color clrA = aclrPalette[iclrA];

                    // Find the entry, the long way

                    int nLowest = 256 * 256 * 3;
                    int iLowest = 0;
                    for (int iclr = 0; iclr < aclrPalette.Length; iclr++) {
                        if (iclr == iclrA)
                            continue;

                        Color clrPal = aclrPalette[iclr];
                        int dR = clrPal.R - clrA.R;
                        int dG = clrPal.G - clrA.G;
                        int dB = clrPal.B - clrA.B;
                        int nD = dR * dR + dG * dG + dB * dB;
                        if (nD < nLowest) {
                            nLowest = nD;
                            iLowest = iclr;
                        }
                    }

                    Color clrB = aclrPalette[iLowest];
                    double n = Math.Sqrt(nLowest);
                    Console.WriteLine("{8:#.##}\t[{3}] {0},{1},{2} \t[{7}] {4},{5},{6}",
                            clrA.R, clrA.G, clrA.B, iclrA, clrB.R, clrB.G, clrB.B, iLowest, n);
                }
            }

            return 0;
        }
Exemplo n.º 35
0
        static unsafe int Main(string[] astrArgs)
        {
            // Command-line argument processing

            if (astrArgs.Length == 0) {
                PrintHelp();
                return 0;
            }

            for (int i = 0; i < astrArgs.Length; i++) {
                switch (astrArgs[i]) {
                case "-?":
                    PrintHelp();
                    return 0;

                case "-p":
                    gstrPalette = astrArgs[++i];
                    gpal = new Palette(gstrPalette);
                    break;

                case "-6":
                    gf6bitRGB = true;
                    break;

                default:
                    if (astrArgs[i][0] == '-') {
                        Console.WriteLine("Error: invalid flag '{0}'", astrArgs[i]);
                        return -1;
                    }

                    // Assume all 'unassociated' arguments are input filenames (potentially wildcarded)

                    string strDir = Path.GetDirectoryName(astrArgs[i]);
                    if (strDir == "")
                        strDir = ".";
                    string[] astrFileNames = Directory.GetFiles(strDir, Path.GetFileName(astrArgs[i]));

                    if (astrFileNames.Length == 0) {
                        gstrcFileNames.Add(astrArgs[i]);
                    } else {
                        foreach (string strFileName in astrFileNames) {
                            if (strFileName.ToLower().EndsWith(".ani")) {
                                string strT = Path.GetDirectoryName(strFileName) + @"\" + Path.GetFileNameWithoutExtension(strFileName) + @"\*.png";
                                string[] astrT = Directory.GetFiles(Path.GetDirectoryName(strT), Path.GetFileName(strT));
                                gstrcFileNames.AddRange(astrT);
                            } else {
                                gstrcFileNames.Add(strFileName);
                            }
                        }
                    }
                    break;
                }
            }

            if (gpal == null) {
                Console.WriteLine("A valid palette must be specified via the '-p' switch");
                return -1;
            }

            if (gstrcFileNames.Count == 0) {
                Console.WriteLine("Error: no files specified");
                return -1;
            }

            int nReturnValue = 0;
            Color clrShadow = Color.FromArgb(156, 212, 248);

            Console.Write("Verifying bitmap colors...");

            foreach (string strFileName in gstrcFileNames) {
                Hashtable htInvalidColors = new Hashtable();
                Bitmap bm = null;
                try {
                    bm = new Bitmap(strFileName);
                } catch {
                    Console.WriteLine("Error: {0} is not a recognized bitmap or palette file", strFileName);
                    continue;
                }

                Color clrTransparent = bm.GetPixel(0, 0);
                if (gf6bitRGB)
                    clrTransparent = Color.FromArgb(clrTransparent.R & 0xfc, clrTransparent.G & 0xfc, clrTransparent.B & 0xfc);

                // Lock down bits for speed

                Rectangle rc = new Rectangle(0, 0, bm.Width, bm.Height);
                BitmapData bmd = bm.LockBits(rc, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                byte *pbBase = (byte *)bmd.Scan0.ToPointer();

                for (int y = 0; y < bm.Height; y++) {
                    for (int x = 0; x < bm.Width; x++) {
                        byte *pb = pbBase + y * bmd.Stride + x * 3;
                        Color clr;
                        if (gf6bitRGB)
                            clr = Color.FromArgb(pb[2] & 0xfc, pb[1] & 0xfc, pb[0] & 0xfc);
                        else
                            clr = Color.FromArgb(pb[2], pb[1], pb[0]);

                        int i = gpal.FindClosestEntry(clr);
                        if (gpal[i] != clr && clr != clrShadow && clr != clrTransparent && !htInvalidColors.ContainsKey(clr))
                                htInvalidColors.Add(clr, clr);
                    }
                }
                bm.UnlockBits(bmd);

                // Report any invalid colors

                if (htInvalidColors.Count != 0) {
                    if (nReturnValue == 0)
                        Console.WriteLine();
                    nReturnValue = -1;

                    int cclr = htInvalidColors.Count;

                    Color[] aclr = new Color[cclr];
                    htInvalidColors.Values.CopyTo(aclr, 0);
                    Console.Write("{0} contains {1} invalid color{2} (",
                            Path.GetFileName(strFileName), cclr, cclr == 1 ? "" : "s");
                    for (int i = 0; i < aclr.Length; i++) {
                        Color clr = aclr[i];
                        Console.Write("{0},{1},{2}", clr.R, clr.G, clr.B);
                        if (i != aclr.Length - 1)
                            Console.Write(", ");
                    }
                    Console.WriteLine(")");
                }
            }

            if (nReturnValue == 0)
                Console.WriteLine("done");
            return nReturnValue;
        }
Exemplo n.º 36
0
        static public void SaveFont(string strFileBitmap, Palette pal, string strFileAscii, string strFileSave)
        {
            // Get the character order
            TextReader tr       = new StreamReader(strFileAscii);
            string     strAscii = tr.ReadLine();

            tr.Close();

            // Get the character count
            int cch = strAscii.Length;

            // Load the image, lose scaling factor
            Bitmap bmFile = new Bitmap(strFileBitmap);
            Bitmap bm     = Misc.NormalizeBitmap(bmFile);

            bmFile.Dispose();

// Turn this on to see the character -> glyph mapping as it happens (help for
// finding 'font bugs'). Set a breakpoint below on frm.Dispose().

#if SHOWFONT
            Form frm = new Form();
            frm.Height = 1000;
            frm.Show();
            Graphics gT = frm.CreateGraphics();
            gT.InterpolationMode = InterpolationMode.NearestNeighbor;
            int yDst = 0;
            int xDst = 0;
#endif
            // Scan the bitmap for widths
            int    xLast   = 0;
            int    ich     = 0;
            byte[] acxChar = new byte[256];
            for (int x = 0; x < bm.Width; x++)
            {
                if (bm.GetPixel(x, 0) != Color.FromArgb(255, 0, 255))
                {
                    Debug.Assert(ich < cch);
                    acxChar[strAscii[ich]] = (byte)(x - xLast);
#if SHOWFONT
                    gT.DrawString(strAscii[ich].ToString(), frm.Font, new SolidBrush(frm.ForeColor), new PointF(xDst, yDst));
                    Rectangle rcDst = new Rectangle(xDst + 20, yDst + 2, (x - xLast), bm.Height);
                    Rectangle rcSrc = new Rectangle(xLast, 1, x - xLast, bm.Height);
                    gT.DrawImage(bm, rcDst, rcSrc, GraphicsUnit.Pixel);
                    yDst += Math.Max(bm.Height, frm.Font.Height);
                    if (yDst > frm.ClientRectangle.Height)
                    {
                        xDst += 50;
                        yDst  = 0;
                    }

                    gT.Flush();
                    Application.DoEvents();
#endif
                    ich++;
                    xLast = x;
                }
            }
#if SHOWFONT
            gT.Dispose();
            frm.Dispose();
#endif

            if (ich != cch)
            {
                MessageBox.Show(String.Format("Expecting {0} characters but found {2}{1}.",
                                              cch, ich, ich < cch ? "only " : ""), "bcr2 - Font Compilation Error");
                Debug.Assert(ich == cch - 1);
            }
            int cy = bm.Height - 1;

            // Save serialization
            ArrayList alsSdEven  = new ArrayList();
            int       xT         = 0;
            int       ichDefault = -1;
            for (ich = 0; ich < cch; ich++)
            {
                // ? is the default "no glyph" character
                if (strAscii[ich] == '?')
                {
                    ichDefault = ich;
                }

                // Get subimage
                int       cx  = acxChar[strAscii[ich]];
                Rectangle rcT = new Rectangle(xT, 1, cx, cy);
                xT += cx;
                Bitmap   bmT = new Bitmap(cx, cy, PixelFormat.Format24bppRgb);
                Graphics g   = Graphics.FromImage(bmT);
                g.DrawImage(bm, 0, 0, rcT, GraphicsUnit.Pixel);
                g.Dispose();

                // Compile scan data
                TBitmap tbm = new TBitmap(bmT, pal);
                bmT.Dispose();

                // Save scan data serialization
                alsSdEven.Add(tbm.SerializeScanData());
            }

            //FontHeader {
            //	word cy;
            //	byte acxChar[256];
            //	word mpchibsdEven[256];
            //	ScanData asd[1];
            //};

            // First serialize scan data

            ArrayList alsIbsdEven = new ArrayList();
            ArrayList alsSd       = new ArrayList();
            foreach (byte[] absd in alsSdEven)
            {
                if ((alsSd.Count & 1) != 0)
                {
                    alsSd.Add((byte)0);
                }
                alsIbsdEven.Add(alsSd.Count);
                alsSd.AddRange(absd);
            }

            // Write out to file
            BinaryWriter bwtr = new BinaryWriter(new FileStream(strFileSave, FileMode.Create, FileAccess.Write));

            // Height
            bwtr.Write(Misc.SwapUShort((ushort)cy));

            // Ascii ordered char widths in bytes. First init 0's to width of '?'

            if (ichDefault != -1)
            {
                for (ich = 0; ich < acxChar.Length; ich++)
                {
                    if (acxChar[ich] == 0)
                    {
                        acxChar[ich] = acxChar[strAscii[ichDefault]];
                    }
                }
            }
            bwtr.Write(acxChar);

            // Ascii ordered offsets to even scan data (even)
            // Fill unused entries to entry for '?'
            int[] aibsdEven = new int[256];
            for (int ibsd = 0; ibsd < aibsdEven.Length; ibsd++)
            {
                aibsdEven[ibsd] = -1;
            }
            for (int i = 0; i < cch; i++)
            {
                aibsdEven[strAscii[i]] = (int)alsIbsdEven[i];
            }
            if (ichDefault != -1)
            {
                for (int ibsd = 0; ibsd < aibsdEven.Length; ibsd++)
                {
                    if (aibsdEven[ibsd] == -1)
                    {
                        aibsdEven[ibsd] = (int)alsIbsdEven[ichDefault];
                    }
                }
            }

            // Write it out
            int cbHeader = 2 + 256 + 512;
            for (int i = 0; i < 256; i++)
            {
                bwtr.Write(Misc.SwapUShort((ushort)(cbHeader + aibsdEven[i])));
            }

            // Now save scan data
            bwtr.Write((byte[])alsSd.ToArray(typeof(byte)));

            // Done
            bwtr.Close();
        }