public FileTypeSaveTokenPair(PaintDotNet.FileType fileType) { if (fileType == null) { throw new ArgumentNullException("fileType"); } this.FileType = fileType; this.SaveToken = fileType.GetLastSaveConfigToken(); }
public int IndexOfFileType(PaintDotNet.FileType fileType) { return((int)mFileTypeCollection.GetType().GetMethod("IndexOfFileType").Invoke(mFileTypeCollection, new object[] { fileType })); }
public void Process(UpdateContext ctx, Dictionary <string, FileTypeSaveTokenPair> saveTokens, IProcessingEventListener events, int index) { PaintDotNet.FileType srcFileType = ctx.FileTypes[System.IO.Path.GetExtension(this.SourcePath)]; PaintDotNet.FileType destFileType = ctx.OutputFileType ?? ctx.FileTypes[System.IO.Path.GetExtension(this.DestinationPath)]; PaintDotNet.Document doc = null; PaintDotNet.Document newDoc = null; PaintDotNet.SaveConfigToken token = null; if (ctx.RenameFiles.Length > 0) { this.DestinationPath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(this.DestinationPath), Util.SanitizePath(ctx.RenameFiles, index)); } if (System.IO.Path.GetExtension(this.DestinationPath).Length == 0) { this.DestinationPath += destFileType.DefaultExtension; } else if (ctx.OutputFileType != null) { this.DestinationPath = System.IO.Path.ChangeExtension(this.DestinationPath, ctx.OutputFileType.DefaultExtension); } string dir = System.IO.Path.GetDirectoryName(this.DestinationPath); if (!System.IO.Directory.Exists(dir)) { System.IO.Directory.CreateDirectory(dir); events.LogInfo("Created directory \'{0}\'", dir); } FileTypeSaveTokenPair tokenPair; if (!saveTokens.TryGetValue(destFileType.Name, out tokenPair)) { token = destFileType.GetLastSaveConfigToken(); } else { token = tokenPair.SaveToken; } using (System.IO.FileStream file = System.IO.File.OpenRead(this.SourcePath)) { newDoc = doc = srcFileType.Load(file); } // Image resize int newWidth = ctx.NewWidthInPixels; int newHeight = ctx.NewHeightInPixels; if (ctx.UsePercent) { if (ctx.Percent != 100) { double percent = ctx.Percent / 100.0; newWidth = (int)(doc.Width * percent); newHeight = (int)(doc.Height * percent); } else { newWidth = doc.Width; newHeight = doc.Height; } } if (doc.Width != newWidth || doc.Height != newHeight) { newDoc = new PaintDotNet.Document(newWidth, newHeight); newDoc.ReplaceMetadataFrom(doc); newDoc.DpuUnit = ctx.DpuUnit; newDoc.DpuX = ctx.Dpu; newDoc.DpuY = ctx.Dpu; for (int i = 0; i < doc.Layers.Count; ++i) { PaintDotNet.BitmapLayer oldLayer = (PaintDotNet.BitmapLayer)doc.Layers[i]; PaintDotNet.Rendering.IRenderer <PaintDotNet.ColorBgra> renderer = null; switch (ctx.ResamplingAlgorithm) { case PaintDotNet.ResamplingAlgorithm.Bicubic: { renderer = Util.CreateResizeBicubic(oldLayer.Surface, newWidth, newHeight); break; } case PaintDotNet.ResamplingAlgorithm.Bilinear: { renderer = Util.CreateResizeBilinear(oldLayer.Surface, newWidth, newHeight); break; } case PaintDotNet.ResamplingAlgorithm.NearestNeighbor: { renderer = Util.CreateResizeNearestNeighbor(oldLayer.Surface, newWidth, newHeight); break; } case PaintDotNet.ResamplingAlgorithm.SuperSampling: { if (newWidth >= oldLayer.Width || newHeight >= oldLayer.Height) { renderer = Util.CreateResizeBicubic(oldLayer.Surface, newWidth, newHeight); } else { renderer = Util.CreateResizeSuperSampling(oldLayer.Surface, newWidth, newHeight); } break; } } PaintDotNet.Rendering.ObservableRenderer <PaintDotNet.ColorBgra> observableRenderer = new PaintDotNet.Rendering.ObservableRenderer <PaintDotNet.ColorBgra>(renderer); PaintDotNet.Rendering.IRenderer <PaintDotNet.ColorBgra> parallelRenderer = Environment.ProcessorCount > 1 ? Util.CreateParallelRenderer(observableRenderer, PaintDotNet.Rendering.TilingStrategy.Tiles, 7, PaintDotNet.Threading.WorkItemQueuePriority.High) : Util.CreateTileizeRenderer(renderer, new PaintDotNet.Rendering.SizeInt32(1 << 7, 1 << 7)); PaintDotNet.Surface newSurface = new PaintDotNet.Surface(newWidth, newHeight); parallelRenderer.Render(newSurface, new PaintDotNet.Rendering.Point2Int32(0, 0)); PaintDotNet.BitmapLayer newLayer = new PaintDotNet.BitmapLayer(newSurface, true); newLayer.LoadProperties(oldLayer.SaveProperties()); newDoc.Layers.Add(newLayer); } } // Canvas resize UpdateContext.CanvasResizeContext canvasResize = ctx.CanvasResize; if (!((canvasResize.UsePercent == true) && (canvasResize.Percent == 100))) { System.Drawing.Size newSize = canvasResize.GetNewSize(newDoc.Width, newDoc.Height); newDoc = Util.CanvasResize(newDoc, newSize, canvasResize.Anchor, PaintDotNet.ColorBgra.White); } using (System.IO.FileStream file = System.IO.File.Create(this.DestinationPath)) { using (PaintDotNet.Surface scratchSurface = new PaintDotNet.Surface(newDoc.Width, newDoc.Height)) { PaintDotNet.ProgressEventHandler progressEventHandler = delegate(object sender, PaintDotNet.ProgressEventArgs e) { // Nothing to do }; destFileType.Save(newDoc, file, token, scratchSurface, progressEventHandler, false); } } doc.Dispose(); if (!newDoc.IsDisposed) { newDoc.Dispose(); } }
/// <summary> /// This code is required to be in a function other than Main(). Otherwise the local variable declarations force /// PDNBulkUpdater.dll to be loaded and we cannot do the delay load check. /// </summary> /// <param name="args">Command line arguments.</param> /// <returns>0 if application execution succeeded.</returns> public static int Run(string[] args) { UpdateContext ctx = new UpdateContext(); ProcessingEventListener events = new ProcessingEventListener(); bool hasCmdLineErrors = false; double?printWidth = null; double?printHeight = null; Dictionary <string, FileTypeSaveTokenPair> saveTokens = new Dictionary <string, FileTypeSaveTokenPair>(); Dictionary <string, Dictionary <string, PaintDotNet.PropertySystem.Property> > fileTypeProperties = new Dictionary <string, Dictionary <string, PaintDotNet.PropertySystem.Property> >(); try { // this is required to support file type plugins from a source other than paint.net foreach (PaintDotNet.FileType fileType in ctx.FileTypes) { FileTypeSaveTokenPair pair = new FileTypeSaveTokenPair(fileType); saveTokens[fileType.Name] = pair; PaintDotNet.PropertyBasedFileType propType = fileType as PaintDotNet.PropertyBasedFileType; if (propType != null) { PaintDotNet.PropertyBasedSaveConfigToken propTok = (PaintDotNet.PropertyBasedSaveConfigToken)pair.SaveToken; Dictionary <string, PaintDotNet.PropertySystem.Property> props = new Dictionary <string, PaintDotNet.PropertySystem.Property>(); foreach (PaintDotNet.PropertySystem.Property curProp in propTok.Properties) { props[curProp.Name.ToLowerInvariant()] = curProp; } foreach (string ext in fileType.Extensions) { fileTypeProperties[ext] = props; } } } for (int i = 0; i < args.Length; ++i) { string arg = args[i]; string[] parts = arg.Split(':'); // yup this switch statement is pretty hideous // I should prob turn the case statements into functions - or something // the primary issue is type initialization causing the CLR to attempt to // load PDNBulkUpdater.dll before it gets to my delay loader which will cause a crash // it's on the todo list switch (parts[0].ToLowerInvariant()) { case "/o": { if (parts.Length < 2) { hasCmdLineErrors = true; } else { // NOTE: + 1 skips the : after /o ctx.OutputDirectory = arg.Substring(parts[0].Length + 1); } break; } case "/dpu": { if (parts.Length != 2) { hasCmdLineErrors = true; } else { double dpu; if (!double.TryParse(parts[1], out dpu) || dpu < 0.0) { hasCmdLineErrors = true; } else { ctx.Dpu = dpu; UpdateResolutionFromDpu(ctx, printWidth, printHeight); } } break; } case "/u": { if (parts.Length != 2) { hasCmdLineErrors = true; } else { switch (parts[1].ToLowerInvariant()) { case "in": { if (ctx.DpuUnit != PaintDotNet.MeasurementUnit.Inch) { ctx.Dpu = PaintDotNet.Document.InchesToCentimeters(ctx.Dpu); ctx.DpuUnit = PaintDotNet.MeasurementUnit.Inch; UpdateResolutionFromDpu(ctx, printWidth, printHeight); } break; } case "cm": { if (ctx.DpuUnit != PaintDotNet.MeasurementUnit.Centimeter) { ctx.Dpu = PaintDotNet.Document.CentimetersToInches(ctx.Dpu); ctx.DpuUnit = PaintDotNet.MeasurementUnit.Centimeter; UpdateResolutionFromDpu(ctx, printWidth, printHeight); } break; } default: { hasCmdLineErrors = true; break; } } } break; } case "/res": { if (parts.Length != 2) { hasCmdLineErrors = true; } else { string[] res = parts[1].Split('x'); int pixelWidth = 0; int pixelHeight = 0; if (res.Length != 2) { hasCmdLineErrors = true; } else if (!int.TryParse(res[0], out pixelWidth) || !int.TryParse(res[1], out pixelHeight) || pixelWidth < 0 || pixelHeight < 0) { hasCmdLineErrors = true; } else { ctx.UsePercent = false; ctx.NewWidthInPixels = pixelWidth; ctx.NewHeightInPixels = pixelHeight; } } break; } case "/print": { if (parts.Length != 2) { hasCmdLineErrors = true; } else { string[] res = parts[1].Split('x'); double tempPrintWidth = 0.0; double tempPrintHeight = 0.0; if (res.Length != 2) { hasCmdLineErrors = true; } else if (!double.TryParse(res[0], out tempPrintWidth) || !double.TryParse(res[1], out tempPrintHeight) || printWidth < 0.0 || printHeight < 0.0) { hasCmdLineErrors = true; } else { ctx.UsePercent = false; ctx.NewWidthInPixels = Util.PrintToPixel(ctx.Dpu, tempPrintWidth); ctx.NewHeightInPixels = Util.PrintToPixel(ctx.Dpu, tempPrintHeight); printWidth = tempPrintWidth; printHeight = tempPrintHeight; } } break; } case "/pcnt": { if (parts.Length != 2) { hasCmdLineErrors = true; } else { int percent; if (!int.TryParse(parts[1], out percent) || percent < 0) { hasCmdLineErrors = true; } else { ctx.Percent = percent; ctx.UsePercent = true; } } break; } case "/alg": { if (parts.Length != 2) { hasCmdLineErrors = true; } else { switch (parts[1].ToLowerInvariant()) { case "bicubic": { ctx.ResamplingAlgorithm = PaintDotNet.ResamplingAlgorithm.Bicubic; break; } case "nearest": { ctx.ResamplingAlgorithm = PaintDotNet.ResamplingAlgorithm.NearestNeighbor; break; } case "bilinear": { ctx.ResamplingAlgorithm = PaintDotNet.ResamplingAlgorithm.Bilinear; break; } case "super": { ctx.ResamplingAlgorithm = PaintDotNet.ResamplingAlgorithm.SuperSampling; break; } default: { hasCmdLineErrors = true; break; } } } break; } case "/ft": { if (parts.Length != 4) { hasCmdLineErrors = true; } else { string ext = parts[1].ToLowerInvariant(); string propName = parts[2].ToLowerInvariant(); string propValue = parts[3]; Dictionary <string, PaintDotNet.PropertySystem.Property> props = null; PaintDotNet.PropertySystem.Property property = null; int intVal = 0; double dblVal = 0.0; bool boolVal = false; bool succeeded = false; if (!ext.StartsWith(".")) { ext = "." + ext; } if (fileTypeProperties.TryGetValue(ext, out props) && props.TryGetValue(propName, out property)) { PaintDotNet.PropertySystem.Int32Property intProp = property as PaintDotNet.PropertySystem.Int32Property; PaintDotNet.PropertySystem.DoubleProperty dblProp = property as PaintDotNet.PropertySystem.DoubleProperty; PaintDotNet.PropertySystem.BooleanProperty boolProp = property as PaintDotNet.PropertySystem.BooleanProperty; PaintDotNet.PropertySystem.StaticListChoiceProperty listProp = property as PaintDotNet.PropertySystem.StaticListChoiceProperty; if (intProp != null) { succeeded = int.TryParse(propValue, out intVal); if (succeeded) { intProp.Value = intVal; } } else if (dblProp != null) { succeeded = double.TryParse(propValue, out dblVal); if (succeeded) { dblProp.Value = dblVal; } } else if (boolProp != null) { succeeded = bool.TryParse(propValue, out boolVal); if (succeeded) { boolProp.Value = boolVal; } } else if (listProp != null) { if (listProp.ValueChoices.Length == 0) { succeeded = true; } else { Type valType = listProp.ValueChoices[0].GetType(); if (valType.IsEnum && valType.IsValueType) { try { listProp.Value = Enum.Parse(valType.DeclaringType, propValue, true); succeeded = true; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); events.LogError("\'{0}\' is an invalid value for property \'{1}\' in file type \'{2}\'", propValue, propName, ext); } } else { foreach (object obj in listProp.ValueChoices) { if (obj.Equals(propValue)) { listProp.Value = obj; succeeded = true; break; } } } } } else { events.LogWarning("Unknown property type \'{0}\' discarded!", property.GetType().Name); succeeded = true; } } if (!succeeded) { hasCmdLineErrors = true; } } break; } case "/v0": { events.Verbosity = Verbosity.None; break; } case "/v1": { events.Verbosity = Verbosity.Exceptions; break; } case "/v2": { events.Verbosity = Verbosity.Exceptions | Verbosity.Errors; break; } case "/v3": { events.Verbosity = Verbosity.Exceptions | Verbosity.Errors | Verbosity.Warnings; break; } case "/v4": { events.Verbosity = Verbosity.Everything; break; } case "/oft": { if (parts.Length != 2) { hasCmdLineErrors = true; } else { PaintDotNet.FileType ft = ctx.FileTypes[parts[1].ToLowerInvariant()]; if (ft == null) { events.LogError("File type \'{0}\' is not supported!", parts[1]); hasCmdLineErrors = true; } else { ctx.OutputFileType = ft; } } break; } case "/ren": { if (parts.Length != 2) { hasCmdLineErrors = true; } else { ctx.RenameFiles = parts[1]; } break; } case "/ftprops": { const int PROP_OFFSET = 35; Console.WriteLine("File Type Properties:"); System.Diagnostics.Debug.WriteLine("File Type Properties:"); foreach (PaintDotNet.FileType fileType in ctx.FileTypes) { PaintDotNet.PropertyBasedSaveConfigToken token = fileType.CreateDefaultSaveConfigToken() as PaintDotNet.PropertyBasedSaveConfigToken; if (token == null) { PrintCmdUsage(fileType.DefaultExtension, "0 properties", PROP_OFFSET); } else { PrintCmdUsage(fileType.DefaultExtension, token.Properties.Count.ToString() + " properties", PROP_OFFSET); foreach (PaintDotNet.PropertySystem.Property prop in token.Properties) { PrintCmdUsage(" " + prop.Name, prop.GetType().Name, PROP_OFFSET); } } System.Diagnostics.Debug.WriteLine(""); Console.WriteLine(""); } break; } default: { try { string fileName = System.IO.Path.GetFileName(arg); if (fileName.Length == 0 || !fileName.Contains('.')) { string dirName = System.IO.Path.GetFullPath(arg); if (!System.IO.Directory.Exists(dirName)) { events.LogError("Directory \'{0}' does not exist!", dirName); hasCmdLineErrors = true; } else { ctx.Files.Add(new FileSystemDirectory(dirName, ctx.FileTypes)); } } else if (fileName.Contains('*')) { string ext = System.IO.Path.GetExtension(fileName); if (ext == ".*") { string dirName = System.IO.Path.GetDirectoryName(arg); if (!System.IO.Directory.Exists(dirName)) { events.LogError("Directory \'{0}' does not exist!", dirName); hasCmdLineErrors = true; } else { ctx.Files.Add(new FileSystemDirectory(dirName, ctx.FileTypes)); } } else { PaintDotNet.FileType fileType = ctx.FileTypes[ext]; if (fileType == null) { hasCmdLineErrors = true; events.LogError("Extension \'{0}\' is not supported!", ext); } else { string dirName = System.IO.Path.GetDirectoryName(arg); if (!System.IO.Directory.Exists(dirName)) { events.LogError("Directory \'{0}' does not exist!", dirName); hasCmdLineErrors = true; } else { ctx.Files.Add(new FileSystemDirectory(dirName, new FileTypeCollection(new PaintDotNet.FileType[] { fileType }))); } } } } else { if (!System.IO.File.Exists(arg)) { events.LogError("File \'{0}' does not exist!", arg); hasCmdLineErrors = true; } else { ctx.Files.Add(new FileSystemFile(System.IO.Path.GetFullPath(arg), ctx.FileTypes)); } } } catch (Exception ex) { events.LogError("Invalid input directory, filter, or file: " + arg); events.LogException(ex); } break; } } } if (ctx.Files.Count == 0 || hasCmdLineErrors) { PrintUsage(); } else { if ((events.Verbosity & Verbosity.Info) == Verbosity.Info) { events.LogInfo("Output Settings"); if (ctx.UsePercent) { PrintCmdUsage("Percent:", ctx.Percent.ToString()); } else { PrintCmdUsage("Pixel Resolution:", string.Format("{0}x{1}", ctx.NewWidthInPixels.ToString(), ctx.NewHeightInPixels.ToString())); PrintCmdUsage("Print Resolution:", string.Format("{0}x{1}", Util.PixelToPrint(ctx.Dpu, ctx.NewWidthInPixels).ToString("0.##"), Util.PixelToPrint(ctx.Dpu, ctx.NewHeightInPixels).ToString("0.##"))); } PrintCmdUsage("Dpu:", ctx.Dpu.ToString("0.##")); PrintCmdUsage("Dpu Unit:", ctx.DpuUnit.ToString()); PrintCmdUsage("Algorithm:", ctx.ResamplingAlgorithm.ToString()); PrintCmdUsage("Rename To:", ctx.RenameFiles); PrintCmdUsage("Output File Type:", ctx.OutputFileType == null ? "" : ctx.OutputFileType.Name); PrintCmdUsage("Output Directory:", ctx.OutputDirectory); Console.WriteLine(""); } Util.ProcessImages(ctx, saveTokens, events); } } catch (Exception ex) { events.LogException(ex); hasCmdLineErrors = true; } return(hasCmdLineErrors ? 1 : 0); }