8000 Memory leak on loading png in multiple pages · Issue #339 · libharu/libharu · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Memory leak on loading png in multiple pages #339
Open
@StephanBischof-eaton

Description

@StephanBischof-eaton

Hi,

The sample below creates 10 PDF files with the size A4 named "Test0.pdf".."Test9.pdf".
Each document contains 3 pages and each page contains a one large png image.
"MyFillpage1.png" on page 1
"MyFillpage2.png" on page 2
"MyFillpage3.png" on page 3
Each png is 1130x1600px in size and has alpha channel (32Bit)

When I execute the program I notice a memory leak of roughly 28MB on Ubuntu between the first and second iteration of creating a PDF.
The other iterations seem to be stable and no additional leaking memory.
Why there is such a large drop of free memory resp. increase of used memory after the first iteration ?
HPDF_Free is called at the end of each iteration.

Any suggestion or advise what goes wrong is aprechiated.

Procedure for memory determination:
At the begin of the program and after each iteration the sample requires to enter a value followed by ENTER. This gives time to note the used memory
before the PDF creation and after each iteration of PDF creation.
I determined the used memory with the command: "top -p "

Attached files to this issue:

  • MyFullpage1.png
  • MyFullpage2.png
  • MyFullpage3.png
  • sample output Test0.pdf (one of 10 identical PDF's)

Environment:

Files/Folders:
<path_to_current_folder>/sample.cpp
<path_to_current_folder>/include/
<path_to_current_folder>/lib/libhpdf.a

installed libraries:
sudo apt install libhpdf-dev libpng-dev
sudo apt install zlib1g-dev

compile/link:
g++ -std=c++17 -m32 -o my_program sample.cpp -Iinclude <path_to_current_folder>/lib/libhpdf.a -lpng -lz

Sample code:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sstream>
#include <iostream>
#include <filesystem>
#include "hpdf.h"

std::string libHaruError;

void error_handler(HPDF_STATUS   error_no,
                   HPDF_STATUS   detail_no,
                   void         *user_data)
{
    std::stringstream ss;
    ss << std::hex << "PDF engine error : error no. = 0x" << static_cast<unsigned int>(error_no)  <<
          std::dec << ", detail no.= "                    << static_cast<unsigned int>(detail_no) << 
                      " !";
    libHaruError = ss.str();
}



int main (int argc, char **argv)
{
    (void) argc; /* Not used */
    (void) argv; /* Not used */    

    std::cout << "Started...press a value and ENTER after memory noted" << std::endl;

    int wait;
    std::cin >> wait;

    for (int i=0; i<10; ++i)
    {
        // Create PDF
        HPDF_Doc pdf = HPDF_New(error_handler, NULL);

        if ( HPDF_SetCompressionMode (pdf, HPDF_COMP_ALL) != HPDF_OK )
        {
            std::cout << libHaruError.c_str()<< std::endl;
        }

        // Page size
        HPDF_REAL width  = 2.83f * 210; //A4
        HPDF_REAL height = 2.83f * 297; //A4
        

        // Add page 1
        HPDF_Page page = HPDF_AddPage(pdf);
        if ( HPDF_Page_SetWidth (page, width)  != HPDF_OK || 
             HPDF_Page_SetHeight(page, height) != HPDF_OK )
        {
            std::cout << libHaruError.c_str()<< std::endl;
        }

        HPDF_Image image = HPDF_LoadPngImageFromFile(pdf, "MyFullpage1.png");
        HPDF_UINT imageWidth = HPDF_Image_GetWidth(image);
        HPDF_UINT imageHeight= HPDF_Image_GetHeight(image);

        if (HPDF_Page_DrawImage(page, image, 0, 0, width, height) != HPDF_OK)
        {
            std::cout << libHaruError.c_str()<< std::endl;
        }

        // Add page 2
        HPDF_Page page2 = HPDF_AddPage(pdf);
        if ( HPDF_Page_SetWidth (page2, width)  != HPDF_OK || 
             HPDF_Page_SetHeight(page2, height) != HPDF_OK )
        {
            std::cout << libHaruError.c_str()<< std::endl;
        }    
        HPDF_Image image2 = HPDF_LoadPngImageFromFile(pdf, "MyFullpage2.png");
        imageWidth = HPDF_Image_GetWidth(image2);
        imageHeight= HPDF_Image_GetHeight(image2);
        
        if (HPDF_Page_DrawImage(page2, image2, 0, 0, width, height) != HPDF_OK)
        {
            std::cout << libHaruError.c_str()<< std::endl;
        }

        // Add page 3
        HPDF_Page page3 = HPDF_AddPage(pdf);
        if ( HPDF_Page_SetWidth (page3, width)  != HPDF_OK || 
             HPDF_Page_SetHeight(page3, height) != HPDF_OK )
        {
            std::cout << libHaruError.c_str()<< std::endl;
        }    
        HPDF_Image image3 = HPDF_LoadPngImageFromFile(pdf, "MyFullpage3.png");
        imageWidth = HPDF_Image_GetWidth(image3);
        imageHeight= HPDF_Image_GetHeight(image3);
        
        if (HPDF_Page_DrawImage(page3, image3, 0, 0, width, height) != HPDF_OK)
        {
            std::cout << libHaruError.c_str()<< std::endl;
        }
    
        std::stringstream ss;
        ss << "/tmp/Test" << i << ".pdf";

        // Remove file if exist already
        std::filesystem::remove(ss.str());
        
        // Save PDF
        if (HPDF_SaveToFile(pdf, ss.str().c_str()) != HPDF_OK)
        {
            std::cout << libHaruError.c_str()<< std::endl;
        }
        std::cout << "PDF <" << ss.str() << "> stored. Press value and ENTER after memory noted" << std::endl;
        
        HPDF_Free(pdf);    
        
        // wait for keyboard input to measure memory with "top" command for the current pid
        int wait;
        std::cin >> wait;        
    }
    std::cout << "Done" << std::endl;
    return 0;
}

Image
Image
Image
Test0.pdf

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

      0