Skip to content

Zoom plugin memory issues #224

@mpenndev

Description

@mpenndev

Hello, I was wondering if anyone could advise where I'm going wrong with my usage of the zoom plugin.

~90% of the time I get a memory error on the initial render of the PDF.
~8% of the time the PDF renders and I get a memory error as soon as I try to adjust the zoom level.
~2% of the time I can adjust the zoom level one or twice, then I get the memory error.

Given the example of zoom working I'm presuming that I'm missing something in my implementation.

Toolbar implementation:

import { useFullscreen } from '@embedpdf/plugin-fullscreen/react'
import { useZoom, ZoomMode } from '@embedpdf/plugin-zoom/react'
import { Fullscreen, FullscreenExit } from '@mui/icons-material'
import { AppBar, IconButton, Toolbar } from '@mui/material'

const PDFToolbar = () => {
    const { provides: fullscreenProvider, state: fullscreenState } = useFullscreen()
    const { provides: zoomProvider } = useZoom()

    return (
        <AppBar position='static'>
            <Toolbar variant='dense'>
                <IconButton onClick={() => fullscreenProvider?.toggleFullscreen()} aria-label='fullscreen'>
                    {fullscreenState.isFullscreen ? <FullscreenExit /> : <Fullscreen />}
                </IconButton>
                <IconButton onClick={() => zoomProvider?.zoomIn()}>
                    -
                </IconButton>
                <IconButton onClick={() => zoomProvider?.zoomOut()}>
                    +
                </IconButton>
                <IconButton onClick={() => zoomProvider?.requestZoom(ZoomMode.FitPage)}>Fit Page</IconButton>
                <IconButton onClick={() => zoomProvider?.requestZoom(ZoomMode.FitWidth)}>Fit Width</IconButton>
            </Toolbar>
        </AppBar>
    )
}

export default PDFToolbar

Viewer implementation:

import { createPluginRegistration } from '@embedpdf/core'
import { EmbedPDF } from '@embedpdf/core/react'
import { usePdfiumEngine } from '@embedpdf/engines/react'
import { FullscreenPluginPackage } from '@embedpdf/plugin-fullscreen/react'
import { LoaderPluginPackage, useLoaderCapability } from '@embedpdf/plugin-loader/react'
import { RenderLayer, RenderPluginPackage } from '@embedpdf/plugin-render/react'
import { Scroller, ScrollPluginPackage } from '@embedpdf/plugin-scroll/react'
import { Viewport, ViewportPluginPackage } from '@embedpdf/plugin-viewport/react'
import { ZoomPluginPackage } from '@embedpdf/plugin-zoom/react'
import { CircularProgress } from '@mui/material'
import { useEffect } from 'react'
import useSWRImmutable from 'swr/immutable'
import PDFToolbar from './PDFToolbar'
import { getDownloadEndpoint } from '../api/endpoints'

interface BlobWithFilename {
    blob: Blob
    filename: string
}

interface PDFViewerProps {
    fileId: string
}

interface WrappedPDFViewerProps extends PDFViewerProps {
    data?: BlobWithFilename
}

const WrappedPDFViewer = ({ fileId, data }: WrappedPDFViewerProps) => {
    const { provides } = useLoaderCapability()

    useEffect(() => {
        const run = async () => {
            const buffer = await data?.blob.arrayBuffer()

            if (buffer) {
                provides?.loadDocument({
                    type: 'buffer',
                    pdfFile: {
                        id: fileId,
                        content: buffer,
                    },
                })
            }
        }

        run()
    }, [data, provides, fileId])

    return (
        <>
            <PDFToolbar />
            <Viewport
                style={{
                    backgroundColor: '#525659',
                    width: 'unset',
                }}
            >
                <Scroller
                    renderPage={({ width, height, pageIndex, scale }) => (
                        <div style={{ width, height }}>
                            <RenderLayer pageIndex={pageIndex} scale={scale} />
                        </div>
                    )}
                />
            </Viewport>
        </>
    )
}

const pdfPlugins = [
    createPluginRegistration(LoaderPluginPackage),
    createPluginRegistration(ViewportPluginPackage),
    createPluginRegistration(ScrollPluginPackage),
    createPluginRegistration(RenderPluginPackage),
    createPluginRegistration(FullscreenPluginPackage),
    createPluginRegistration(ZoomPluginPackage),
]

const PDFViewer = ({ fileId }: PDFViewerProps) => {
    const { engine } = usePdfiumEngine()

    // Get Stream of PDF from API
    const { data, isLoading: isDownloading } = useSWRImmutable<BlobWithFilename>(getDownloadEndpoint(fileId))

    if (!engine || isDownloading) {
        return <CircularProgress />
    }

    return (
        <EmbedPDF engine={engine} plugins={pdfPlugins}>
            <WrappedPDFViewer fileId={fileId} data={data} />
        </EmbedPDF>
    )
}

export default PDFViewer

Most common error I get is:

ncaught (in promise) RuntimeError: memory access out of bounds
at pdfium.wasm.std::__2::__tree<std::__2::__value_type<unsigned int, fxcrt::RetainPtr<CPDF_Object>>, std::__2::__map_value_compare<unsigned int, std::__2::__value_type<unsigned int, fxcrt::RetainPtr<CPDF_Object>>, std::__2::less, true>, std::__2::allocator<std::__2::__value_type<unsigned int, fxcrt::RetainPtr<CPDF_Object>>>>::destroy(std::__2::__tree_node<std::__2::__value_type<unsigned int, fxcrt::RetainPtr<CPDF_Object>>, void*>) (wasm://wasm/pdfium.wasm-01d59ee2:wasm-function[139]:0xb1b0)
at pdfium.wasm.std::__2::__tree<std::__2::__value_type<unsigned int, fxcrt::RetainPtr<CPDF_Object>>, std::__2::__map_value_compare<unsigned int, std::__2::__value_type<unsigned int, fxcrt::RetainPtr<CPDF_Object>>, std::__2::less, true>, std::__2::allocator<std::__2::__value_type<unsigned int, fxcrt::RetainPtr<CPDF_Object>>>>::destroy(std::__2::__tree_node<std::__2::__value_type<unsigned int, fxcrt::RetainPtr<CPDF_Object>>, void
>) (wasm://wasm/pdfium.wasm-01d59ee2:wasm-function[139]:0xb18c)
at pdfium.wasm.std::__2::__tree<std::__2::__value_type<unsigned int, fxcrt::RetainPtr<CPDF_Object>>, std::__2::__map_value_compare<unsigned int, std::__2::__value_type<unsigned int, fxcrt::RetainPtr<CPDF_Object>>, std::__2::less, true>, std::__2::allocator<std::__2::__value_type<unsigned int, fxcrt::RetainPtr<CPDF_Object>>>>::destroy(std::__2::__tree_node<std::__2::__value_type<unsigned int, fxcrt::RetainPtr<CPDF_Object>>, void
>) (wasm://wasm/pdfium.wasm-01d59ee2:wasm-function[139]:0xb196)
at pdfium.wasm.std::__2::__tree<std::__2::__value_type<unsigned int, fxcrt::RetainPtr<CPDF_Object>>, std::__2::__map_value_compare<unsigned int, std::__2::__value_type<unsigned int, fxcrt::RetainPtr<CPDF_Object>>, std::__2::less, true>, std::__2::allocator<std::__2::__value_type<unsigned int, fxcrt::RetainPtr<CPDF_Object>>>>::destroy(std::__2::__tree_node<std::__2::__value_type<unsigned int, fxcrt::RetainPtr<CPDF_Object>>, void
>*) (wasm://wasm/pdfium.wasm-01d59ee2:wasm-function[139]:0xb18c)
at pdfium.wasm.CPDF_IndirectObjectHolder::~CPDF_IndirectObjectHolder()_140 (wasm://wasm/pdfium.wasm-01d59ee2:wasm-function[140]:0xb21c)
at pdfium.wasm.FPDF_CloseDocument (wasm://wasm/pdfium.wasm-01d59ee2:wasm-function[3689]:0x10582f)
at blob:http://localhost:3000/68b29d6d-2340-4d09-b0ec-0cdd516f8756:2172:16
at ccall (blob:http://localhost:3000/68b29d6d-2340-4d09-b0ec-0cdd516f8756:5754:17)
at Object.FPDF_CloseDocument (blob:http://localhost:3000/68b29d6d-2340-4d09-b0ec-0cdd516f8756:5763:27)
at DocumentContext.dispose (blob:http://localhost:3000/68b29d6d-2340-4d09-b0ec-0cdd516f8756:9297:24)

Any assistance is much appreciated!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions