Skip to content

Commit

Permalink
Merge pull request #4 from cbadke/x64Support
Browse files Browse the repository at this point in the history
X64 support
  • Loading branch information
mephraim committed Oct 15, 2013
2 parents 1cdb015 + 1dba35d commit f4fa63b
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 65 deletions.
65 changes: 65 additions & 0 deletions GhostScriptSharp/API/GhostScript32.cs
@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace GhostscriptSharp.API
{
internal class GhostScript32
{
#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

/// <summary>
/// Calls the Ghostscript API with a collection of arguments to be passed to it
/// </summary>
public 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>
/// 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>
/// GS can only support a single instance, so we need to bottleneck any multi-threaded systems.
/// </summary>
private static object resourceLock = new object();
}
}
66 changes: 66 additions & 0 deletions GhostScriptSharp/API/GhostScript64.cs
@@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace GhostscriptSharp.API
{
internal class GhostScript64
{
#region Hooks into Ghostscript DLL
[DllImport("gsdll64.dll", EntryPoint = "gsapi_new_instance")]
private static extern int CreateAPIInstance(out IntPtr pinstance, IntPtr caller_handle);

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

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

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

/// <summary>
/// Calls the Ghostscript API with a collection of arguments to be passed to it
/// </summary>
public 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>
/// 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>
/// GS can only support a single instance, so we need to bottleneck any multi-threaded systems.
/// </summary>
private static object resourceLock = new object();
}
}
93 changes: 29 additions & 64 deletions GhostScriptSharp/GhostscriptSharp.cs
@@ -1,4 +1,5 @@
using System;
using System.Drawing;
using System.Text;
using System.Runtime.InteropServices;

Expand All @@ -9,20 +10,6 @@ namespace GhostscriptSharp
/// </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[] {
Expand All @@ -45,23 +32,27 @@ public class GhostscriptWrapper
};
#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)
public static void GeneratePageThumb(string inputPath, string outputPath, int page, int dpix, int dpiy, int width = 0, int height = 0)
{
GeneratePageThumbs(inputPath, outputPath, page, page, width, height);
GeneratePageThumbs(inputPath, outputPath, page, page, dpix, dpiy, 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)
public static void GeneratePageThumbs(string inputPath, string outputPath, int firstPage, int lastPage, int dpix, int dpiy, int width = 0, int height = 0)
{
CallAPI(GetArgs(inputPath, outputPath, firstPage, lastPage, width, height));
if (IntPtr.Size == 4)
API.GhostScript32.CallAPI(GetArgs(inputPath, outputPath, firstPage, lastPage, dpix, dpiy, width, height));
else
API.GhostScript64.CallAPI(GetArgs(inputPath, outputPath, firstPage, lastPage, dpix, dpiy, width, height));
}

/// <summary>
Expand All @@ -72,47 +63,10 @@ public static void GeneratePageThumbs(string inputPath, string outputPath, int f
/// <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);
if (IntPtr.Size == 4)
API.GhostScript32.CallAPI(GetArgs(inputPath, outputPath, settings));
else
API.GhostScript64.CallAPI(GetArgs(inputPath, outputPath, settings));
}

/// <summary>
Expand All @@ -126,20 +80,29 @@ private static void Cleanup(IntPtr gsInstancePtr)
string outputPath,
int firstPage,
int lastPage,
int width,
int height)
int dpix,
int dpiy,
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);
s.Resolution = new System.Drawing.Size(dpix, dpiy);

Settings.GhostscriptPageSize pageSize = new Settings.GhostscriptPageSize();
pageSize.Native = GhostscriptSharp.Settings.GhostscriptPageSizes.a7;
s.Size = pageSize;
if (width == 0 && height == 0)
{
pageSize.Native = GhostscriptSharp.Settings.GhostscriptPageSizes.a7;
}
else
{
pageSize.Manual = new Size(width, height);
}
s.Size = pageSize;

return GetArgs(inputPath, outputPath, s);
}
Expand Down Expand Up @@ -199,6 +162,8 @@ private static void Cleanup(IntPtr gsInstancePtr)
{
args.Add(String.Format("-dDEVICEWIDTHPOINTS={0}", settings.Size.Manual.Width));
args.Add(String.Format("-dDEVICEHEIGHTPOINTS={0}", settings.Size.Manual.Height));
args.Add("-dFIXEDMEDIA");
args.Add("-dPDFFitPage");
}
else
{
Expand Down
2 changes: 2 additions & 0 deletions GhostScriptSharp/GhostscriptSharp.csproj
Expand Up @@ -46,6 +46,8 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="API\GhostScript32.cs" />
<Compile Include="API\GhostScript64.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="GhostscriptSharp.cs" />
</ItemGroup>
Expand Down
5 changes: 4 additions & 1 deletion Tests/GhostscriptSharpTests/GhostscriptSharpTests.csproj
Expand Up @@ -31,7 +31,7 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="nunit.framework, Version=2.5.0.9122, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
<Reference Include="nunit.framework, Version=2.6.0.12051, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
Expand Down Expand Up @@ -64,6 +64,9 @@
<Content Include="gsdll32.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="gsdll64.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Expand Down
Binary file modified Tests/GhostscriptSharpTests/gsdll32.dll
Binary file not shown.
Binary file added Tests/GhostscriptSharpTests/gsdll64.dll
Binary file not shown.
Binary file modified ThirdParty/gsdll32.dll
Binary file not shown.
Binary file added ThirdParty/gsdll64.dll
Binary file not shown.

0 comments on commit f4fa63b

Please sign in to comment.