21using System.Runtime.InteropServices;
23using System.Threading.Tasks;
25[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(
"Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100d18d076ff369e4fb7295f51bbfedc5974e626236cec589265dca9183dd03ac869402b455337d976594875fb1993db7971bce4c6326bf5b6497ed50fe64629147cbe6ba727baf462fb9fcd2abb2db58feb93c754c92c107d6d57d9e099e8654ddc949d4622f13e01ef079351bc83c73988218218f3e67909ee75d225d6e9d78a7")]
36 ERR_CANNOT_CREATE_CONTEXT = 129,
41 ERR_CANNOT_REGISTER_HANDLERS = 130,
46 ERR_CANNOT_OPEN_FILE = 131,
51 ERR_CANNOT_COUNT_PAGES = 132,
56 ERR_CANNOT_RENDER = 134,
61 ERR_CANNOT_OPEN_STREAM = 135,
66 ERR_CANNOT_LOAD_PAGE = 136,
71 ERR_CANNOT_COMPUTE_BOUNDS = 137,
76 ERR_CANNOT_INIT_MUTEX = 138,
81 ERR_CANNOT_CLONE_CONTEXT = 139,
86 ERR_CANNOT_SAVE = 140,
91 ERR_CANNOT_CREATE_BUFFER = 141,
96 ERR_CANNOT_CREATE_WRITER = 142,
101 ERR_CANNOT_CLOSE_DOCUMENT = 143,
106 ERR_CANNOT_CREATE_PAGE = 144,
111 ERR_CANNOT_POPULATE_PAGE = 145,
370 [StructLayout(LayoutKind.Sequential)]
371 internal struct Cookie
375 public ulong progress_max;
377 public int incomplete;
402 this.Progress = progress;
403 this.MaxProgress = (long)maxProgress;
412 internal RenderProgress(ThreadRenderProgress[] threadRenderProgresses)
426 private readonly IntPtr InternalPointer;
431 private readonly
long BytesAllocated = -1;
439 this.InternalPointer = pointer;
449 this.InternalPointer = pointer;
450 this.BytesAllocated = bytesAllocated;
452 if (BytesAllocated > 0)
454 GC.AddMemoryPressure(bytesAllocated);
458 private bool disposedValue;
461 protected virtual void Dispose(
bool disposing)
465 Marshal.FreeHGlobal(InternalPointer);
467 if (BytesAllocated > 0)
469 GC.RemoveMemoryPressure(BytesAllocated);
472 disposedValue =
true;
479 Dispose(disposing:
false);
483 public void Dispose()
485 Dispose(disposing:
true);
486 GC.SuppressFinalize(
this);
502 this.ErrorCode = errorCode;
517 internal class UTF8EncodedString : IDisposable
519 private bool disposedValue;
524 public IntPtr Address {
get; }
530 public UTF8EncodedString(
string text)
532 byte[] data = System.Text.Encoding.UTF8.GetBytes(text);
534 IntPtr dataHolder = Marshal.AllocHGlobal(data.Length + 1);
535 Marshal.Copy(data, 0, dataHolder, data.Length);
536 Marshal.WriteByte(dataHolder, data.Length, 0);
538 this.Address = dataHolder;
541 protected virtual void Dispose(
bool disposing)
545 Marshal.FreeHGlobal(Address);
546 disposedValue =
true;
552 Dispose(disposing:
false);
555 public void Dispose()
557 Dispose(disposing:
true);
558 GC.SuppressFinalize(
this);
578 this.Message = message;
587 private static int StdOutFD = -1;
588 private static int StdErrFD = -1;
590 private static TextWriter ConsoleOut;
591 private static TextWriter ConsoleErr;
593 private static ConsoleColor DefaultForeground;
594 private static ConsoleColor DefaultBackground;
596 private static string PipeName;
597 private static bool CleanupRegistered =
false;
598 private static object CleanupLock =
new object();
616 if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows))
618 await RedirectOutputWindows();
622 await RedirectOutputUnix();
625 if (!CleanupRegistered)
627 AppDomain.CurrentDomain.ProcessExit += (s, e) =>
634 const int UnixMaxPipeLength = 107;
636 private static async Task RedirectOutputUnix()
638 if (StdOutFD < 0 && StdErrFD < 0)
640 string tempPath = Path.GetTempPath();
642 string pipeName =
"MuPDFCore-" + Guid.NewGuid().ToString();
644 pipeName = pipeName.Substring(0, Math.Min(pipeName.Length, UnixMaxPipeLength - tempPath.Length - 4));
645 pipeName = Path.Combine(tempPath, pipeName);
649 Task redirectOutputTask = System.Threading.Tasks.Task.Run(() =>
651 NativeMethods.RedirectOutput(out StdOutFD, out StdErrFD, pipeName +
"-out", pipeName +
"-err");
657 using (NamedPipeClientStream client =
new NamedPipeClientStream(pipeName +
"-out"))
669 using (StreamReader reader =
new StreamReader(client))
673 string message = reader.ReadLine();
675 if (!
string.IsNullOrEmpty(message))
688 using (NamedPipeClientStream client =
new NamedPipeClientStream(pipeName +
"-err"))
700 using (StreamReader reader =
new StreamReader(client))
704 string message = reader.ReadLine();
706 if (!
string.IsNullOrEmpty(message))
716 await redirectOutputTask;
718 ConsoleOut = Console.Out;
719 ConsoleErr = Console.Error;
721 ConsoleColor fg = Console.ForegroundColor;
722 ConsoleColor bg = Console.BackgroundColor;
724 Console.ResetColor();
726 DefaultForeground = Console.ForegroundColor;
727 DefaultBackground = Console.BackgroundColor;
729 Console.ForegroundColor = fg;
730 Console.BackgroundColor = bg;
732 Console.SetOut(
new FileDescriptorTextWriter(Console.Out.Encoding, StdOutFD));
733 Console.SetError(
new FileDescriptorTextWriter(Console.Error.Encoding, StdErrFD));
737 private static async Task RedirectOutputWindows()
739 if (StdOutFD < 0 && StdErrFD < 0)
741 string pipeName =
"MuPDFCore-" + Guid.NewGuid().ToString();
743 Task redirectOutputTask = System.Threading.Tasks.Task.Run(() =>
745 NativeMethods.RedirectOutput(out StdOutFD, out StdErrFD,
"\\\\.\\pipe\\" + pipeName +
"-out",
"\\\\.\\pipe\\" + pipeName +
"-err");
751 using (NamedPipeClientStream client =
new NamedPipeClientStream(pipeName +
"-out"))
763 using (StreamReader reader =
new StreamReader(client))
767 string message = reader.ReadLine();
769 if (!
string.IsNullOrEmpty(message))
782 using (NamedPipeClientStream client =
new NamedPipeClientStream(pipeName +
"-err"))
794 using (StreamReader reader =
new StreamReader(client))
798 string message = reader.ReadLine();
800 if (!
string.IsNullOrEmpty(message))
810 await redirectOutputTask;
812 ConsoleOut = Console.Out;
813 ConsoleErr = Console.Error;
815 ConsoleColor fg = Console.ForegroundColor;
816 ConsoleColor bg = Console.BackgroundColor;
818 Console.ResetColor();
820 DefaultForeground = Console.ForegroundColor;
821 DefaultBackground = Console.BackgroundColor;
823 Console.ForegroundColor = fg;
824 Console.BackgroundColor = bg;
826 Console.SetOut(
new FileDescriptorTextWriter(Console.Out.Encoding, StdOutFD));
827 Console.SetError(
new FileDescriptorTextWriter(Console.Error.Encoding, StdErrFD));
838 if (StdOutFD >= 0 && StdErrFD >= 0)
840 NativeMethods.ResetOutput(StdOutFD, StdErrFD);
842 Console.SetOut(ConsoleOut);
843 Console.SetError(ConsoleErr);
848 if (!System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
850 File.Delete(PipeName +
"-out");
851 File.Delete(PipeName +
"-err");
857 internal class FileDescriptorTextWriter : TextWriter
859 public override Encoding Encoding {
get; }
860 private int FileDescriptor {
get; }
862 public FileDescriptorTextWriter(Encoding encoding,
int fileDescriptor)
864 this.Encoding = encoding;
865 this.FileDescriptor = fileDescriptor;
868 public override void Write(
string value)
870 StringBuilder sb =
new StringBuilder();
872 if (Console.ForegroundColor != DefaultForeground || Console.BackgroundColor != DefaultBackground)
877 if (Console.ForegroundColor != DefaultForeground)
879 switch (Console.ForegroundColor)
881 case ConsoleColor.Black:
884 case ConsoleColor.DarkRed:
887 case ConsoleColor.DarkGreen:
890 case ConsoleColor.DarkYellow:
893 case ConsoleColor.DarkBlue:
896 case ConsoleColor.DarkMagenta:
899 case ConsoleColor.DarkCyan:
902 case ConsoleColor.Gray:
905 case ConsoleColor.DarkGray:
908 case ConsoleColor.Red:
911 case ConsoleColor.Green:
914 case ConsoleColor.Yellow:
917 case ConsoleColor.Blue:
920 case ConsoleColor.Magenta:
923 case ConsoleColor.Cyan:
926 case ConsoleColor.White:
932 if (Console.ForegroundColor != DefaultForeground && Console.BackgroundColor != DefaultBackground)
937 if (Console.BackgroundColor != DefaultBackground)
939 switch (Console.BackgroundColor)
941 case ConsoleColor.Black:
944 case ConsoleColor.DarkRed:
947 case ConsoleColor.DarkGreen:
950 case ConsoleColor.DarkYellow:
953 case ConsoleColor.DarkBlue:
956 case ConsoleColor.DarkMagenta:
959 case ConsoleColor.DarkCyan:
962 case ConsoleColor.Gray:
965 case ConsoleColor.DarkGray:
968 case ConsoleColor.Red:
971 case ConsoleColor.Green:
974 case ConsoleColor.Yellow:
977 case ConsoleColor.Blue:
980 case ConsoleColor.Magenta:
983 case ConsoleColor.Cyan:
986 case ConsoleColor.White:
992 if (Console.ForegroundColor != DefaultForeground || Console.BackgroundColor != DefaultBackground)
999 if (Console.ForegroundColor != DefaultForeground || Console.BackgroundColor != DefaultBackground)
1004 if (Console.ForegroundColor != DefaultForeground)
1009 if (Console.ForegroundColor != DefaultForeground && Console.BackgroundColor != DefaultBackground)
1014 if (Console.BackgroundColor != DefaultBackground)
1019 if (Console.ForegroundColor != DefaultForeground || Console.BackgroundColor != DefaultBackground)
1024 NativeMethods.WriteToFileDescriptor(FileDescriptor, sb.ToString(), sb.Length);
1027 public override void Write(
char value)
1029 Write(value.ToString());
1032 public override void Write(
char[] buffer)
1034 Write(
new string(buffer));
1037 public override void Write(
char[] buffer,
int index,
int count)
1039 Write(
new string(buffer, index, count));
1042 public override void WriteLine(
string value)
1053 internal static class NativeMethods
1061 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1062 internal static extern int CreateContext(ulong store_size, ref IntPtr out_ctx);
1069 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1070 internal static extern int DisposeContext(IntPtr ctx);
1078 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1079 internal static extern int ShrinkStore(IntPtr ctx, uint perc);
1086 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1087 internal static extern void EmptyStore(IntPtr ctx);
1094 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1095 internal static extern ulong GetCurrentStoreSize(IntPtr ctx);
1102 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1103 internal static extern ulong GetMaxStoreSize(IntPtr ctx);
1112 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1113 internal static extern void SetAALevel(IntPtr ctx,
int aa,
int graphics_aa,
int text_aa);
1122 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1123 internal static extern void GetAALevel(IntPtr ctx, out
int out_aa, out
int out_graphics_aa, out
int out_text_aa);
1137 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1138 internal static extern int GetDisplayList(IntPtr ctx, IntPtr page,
int annotations, ref IntPtr out_display_list, ref
float out_x0, ref
float out_y0, ref
float out_x1, ref
float out_y1);
1146 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1147 internal static extern int DisposeDisplayList(IntPtr ctx, IntPtr list);
1163 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1164 internal static extern int CreateDocumentFromStream(IntPtr ctx, IntPtr data, ulong data_length,
string file_type,
int get_image_resolution, ref IntPtr out_doc, ref IntPtr out_str, ref
int out_page_count, ref
float out_image_xres, ref
float out_image_yres);
1177 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1178 internal static extern int CreateDocumentFromFile(IntPtr ctx, IntPtr file_name,
int get_image_resolution, ref IntPtr out_doc, ref
int out_page_count, ref
float out_image_xres, ref
float out_image_yres);
1186 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1187 internal static extern int DisposeStream(IntPtr ctx, IntPtr str);
1195 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1196 internal static extern int DisposeDocument(IntPtr ctx, IntPtr doc);
1212 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1213 internal static extern int RenderSubDisplayList(IntPtr ctx, IntPtr list,
float x0,
float y0,
float x1,
float y1,
float zoom,
int colorFormat, IntPtr pixel_storage, IntPtr cookie);
1227 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1228 internal static extern int LoadPage(IntPtr ctx, IntPtr doc,
int page_number, ref IntPtr out_page, ref
float out_x, ref
float out_y, ref
float out_w, ref
float out_h);
1236 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1237 internal static extern int DisposePage(IntPtr ctx, IntPtr page);
1249 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1250 internal static extern int LayoutDocument(IntPtr ctx, IntPtr doc,
float width,
float height,
float em, out
int out_page_count);
1259 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1260 internal static extern int CloneContext(IntPtr ctx,
int count, IntPtr out_contexts);
1277 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1278 internal static extern int SaveImage(IntPtr ctx, IntPtr list,
float x0,
float y0,
float x1,
float y1,
float zoom,
int colorFormat, IntPtr file_name,
int output_format,
int quality);
1297 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1298 internal static extern int WriteImage(IntPtr ctx, IntPtr list,
float x0,
float y0,
float x1,
float y1,
float zoom,
int colorFormat,
int output_format,
int quality, ref IntPtr out_buffer, ref IntPtr out_data, ref ulong out_length);
1306 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1307 internal static extern int DisposeBuffer(IntPtr ctx, IntPtr buf);
1317 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1318 internal static extern int CreateDocumentWriter(IntPtr ctx, IntPtr file_name,
int format, ref IntPtr out_document_writer);
1332 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1333 internal static extern int WriteSubDisplayListAsPage(IntPtr ctx, IntPtr list,
float x0,
float y0,
float x1,
float y1,
float zoom, IntPtr writ);
1341 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1342 internal static extern int FinalizeDocumentWriter(IntPtr ctx, IntPtr writ);
1362 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1363 internal static extern int GetStructuredTextChar(IntPtr character, ref
int out_c, ref
int out_color, ref
float out_origin_x, ref
float out_origin_y, ref
float out_size, ref
float out_ll_x, ref
float out_ll_y, ref
float out_ul_x, ref
float out_ul_y, ref
float out_ur_x, ref
float out_ur_y, ref
float out_lr_x, ref
float out_lr_y);
1371 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1372 internal static extern int GetStructuredTextChars(IntPtr line, IntPtr out_chars);
1387 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1388 internal static extern int GetStructuredTextLine(IntPtr line, ref
int out_wmode, ref
float out_x0, ref
float out_y0, ref
float out_x1, ref
float out_y1, ref
float out_x, ref
float out_y, ref
int out_char_count);
1396 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1397 internal static extern int GetStructuredTextLines(IntPtr block, IntPtr out_lines);
1410 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1411 internal static extern int GetStructuredTextBlock(IntPtr block, ref
int out_type, ref
float out_x0, ref
float out_y0, ref
float out_x1, ref
float out_y1, ref
int out_line_count);
1419 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1420 internal static extern int GetStructuredTextBlocks(IntPtr page, IntPtr out_blocks);
1430 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1431 internal static extern int GetStructuredTextPage(IntPtr ctx, IntPtr list, ref IntPtr out_page, ref
int out_stext_block_count);
1438 internal delegate
int ProgressCallback(
int progress);
1456 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1457 internal static extern int GetStructuredTextPageWithOCR(IntPtr ctx, IntPtr list, ref IntPtr out_page, ref
int out_stext_block_count,
float zoom,
float x0,
float y0,
float x1,
float y1,
string prefix,
string language, [MarshalAs(UnmanagedType.FunctionPtr)] ProgressCallback callback);
1465 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1466 internal static extern int DisposeStructuredTextPage(IntPtr ctx, IntPtr page);
1475 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1476 internal static extern void RedirectOutput(out
int stdoutFD, out
int stderrFD,
string stdoutPipeName,
string stderrPipeName);
1484 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1485 internal static extern void WriteToFileDescriptor(
int fileDescriptor,
string text,
int length);
1492 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1493 internal static extern void ResetOutput(
int stdoutFD,
int stderrFD);
1502 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1503 internal static extern int UnlockWithPassword(IntPtr ctx, IntPtr doc,
string password);
1511 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1512 internal static extern int CheckIfPasswordNeeded(IntPtr ctx, IntPtr doc);
1520 [DllImport(
"MuPDFWrapper", CallingConvention = CallingConvention.Cdecl)]
1521 internal static extern int GetPermissions(IntPtr ctx, IntPtr doc);
An IDisposable wrapper around an IntPtr that frees the allocated memory when it is disposed.
DisposableIntPtr(IntPtr pointer, long bytesAllocated)
Create a new DisposableIntPtr, adding memory pressure to the GC to account for the allocation of unma...
DisposableIntPtr(IntPtr pointer)
Create a new DisposableIntPtr.
The exception that is thrown when an attempt is made to render an encrypted document without supplyin...
EventArgs for the MuPDF.StandardOutputMessage and MuPDF.StandardErrorMessage events.
string Message
The message that has been logged.
MessageEventArgs(string message)
Create a new MessageEventArgs instance.
The exception that is thrown when a MuPDF operation fails.
readonly ExitCodes ErrorCode
The ExitCodes returned by the native function.
Contains static methods to perform setup operations.
static async Task RedirectOutput()
Redirects output messages from the native MuPDF library to the StandardOutputMessage and StandardErro...
static EventHandler< MessageEventArgs > StandardOutputMessage
This event is invoked when RedirectOutput has been called and the native MuPDF library writes to the ...
static EventHandler< MessageEventArgs > StandardErrorMessage
This event is invoked when RedirectOutput has been called and the native MuPDF library writes to the ...
static void ResetOutput()
Reset the default standard output and error streams for the native MuPDF library.
Holds a summary of the progress of the current rendering operation.
ThreadRenderProgress[] ThreadRenderProgresses
Contains the progress of all the threads used in rendering the document.
DocumentOutputFileTypes
Document file types supported in output by the library.
InputFileTypes
File types supported in input by the library.
EncryptionState
Possible document encryption states.
RestrictionState
Possible document restriction states.
ExitCodes
Exit codes returned by native methods describing various errors that can occur.
DocumentRestrictions
Document restrictions.
PixelFormats
Pixel formats supported by the library.
PasswordTypes
Password types.
RasterOutputFileTypes
Raster image file types supported in output by the library.
Holds the progress of a single thread.
int Progress
The current progress.
long MaxProgress
The maximum progress. If this is 0, this value could not be determined (yet).