Holds all information related to a single map-rendering task.
Beispiel #1
0
 static void SaveImage(int percentage, RenderTask task)
 {
     if (task.Exception != null)
     {
         Console.WriteLine("{0}: Error rendering image:", task.RelativeName);
         Console.Error.WriteLine("{0}: {1}", task.Exception.GetType().Name, task.Exception);
     }
     else
     {
         if (!p.AlwaysOverwrite && File.Exists(task.TargetPath))
         {
             Console.WriteLine();
             if (!ShowYesNo("File \"{0}\" already exists. Overwrite?", Path.GetFileName(task.TargetPath)))
             {
                 Console.WriteLine("[{0}%] {1}: Skipped (image file already exists)",
                                   percentage.ToString(CultureInfo.InvariantCulture).PadLeft(3),
                                   task.RelativeName);
                 return;
             }
         }
         using (FileStream fs = File.OpenWrite(task.TargetPath)) {
             fs.Write(task.Result, 0, task.Result.Length);
         }
         Console.WriteLine("[{0}%] {1}: ok",
                           percentage.ToString(CultureInfo.InvariantCulture).PadLeft(3),
                           task.RelativeName);
     }
 }
Beispiel #2
0
        void RenderLoop()
        {
            renderer = MakeRenderer();
            using (MemoryStream ms = new MemoryStream()) {
                // loop terminates with the rest of the program (this is a background thread)
                while (true)
                {
                    // wait (block) until a map is available for drawing
                    RenderTask task = inQueue.WaitDequeue();
                    try {
                        // render the map
                        IsoCatResult result = renderer.Draw(task.Map);
                        task.Map = null;

                        // crop image (if needed)
                        Image image;
                        if (p.Uncropped)
                        {
                            image = result.Bitmap;
                        }
                        else
                        {
                            image = result.Bitmap.Clone(result.CropRectangle, result.Bitmap.PixelFormat);
                            result.Bitmap.Dispose();
                        }

                        // encode image
                        if (p.ExportFormat.Equals(ImageFormat.Jpeg))
                        {
                            EncoderParameters encoderParams = new EncoderParameters();
                            encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, p.JpegQuality);
                            image.Save(ms, p.ImageEncoder, encoderParams);
                        }
                        else if (p.ExportFormat.Equals(ImageFormat.Gif))
                        {
                            OctreeQuantizer q = new OctreeQuantizer(255, 8);
                            image = q.Quantize(image);
                            image.Save(ms, p.ExportFormat);
                        }
                        else
                        {
                            image.Save(ms, p.ExportFormat);
                        }
                        image.Dispose();

                        // store result as a byte[]
                        task.Result = ms.ToArray();
                    } catch (Exception ex) {
                        task.Exception = ex;
                    }

                    // send stack to the results queue
                    outQueue.Enqueue(task);
                    ms.SetLength(0);
                }
            }
        }
Beispiel #3
0
 static bool LoadMap(RenderTask task)
 {
     try {
         Map map;
         if (p.MapImporter != null)
         {
             map = p.MapImporter.Load(task.MapPath);
         }
         else
         {
             map = MapUtility.Load(task.MapPath, p.TryHard);
         }
         task.Map = map;
         return(true);
     } catch (NoMapConverterFoundException) {
         Console.WriteLine("{0}: Skipped (no compatible converter found).", task.RelativeName);
         return(false);
     } catch (Exception ex) {
         Console.WriteLine("{0}: Error loading map file:", task.RelativeName);
         Console.Error.WriteLine(ex);
         return(false);
     }
 }
Beispiel #4
0
 static void SaveImage(int percentage, RenderTask task) {
     if (task.Exception != null) {
         Console.WriteLine("{0}: Error rendering image:", task.RelativeName);
         Console.Error.WriteLine("{0}: {1}", task.Exception.GetType().Name, task.Exception);
     } else {
         if (p.OverwritePolicy == OverwritePolicy.Ask && File.Exists(task.TargetPath)) {
             Console.WriteLine();
             if (!ConsoleUtil.ShowYesNo("File \"{0}\" already exists. Overwrite?",
                                        Path.GetFileName(task.TargetPath))) {
                 Console.WriteLine("[{0}%] {1}: Skipped (image file already exists)",
                                   percentage.ToString(CultureInfo.InvariantCulture).PadLeft(3),
                                   task.RelativeName);
                 return;
             }
         }
         using (FileStream fs = File.OpenWrite(task.TargetPath)) {
             fs.Write(task.Result, 0, task.Result.Length);
         }
         Console.WriteLine("[{0}%] {1}: ok",
                           percentage.ToString(CultureInfo.InvariantCulture).PadLeft(3),
                           task.RelativeName);
     }
 }
Beispiel #5
0
 static bool LoadMap(RenderTask task) {
     try {
         Map map;
         if (p.MapImporter != null) {
             map = p.MapImporter.Load(task.MapPath);
         } else {
             map = MapUtility.Load(task.MapPath, p.TryHard);
         }
         task.Map = map;
         return true;
     } catch (NoMapConverterFoundException) {
         Console.WriteLine("{0}: Skipped (no compatible converter found).", task.RelativeName);
         return false;
     } catch (Exception ex) {
         Console.WriteLine("{0}: Error loading map file:", task.RelativeName);
         Console.Error.WriteLine(ex);
         return false;
     }
 }
Beispiel #6
0
        static int Main(string[] args)
        {
            Logger.Logged += OnLogged;
            Logger.DisableFileLogging();

            ReturnCode optionParsingResult = ParseOptions(args);

            if (optionParsingResult != ReturnCode.Success)
            {
                return((int)optionParsingResult);
            }

            // parse importer name
            if (importerName != null && !importerName.Equals("auto", StringComparison.OrdinalIgnoreCase))
            {
                MapFormat importFormat;
                if (!EnumUtil.TryParse(importerName, out importFormat, true))
                {
                    Console.Error.WriteLine("Unsupported importer \"{0}\"", importerName);
                    PrintUsage();
                    return((int)ReturnCode.UnrecognizedImporter);
                }
                p.MapImporter = MapUtility.GetImporter(importFormat);
                if (p.MapImporter == null)
                {
                    Console.Error.WriteLine("Loading from \"{0}\" is not supported", importFormat);
                    PrintUsage();
                    return((int)ReturnCode.UnsupportedLoadFormat);
                }
            }

            // check input paths
            bool hadFile = false,
                 hadDir  = false;

            foreach (string inputPath in p.InputPathList)
            {
                if (hadDir)
                {
                    Console.Error.WriteLine("MapRenderer: Only one directory may be specified at a time.");
                    return((int)ReturnCode.ArgumentError);
                }
                // check if input path exists, and if it's a file or directory
                try {
                    if (File.Exists(inputPath))
                    {
                        hadFile = true;
                    }
                    else if (Directory.Exists(inputPath))
                    {
                        hadDir = true;
                        if (hadFile)
                        {
                            Console.Error.WriteLine("MapRenderer: Cannot mix directories and files in input.");
                            return((int)ReturnCode.ArgumentError);
                        }
                        p.DirectoryMode = true;
                        if (!p.OutputDirGiven)
                        {
                            p.OutputDirName = inputPath;
                        }
                    }
                    else
                    {
                        Console.Error.WriteLine("MapRenderer: Cannot locate \"{0}\"", inputPath);
                        return((int)ReturnCode.InputPathNotFound);
                    }
                } catch (Exception ex) {
                    Console.Error.WriteLine("MapRenderer: {0}: {1}",
                                            ex.GetType().Name,
                                            ex.Message);
                    return((int)ReturnCode.PathError);
                }
            }

            // initialize image encoder
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
            p.ImageEncoder = codecs.FirstOrDefault(codec => codec.FormatID == p.ExportFormat.Guid);
            if (p.ImageEncoder == null)
            {
                Console.Error.WriteLine("MapRenderer: Specified image encoder is not supported.");
                return((int)ReturnCode.UnsupportedSaveFormat);
            }

            // check recursive flag
            if (p.Recursive && !p.DirectoryMode)
            {
                Console.Error.WriteLine("MapRenderer: Recursive flag is given, but input is not a directory.");
                return((int)ReturnCode.ArgumentError);
            }

            // check input filter
            if (p.InputFilter != null && !p.DirectoryMode)
            {
                Console.Error.WriteLine("MapRenderer: Filter param is given, but input is not a directory.");
                return((int)ReturnCode.ArgumentError);
            }

            // check regex filter
            if (p.UseRegex)
            {
                try {
                    p.FilterRegex = new Regex(p.InputFilter);
                } catch (ArgumentException ex) {
                    Console.Error.WriteLine("MapRenderer: Cannot parse filter regex: {0}",
                                            ex.Message);
                    return((int)ReturnCode.ArgumentError);
                }
            }

            // check if output dir exists; create it if needed
            if (p.OutputDirName != null)
            {
                try {
                    if (!Directory.Exists(p.OutputDirName))
                    {
                        Directory.CreateDirectory(p.OutputDirName);
                    }
                } catch (Exception ex) {
                    Console.Error.WriteLine("MapRenderer: Error checking output directory: {0}: {1}",
                                            ex.GetType().Name, ex.Message);
                }
            }

            Console.Write("Counting files... ");

            // process inputs, one path at a time
            foreach (string inputPath in p.InputPathList)
            {
                ProcessInputPath(inputPath);
            }
            int totalFiles = InputPaths.Count;

            Console.WriteLine(totalFiles);

            if (totalFiles > 0)
            {
                int            actualThreadCount = Math.Min(p.ThreadCount, InputPaths.Count);
                RenderWorker[] workers           = new RenderWorker[actualThreadCount];
                for (int i = 0; i < workers.Length; i++)
                {
                    workers[i] = new RenderWorker(WorkQueue, ResultQueue, p);
                    workers[i].Start();
                }

                int inputsProcessed  = 0;
                int resultsProcessed = 0;
                while (resultsProcessed < totalFiles)
                {
                    if (inputsProcessed < totalFiles)
                    {
                        // load and enqueue another map for rendering
                        if (WorkQueue.Count < actualThreadCount)
                        {
                            RenderTask newTask = InputPaths.Dequeue();
                            if (LoadMap(newTask))
                            {
                                WorkQueue.Enqueue(newTask);
                            }
                            else
                            {
                                resultsProcessed++;
                            }
                            inputsProcessed++;
                        }
                        else
                        {
                            Thread.Sleep(1);
                        }

                        // try dequeue a rendered image for saving
                        RenderTask resultTask;
                        if (ResultQueue.TryDequeue(out resultTask))
                        {
                            int percent = (resultsProcessed * 100 + 100) / totalFiles;
                            SaveImage(percent, resultTask);
                            resultsProcessed++;
                        }
                    }
                    else
                    {
                        // no more maps to load -- just wait for results
                        int percent = (resultsProcessed * 100 + 100) / totalFiles;
                        SaveImage(percent, ResultQueue.WaitDequeue());
                        resultsProcessed++;
                    }
                }
            }

            Console.WriteLine("MapRenderer: Processed {0} files in {1:0.00} seconds",
                              totalFiles,
                              DateTime.UtcNow.Subtract(StartTime).TotalSeconds);
            return((int)ReturnCode.Success);
        }