<commit_before>using System;
using System.Text;
using System.Runtime.InteropServices;

namespace GhostscriptSharp
{
	/// <summary>
	/// Wraps the Ghostscript API with a C# interface
	/// </summary>
	public class GhostscriptWrapper
	{
		#region Hooks into Ghostscript DLL
		[DllImport("gsdll32.dll", EntryPoint = "gsapi_new_instance")]
		private static extern int CreateAPIInstance(out IntPtr pinstance, IntPtr caller_handle);

		[DllImport("gsdll32.dll", EntryPoint = "gsapi_init_with_args")]
		private static extern int InitAPI(IntPtr instance, int argc, string[] argv);

		[DllImport("gsdll32.dll", EntryPoint = "gsapi_exit")]
		private static extern int ExitAPI(IntPtr instance);

		[DllImport("gsdll32.dll", EntryPoint = "gsapi_delete_instance")]
		private static extern void DeleteAPIInstance(IntPtr instance);
		#endregion

		#region Globals

		private static readonly string[] ARGS = new string[] {
				// Keep gs from writing information to standard output
                "-q",                     
                "-dQUIET",
               
                "-dPARANOIDSAFER",       // Run this command in safe mode
                "-dBATCH",               // Keep gs from going into interactive mode
                "-dNOPAUSE",             // Do not prompt and pause for each page
                "-dNOPROMPT",            // Disable prompts for user interaction           
                "-dMaxBitmap=500000000", // Set high for better performance
				"-dNumRenderingThreads=4", // Multi-core, come-on!
                
                // Configure the output anti-aliasing, resolution, etc
                "-dAlignToPixels=0",
                "-dGridFitTT=0",
                "-dTextAlphaBits=4",
                "-dGraphicsAlphaBits=4"
		};
		#endregion

		/// <summary>
		/// Generates a thumbnail jpg for the pdf at the input path and saves it 
		/// at the output path
		/// </summary>
		public static void GeneratePageThumb(string inputPath, string outputPath, int page, int width, int height)
		{
			GeneratePageThumbs(inputPath, outputPath, page, page, width, height);
		}

		/// <summary>
		/// Generates a collection of thumbnail jpgs for the pdf at the input path 
		/// starting with firstPage and ending with lastPage.
		/// Put "%d" somewhere in the output path to have each of the pages numbered
		/// </summary>
		public static void GeneratePageThumbs(string inputPath, string outputPath, int firstPage, int lastPage, int width, int height)
		{
			CallAPI(GetArgs(inputPath, outputPath, firstPage, lastPage, width, height));
		}

		/// <summary>
		/// Rasterises a PDF into selected format
		/// </summary>
		/// <param name="inputPath">PDF file to convert</param>
		/// <param name="outputPath">Destination file</param>
		/// <param name="settings">Conversion settings</param>
		public static void GenerateOutput(string inputPath, string outputPath, GhostscriptSettings settings)
		{
			CallAPI(GetArgs(inputPath, outputPath, settings));
		}

		/// <summary>
		/// Calls the Ghostscript API with a collection of arguments to be passed to it
		/// </summary>
		private static void CallAPI(string[] args)
		{
			// Get a pointer to an instance of the Ghostscript API and run the API with the current arguments
			IntPtr gsInstancePtr;
			lock (resourceLock)
			{
				CreateAPIInstance(out gsInstancePtr, IntPtr.Zero);
				try
				{

					

					int result = InitAPI(gsInstancePtr, args.Length, args);

					if (result < 0)
					{
						throw new ExternalException("Ghostscript conversion error", result);
					}

				}
				finally
				{
					Cleanup(gsInstancePtr);
				}
			}
		}

		/// <summary>
		/// GS can only support a single instance, so we need to bottleneck any multi-threaded systems.
		/// </summary>
		private static object resourceLock = new object();

		/// <summary>
		/// Frees up the memory used for the API arguments and clears the Ghostscript API instance
		/// </summary>
		private static void Cleanup(IntPtr gsInstancePtr)
		{
			ExitAPI(gsInstancePtr);
			DeleteAPIInstance(gsInstancePtr);
		}

		/// <summary>
		/// Returns an array of arguments to be sent to the Ghostscript API
		/// </summary>
		/// <param name="inputPath">Path to the source file</param>
		/// <param name="outputPath">Path to the output file</param>
		/// <param name="firstPage">The page of the file to start on</param>
		/// <param name="lastPage">The page of the file to end on</param>
		private static string[] GetArgs(string inputPath,
			string outputPath,
			int firstPage,
			int lastPage,
			int width,
			int height)
		{
			// To maintain backwards compatibility, this method uses previous hardcoded values.

			GhostscriptSettings s = new GhostscriptSettings();
			s.Device = Settings.GhostscriptDevices.jpeg;
			s.Page.Start = firstPage;
			s.Page.End = lastPage;
			s.Resolution = new System.Drawing.Size(width, height);

			return GetArgs(inputPath, outputPath, s);
		}

		/// <summary>
		/// Returns an array of arguments to be sent to the Ghostscript API
		/// </summary>
		/// <param name="inputPath">Path to the source file</param>
		/// <param name="outputPath">Path to the output file</param>
		/// <param name="settings">API parameters</param>
		/// <returns>API arguments</returns>
		private static string[] GetArgs(string inputPath,
			string outputPath,
			GhostscriptSettings settings)
		{
			System.Collections.ArrayList args = new System.Collections.ArrayList(ARGS);

			if (settings.Device == Settings.GhostscriptDevices.UNDEFINED)
			{
				throw new ArgumentException("An output device must be defined for Ghostscript", "GhostscriptSettings.Device");
			}

			if (settings.Page.AllPages == false && (settings.Page.Start <= 0 && settings.Page.End < settings.Page.Start))
			{
				throw new ArgumentException("Pages to be printed must be defined.", "GhostscriptSettings.Pages");
			}

			if (settings.Resolution.IsEmpty)
			{<commit_msg>Pulled in Dash's changes and updated the code a little because the old method for generating a file was breaking when I tested it<commit_after>using System;
using System.Text;
using System.Runtime.InteropServices;

namespace GhostscriptSharp
{
	/// <summary>
	/// Wraps the Ghostscript API with a C# interface
	/// </summary>
	public class GhostscriptWrapper
	{
		#region Hooks into Ghostscript DLL
		[DllImport("gsdll32.dll", EntryPoint = "gsapi_new_instance")]
		private static extern int CreateAPIInstance(out IntPtr pinstance, IntPtr caller_handle);

		[DllImport("gsdll32.dll", EntryPoint = "gsapi_init_with_args")]
		private static extern int InitAPI(IntPtr instance, int argc, string[] argv);

		[DllImport("gsdll32.dll", EntryPoint = "gsapi_exit")]
		private static extern int ExitAPI(IntPtr instance);

		[DllImport("gsdll32.dll", EntryPoint = "gsapi_delete_instance")]
		private static extern void DeleteAPIInstance(IntPtr instance);
		#endregion

		#region Globals

		private static readonly string[] ARGS = new string[] {
				// Keep gs from writing information to standard output
                "-q",                     
                "-dQUIET",
               
                "-dPARANOIDSAFER",       // Run this command in safe mode
                "-dBATCH",               // Keep gs from going into interactive mode
                "-dNOPAUSE",             // Do not prompt and pause for each page
                "-dNOPROMPT",            // Disable prompts for user interaction           
                "-dMaxBitmap=500000000", // Set high for better performance
				"-dNumRenderingThreads=4", // Multi-core, come-on!
                
                // Configure the output anti-aliasing, resolution, etc
                "-dAlignToPixels=0",
                "-dGridFitTT=0",
                "-dTextAlphaBits=4",
                "-dGraphicsAlphaBits=4"
		};
		#endregion

		/// <summary>
		/// Generates a thumbnail jpg for the pdf at the input path and saves it 
		/// at the output path
		/// </summary>
		public static void GeneratePageThumb(string inputPath, string outputPath, int page, int width, int height)
		{
			GeneratePageThumbs(inputPath, outputPath, page, page, width, height);
		}

		/// <summary>
		/// Generates a collection of thumbnail jpgs for the pdf at the input path 
		/// starting with firstPage and ending with lastPage.
		/// Put "%d" somewhere in the output path to have each of the pages numbered
		/// </summary>
		public static void GeneratePageThumbs(string inputPath, string outputPath, int firstPage, int lastPage, int width, int height)
		{
			CallAPI(GetArgs(inputPath, outputPath, firstPage, lastPage, width, height));
		}

		/// <summary>
		/// Rasterises a PDF into selected format
		/// </summary>
		/// <param name="inputPath">PDF file to convert</param>
		/// <param name="outputPath">Destination file</param>
		/// <param name="settings">Conversion settings</param>
		public static void GenerateOutput(string inputPath, string outputPath, GhostscriptSettings settings)
		{
			CallAPI(GetArgs(inputPath, outputPath, settings));
		}

		/// <summary>
		/// Calls the Ghostscript API with a collection of arguments to be passed to it
		/// </summary>
		private static void CallAPI(string[] args)
		{
			// Get a pointer to an instance of the Ghostscript API and run the API with the current arguments
			IntPtr gsInstancePtr;
			lock (resourceLock)
			{
				CreateAPIInstance(out gsInstancePtr, IntPtr.Zero);
				try
				{
					int result = InitAPI(gsInstancePtr, args.Length, args);

					if (result < 0)
					{
						throw new ExternalException("Ghostscript conversion error", result);
					}
				}
				finally
				{
					Cleanup(gsInstancePtr);
				}
			}
		}

		/// <summary>
		/// GS can only support a single instance, so we need to bottleneck any multi-threaded systems.
		/// </summary>
		private static object resourceLock = new object();

		/// <summary>
		/// Frees up the memory used for the API arguments and clears the Ghostscript API instance
		/// </summary>
		private static void Cleanup(IntPtr gsInstancePtr)
		{
			ExitAPI(gsInstancePtr);
			DeleteAPIInstance(gsInstancePtr);
		}

		/// <summary>
		/// Returns an array of arguments to be sent to the Ghostscript API
		/// </summary>
		/// <param name="inputPath">Path to the source file</param>
		/// <param name="outputPath">Path to the output file</param>
		/// <param name="firstPage">The page of the file to start on</param>
		/// <param name="lastPage">The page of the file to end on</param>
		private static string[] GetArgs(string inputPath,
			string outputPath,
			int firstPage,
			int lastPage,
			int width,
			int height)
		{
			// To maintain backwards compatibility, this method uses previous hardcoded values.

			GhostscriptSettings s = new GhostscriptSettings();
			s.Device = Settings.GhostscriptDevices.jpeg;
			s.Page.Start = firstPage;
			s.Page.End = lastPage;
			s.Resolution = new System.Drawing.Size(width, height);
			
			Settings.GhostscriptPageSize pageSize = new Settings.GhostscriptPageSize();
			pageSize.Native = GhostscriptSharp.Settings.GhostscriptPageSizes.a7;
			s.Size = pageSize;

			return GetArgs(inputPath, outputPath, s);
		}

		/// <summary>
		/// Returns an array of arguments to be sent to the Ghostscript API
		/// </summary>
		/// <param name="inputPath">Path to the source file</param>
		/// <param name="outputPath">Path to the output file</param>
		/// <param name="settings">API parameters</param>
		/// <returns>API arguments</returns>
		private static string[] GetArgs(string inputPath,
			string outputPath,
			GhostscriptSettings settings)
		{
			System.Collections.ArrayList args = new System.Collections.ArrayList(ARGS);

			if (settings.Device == Settings.GhostscriptDevices.UNDEFINED)
			{
				throw new ArgumentException("An output device must be defined for Ghostscript", "GhostscriptSettings.Device");
			}

			if (settings.Page.AllPages == false && (settings.Page.Start <= 0 && settings.Page.End < settings.Page.Start))
			{
				throw new ArgumentException("Pages to be printed must be defined.", "GhostscriptSettings.Pages");
			}

			if (settings.Resolution.IsEmpty)
			{
{'fraction_non_alphanumeric': 0.10781224083595953, 'fraction_numerical': 0.004063692154586167, 'mean_word_length': 2.9152597402597404, 'pattern_counts': {'":': 0, '<': 89, '<?xml version=': 0, '>': 83, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6942455', 'n_tokens_mistral': 3889, 'n_tokens_neox': 3343, 'n_words': 1111}