Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed memory leaks and added drawPageAsPNGRaw method #58

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
61 changes: 60 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ async function handleSomePdf(file) {
const png = mupdf.drawPageAsPNG(doc, 1, 300);
const svg = mupdf.drawPageAsSVG(doc, 1);
const html = mupdf.drawPageAsHTML(doc, 1);

// This method returns Uint8Array
const pngRaw = mupdf.drawPageAsPNGRaw(doc, 1, 300);
}
```

Expand All @@ -81,7 +84,11 @@ async function handleSomePdf(file) {
### PNG

```js
mupdf.drawPageAsPNG(document, page, resolution);
// Returns PNG as data uri string
mupdf.drawPageAsPNG(document, page, resolution);

// Returns PNG data as Uint8Array
mupdf.drawPageAsPNGRaw(document, page, resolution);
```

Arguments:
Expand Down Expand Up @@ -145,6 +152,58 @@ Returns: *array of found rectangles of text matches ({x: number, y: number, w: n

You should set `maxHits` to an appropriate level that a user would expect (for example 100), or allow users to set their own limit. Alternatively, if you want to allow effectively unlimited search hits (and risk running out of memory), you can set it to C's maximum unsigned 32-bit integer size, which is 4294967295.

# Manual context management

By default, mupdf-js creates a MuPDF context upon initialization and uses it for all calls. However, since the context includes a cache, over time this can lead to an increase in the application's memory consumption. To manage the context independently, mupdf-js supports the following:

```js
import { createMuPdfWithoutContext } from "mupdf-js";

async function handleSomePdf(file) {
const mupdf = await createMuPdfWithoutContext();
const ctx = mupdf.createContext();
const buf = await file.arrayBuffer();
const arrayBuf = new Uint8Array(buf);
const doc = mupdf.load(ctx, arrayBuf);

// Each of these returns a string:

const png = mupdf.drawPageAsPNG(ctx, doc, 1, 300);
const svg = mupdf.drawPageAsSVG(ctx, doc, 1);
const html = mupdf.drawPageAsHTML(ctx, doc, 1);

// This method returns Uint8Array
const pngRaw = mupdf.drawPageAsPNGRaw(ctx, doc, 1, 300);
mupdf.freeDocument(doc);
mupdf.freeContext(ctx);
}
```

# Custom logging

By default, console.log and console.warn are used for printing errors and other messages. If you prefer to use your custom logger (e.g., pino), you can do the following:


```typescript
import {createMuPdf} from "mupdf-js";
import pino from 'pino';

const logger = pino();

async function handleSomePdf(file) {
const mupdf = await createMuPdf();
mupdf.setLogger({
log: (...args: any[]) => {
logger.debug(...args);
},
errorLog: (...args: any[]) => {
logger.error(...args);
},
});
//...
}
```

# Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md)
Expand Down
21 changes: 15 additions & 6 deletions bin/build-examples.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { mkdirSync, readFileSync, writeFileSync } from "fs";
import initMuPdf from "../dist/libmupdf";
import createMuPdf from "../dist";

main();

async function main() {
const mupdf = await initMuPdf();
const mupdf = await createMuPdf();
const { FS, openDocument, countPages } = mupdf;
const pdfFile = readFileSync("./examples/example.pdf");
FS.writeFile("example.pdf", pdfFile);
Expand All @@ -19,6 +19,7 @@ async function main() {
for (let i = 1; i <= n; i++) {
console.log("Page " + i + "");
writePageToPngFile(i, mupdf, doc);
writePageToPngRawFile(i, mupdf, doc);
writePageToSvgFile(i, mupdf, doc);
writePageToHtmlFile(i, mupdf, doc);
writePageToTextFile(i, mupdf, doc);
Expand All @@ -34,6 +35,13 @@ function writePageToPngFile(i: number, { drawPageAsPNG }: any, doc: any) {
);
}

function writePageToPngRawFile(i: number, { drawPageAsPNGRaw }: any, doc: any) {
writeFileSync(
`./examples/png/example-raw-${i}.png`,
drawPageAsPNGRaw(doc, i, 600)
);
}

function writePageToSvgFile(i: number, { drawPageAsSVG }: any, doc: any) {
writeFileSync(`./examples/svg/example-${i}.svg`, drawPageAsSVG(doc, i));
}
Expand All @@ -42,17 +50,18 @@ function writePageToHtmlFile(i: number, { drawPageAsHTML }: any, doc: any) {
writeFileSync(`./examples/html/example-${i}.html`, drawPageAsHTML(doc, i));
}

function writePageToTextFile(i: number, { getPageText }: any, doc: any) {
writeFileSync(`./examples/text/example-${i}.txt`, getPageText(doc, i));
}

function writePageSearchToFile(i: number, { searchPageText }: any, doc: any) {
writeFileSync(
`./examples/search/example-${i}-search.json`,
JSON.stringify(searchPageText(doc, i, 'lorem', 10), null, " ")
);
}

function writePageToTextFile(i: number, { getPageText }: any, doc: any) {
writeFileSync(`./examples/text/example-${i}.txt`, getPageText(doc, i));
}


function decodeUri(uri: string) {
return Buffer.from(uri.slice(23), "base64");
}
Empty file removed dist/.gitkeep
Empty file.
Binary file added examples/invalid.pdf
Binary file not shown.
2 changes: 2 additions & 0 deletions overrides/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ wasm: $(MUPDF_JS) $(MUPDF_WASM)
$(MUPDF_JS) $(MUPDF_WASM) : $(MUPDF_CORE) wrap.c wrap.js
BASH_SOURCE=$(EMSDK_DIR)/emsdk_env.sh; . $(EMSDK_DIR)/emsdk_env.sh; \
emcc -Wall -O3 -o $@ \
-s ASSERTIONS=1 \
-s WASM=1 \
-s VERBOSE=0 \
-s INITIAL_MEMORY=750MB \
-s MAXIMUM_MEMORY=4096MB \
-s ALLOW_MEMORY_GROWTH=1 \
-s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall","cwrap", "FS"]' \
-s MODULARIZE=1 \
Expand Down
Loading