Skip to content

Commit

Permalink
Use Pdfium-allocated buffers for correctness and simplicity
Browse files Browse the repository at this point in the history
  • Loading branch information
cyanfish committed Aug 31, 2023
1 parent 15b732a commit 8edee06
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 31 deletions.
11 changes: 7 additions & 4 deletions NAPS2.Sdk/Pdf/Pdfium/PdfBitmap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@ internal class PdfBitmap : NativePdfiumObject
public const uint BLACK = 0;
public const uint WHITE = uint.MaxValue;

public static PdfBitmap CreateFromPointerBgr(int width, int height, IntPtr scan0, int stride)
public static PdfBitmap CreateFromPointerBgr(int width, int height, IntPtr scan0, int stride) =>
CreateFromPointer(width, height, scan0, stride, PdfiumNativeLibrary.FPDFBitmap_BGR);

public static PdfBitmap CreateFromPointer(int width, int height, IntPtr scan0, int stride, int format)
{
return new PdfBitmap(
Native.FPDFBitmap_CreateEx(width, height, PdfiumNativeLibrary.FPDFBitmap_BGR, scan0, stride));
Native.FPDFBitmap_CreateEx(width, height, format, scan0, stride));
}

public static PdfBitmap CreateFromPointer(int width, int height, IntPtr scan0, int stride, int format)
public static PdfBitmap Create(int width, int height, int format)
{
return new PdfBitmap(
Native.FPDFBitmap_CreateEx(width, height, format, scan0, stride));
Native.FPDFBitmap_CreateEx(width, height, format, IntPtr.Zero, 0));
}

internal PdfBitmap(IntPtr handle) : base(handle)
Expand Down
23 changes: 9 additions & 14 deletions NAPS2.Sdk/Pdf/PdfiumImageExtractor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,26 +78,21 @@ private static IMemoryImage RenderPdfPageToNewImage(ImageContext imageContext, P
return CopyPdfBitmapToNewImage(imageContext, pdfBitmap, metadata);
}

private static unsafe PdfBitmap RenderPdfPageToBitmap(PdfPage page, PdfImageMetadata imageMetadata)
private static PdfBitmap RenderPdfPageToBitmap(PdfPage page, PdfImageMetadata imageMetadata)
{
var w = imageMetadata.Width;
var h = imageMetadata.Height;
var (subPixelType, format) = imageMetadata.BitsPerPixel switch
var format = imageMetadata.BitsPerPixel switch
{
1 or 8 => (SubPixelType.Gray, PdfiumNativeLibrary.FPDFBitmap_Gray),
24 => (SubPixelType.Bgr, PdfiumNativeLibrary.FPDFBitmap_BGR),
32 => (SubPixelType.Bgra, PdfiumNativeLibrary.FPDFBitmap_BGRA),
1 or 8 => PdfiumNativeLibrary.FPDFBitmap_Gray,
24 => PdfiumNativeLibrary.FPDFBitmap_BGR,
32 => PdfiumNativeLibrary.FPDFBitmap_BGRA,
_ => throw new ArgumentException()
};
var pixelInfo = new PixelInfo(w, h, subPixelType);
var buffer = new byte[pixelInfo.Length];
fixed (byte* ptr = buffer)
{
var pdfiumBitmap = PdfBitmap.CreateFromPointer(w, h, (IntPtr) ptr, pixelInfo.Stride, format);
pdfiumBitmap.FillRect(0, 0, w, h, PdfBitmap.WHITE);
pdfiumBitmap.RenderPage(page, 0, 0, w, h);
return pdfiumBitmap;
}
var pdfiumBitmap = PdfBitmap.Create(w, h, format);
pdfiumBitmap.FillRect(0, 0, w, h, PdfBitmap.WHITE);
pdfiumBitmap.RenderPage(page, 0, 0, w, h);
return pdfiumBitmap;
}

private static IMemoryImage CopyPdfBitmapToNewImage(ImageContext imageContext, PdfBitmap pdfBitmap,
Expand Down
20 changes: 7 additions & 13 deletions NAPS2.Sdk/Pdf/PdfiumPdfRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,21 +74,15 @@ public unsafe IMemoryImage RenderPageToNewImage(ImageContext imageContext, PdfPa
var bitmap = imageContext.Create(widthInPx, heightInPx, ImagePixelFormat.RGB24);
bitmap.SetResolution(xDpi, yDpi);

// As Pdfium only supports BGR, to be general we need to store it in an intermediate buffer,
// then use a copy operation to get the data to our output image (which might be BGR or RGB).
var pixelInfo = new PixelInfo(widthInPx, heightInPx, SubPixelType.Bgr);
var buffer = new byte[pixelInfo.Length];
fixed (byte* ptr = buffer)
{
using var pdfiumBitmap =
PdfBitmap.CreateFromPointerBgr(widthInPx, heightInPx, (IntPtr) ptr, pixelInfo.Stride);
pdfiumBitmap.FillRect(0, 0, widthInPx, heightInPx, PdfBitmap.WHITE);
pdfiumBitmap.RenderPage(page, 0, 0, widthInPx, heightInPx);
using var pdfiumBitmap =
PdfBitmap.Create(widthInPx, heightInPx, PdfiumNativeLibrary.FPDFBitmap_BGR);
pdfiumBitmap.FillRect(0, 0, widthInPx, heightInPx, PdfBitmap.WHITE);
pdfiumBitmap.RenderPage(page, 0, 0, widthInPx, heightInPx);

new CopyBitwiseImageOp().Perform(buffer, pixelInfo, bitmap);
var pixelInfo = new PixelInfo(pdfiumBitmap.Width, pdfiumBitmap.Height, SubPixelType.Bgr, pdfiumBitmap.Stride);
new CopyBitwiseImageOp().Perform(pdfiumBitmap.Buffer, pixelInfo, bitmap);

return bitmap;
}
return bitmap;
}

/// <summary>
Expand Down

0 comments on commit 8edee06

Please sign in to comment.