503 views
in GUI Development by
we are using external bitmap image and it is running from last two days.But due to some memory issue it fails .

it fails for the below statement

    /* Create an Embedded Wizard bitmap to store the image pixel data */
    bitmap = EwCreateBitmap(EW_PIXEL_FORMAT_NATIVE, frameSize, 0, 1);

    /* Enough memory to create the bitmap? */
    if (bitmap == NULL)
    {

        EwFreeBitmap(bitmap);    /* Added the statement to resolve the error 320  */
        printf("bitmap failed\n\r");
        return NULL;
    }

   /* Could create the image */
    if (bitmap)
    {
        lockArea.Point1.X = 0;
        lockArea.Point1.Y = 0;
        lockArea.Point2.X = frameSize.X;
        lockArea.Point2.Y = frameSize.Y;

        lock = EwLockBitmap(bitmap, 0, lockArea, 0, 1);

        png_bytep row_pointer;
        row_pointer = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));

        for (unsigned int pass = 0; pass < (unsigned int)frameSize.Y; pass++)
        {
            png_read_rows(png_ptr, &row_pointer, NULL, 1);

            unsigned int* dest = (unsigned int*)((char*)lock->Pixel1 + pass * lock->Pitch1Y);

            for (unsigned int x = 0; x < (unsigned int)frameSize.X; x++)
            {
                png_byte* ptr = &(row_pointer[x * channels]);

                // Get the RGBA values from the PNG decoder and arrange the 'red', 'green', 'blue' channels at the right bit offset position
                unsigned int red = ptr[0] << EW_COLOR_CHANNEL_BIT_OFFSET_RED;
                unsigned int green = ptr[1] << EW_COLOR_CHANNEL_BIT_OFFSET_GREEN;
                unsigned int blue = ptr[2] << EW_COLOR_CHANNEL_BIT_OFFSET_BLUE;
                unsigned int alpha;
                if (channels == 4)
                    alpha = ptr[3] << EW_COLOR_CHANNEL_BIT_OFFSET_ALPHA;
                else
                    alpha = 0xFF << EW_COLOR_CHANNEL_BIT_OFFSET_ALPHA;

                // Store the pixel data in the bitmap memory
                *dest++ = red | green | blue | alpha;
            }

        }

        png_free(png_ptr, row_pointer);
        row_pointer = NULL;
        png_read_end(png_ptr, info_ptr);

        /* Clean up after the read, and free any memory allocated. */
       png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

        /* Unlock the bitmap */
        EwUnlockBitmap(lock);
    }

 

EMWI ERROR: code: 41
For details please visit https://doc.embedded-wizard.de/errors
EMWI ERROR: code: 111, info1: 903, info2: 545
For details please visit https://doc.embedded-wizard.de/errors
EMWI ERROR: code: 320
For details please visit https://doc.embedded-wizard.de/errors
bitmap failed

 

What I tried . Analyses for 320 , put the statement  EwFreeBitmap(bitmap);    /* free the bitmap */ but still after some point it fails

code: 111, info1: 903, info2: 545 : I have put the printf statement :[SYSTEM EVENT] Opened:../../usr/share/splash.png 901x543 Channels:3 ColorType:2. so width and height has increased with "+2"

I am unable to find where exactly it fails ,.Because before migrating to EW11 it was working fine.

plase advice for the same ?

1 Answer

0 votes
by

Hello Pidea,

in case you get some errors during runtime, always start to analyze the issue starting from the first error message.

In your case, the error 41 indicates that there is not enough memory to fulfill the requested memory allocation. Do you have the chance to increase the memory pool provided to the entire GUI application? Maybe you can give some details about your current memory layout.

Concerning the modification:

...
    /* Enough memory to create the bitmap? */
    if (bitmap == NULL)
    {

        EwFreeBitmap(bitmap);    /* Added the statement to resolve the error 320  */
...

Please note, that you cannot free a bitmap in case the bitmap is NULL. This indicates already that the allocation was not successful.

Best regards,

Manfred.

by
Hi,

 

In my project Win32 is based environment where currently I am not taking care of any memory allocation as there is no hardware attach to it.

https://doc.embedded-wizard.de/main-loop?v=11.00#2

As per the docs ,

EwInitHeap( 0 );
    EwAddHeapMemoryPool( (void*)EW_MEMORY_POOL_ADDR, EW_MEMORY_POOL_SIZE );

 

As this is desktop application so what should be the address and pool size for this? . As Image File size is 81.34KB

#define EW_MEMORY_POOL_ADDR 0x0000

#define EW_MEMORY_POOL_SIZE 82000

 

So can you please let me know the memory pool setting for Win32 Application?
by
Hello,

in case of Win32, there is no need for using the heap management provided - in case of Win32 the memory manager of the operating system is used and the memory is allocated/freed by using standard alloc() and free() function calls.

There are no memory pool settings necessary for a Win32 desktop application.

In case that you get an out-of-memory situation on a Win32 machine after a couple of hours - I assume that your application is allocating memory but never freeing that until Windows is running out-of-memory.

Best regards,

Manfred.
by
XBitmap* EwLoadExternBitmap(XString aName)
{
    // LibPNG
    png_structp                 png_ptr;
    png_infop                     info_ptr;
    unsigned char                png_header[PNG_BYTES_TO_CHECK];
    unsigned char                channels, color_type;

    // FILE IO
    FILE* fil;

    // EW
    XBitmap* bitmap = 0;
    XBitmapLock* lock = 0;
    int                           nameLen = EwGetStringLength(aName);
    char* name = malloc(nameLen + 1);
    XPoint                        frameSize;
    XRect                         lockArea;

    /* Out of memory? */
    if (!name)
        return NULL;

    /* Convert the 16-bit wide char string in an 8-bit ANSI string */
    EwStringToAnsi(aName, name, nameLen + 1, 0);

    // Try to open the file
    if ((fil = fopen(name, "rb")) == NULL)
    {
        printf("EwLoadExternBitmap() f_open() error\n\r");
        free(name);
        return NULL;
    }

    // read PNG header
    if (fread(png_header, 1, PNG_BYTES_TO_CHECK, fil) != PNG_BYTES_TO_CHECK)
        return 0;

    if (png_sig_cmp(png_header, 0, PNG_BYTES_TO_CHECK))
    {
        printf("File %s is not recognized as a PNG file\n\r", name);
        free(name);
        fclose(fil);
        return NULL;
    }
    // initialize stuff
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr)
    {
        printf("png_create_read_struct() failed\n\r");
        free(name);
        fclose(fil);
        return NULL;
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
    {
        printf("png_create_info_struct() failed\n\r");
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        free(name);
        fclose(fil);
        return NULL;
    }

    if (setjmp(png_jmpbuf(png_ptr)))
    {
        printf("setjmp(png_jmpbuf) failed\n\r");
        /* Free all of the memory associated with the png_ptr and info_ptr. */
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        fclose(fil);
        /* If we get here, we had a problem reading the file. */
        return (NULL);
    }
    png_init_io(png_ptr, fil);
    png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK);
    png_read_info(png_ptr, info_ptr);
    //  png_set_scale_16(png_ptr);

    color_type = png_get_color_type(png_ptr, info_ptr);
    if (color_type == PNG_COLOR_TYPE_PALETTE)
        png_set_palette_to_rgb(png_ptr);

    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) != 0)
        png_set_tRNS_to_alpha(png_ptr);

    // Get PNG file info
    png_read_update_info(png_ptr, info_ptr);
    channels = png_get_channels(png_ptr, info_ptr);
    frameSize.X = png_get_image_width(png_ptr, info_ptr);
    frameSize.Y = png_get_image_height(png_ptr, info_ptr);
    printf("[SYSTEM EVENT] Opened:%s %ix%i Channels:%i ColorType:%i   \n\r", name, frameSize.X, frameSize.Y, channels, color_type);

    /* Create an Embedded Wizard bitmap to store the image pixel data */
    bitmap = EwCreateBitmap(EW_PIXEL_FORMAT_NATIVE, frameSize, 0, 1);

    /* Enough memory to create the bitmap? */
    if (bitmap == NULL)
    {
        printf("bitmap failed\n\r");
        return NULL;
    }

    /* Could create the image */
    if (bitmap)
    {
        lockArea.Point1.X = 0;
        lockArea.Point1.Y = 0;
        lockArea.Point2.X = frameSize.X;
        lockArea.Point2.Y = frameSize.Y;

        lock = EwLockBitmap(bitmap, 0, lockArea, 0, 1);

        png_bytep row_pointer;
        row_pointer = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));

        for (unsigned int pass = 0; pass < (unsigned int)frameSize.Y; pass++)
        {
            png_read_rows(png_ptr, &row_pointer, NULL, 1);

            unsigned int* dest = (unsigned int*)((char*)lock->Pixel1 + pass * lock->Pitch1Y);

            for (unsigned int x = 0; x < (unsigned int)frameSize.X; x++)
            {
                png_byte* ptr = &(row_pointer[x * channels]);

                // Get the RGBA values from the PNG decoder and arrange the 'red', 'green', 'blue' channels at the right bit offset position
                unsigned int red = ptr[0] << EW_COLOR_CHANNEL_BIT_OFFSET_RED;
                unsigned int green = ptr[1] << EW_COLOR_CHANNEL_BIT_OFFSET_GREEN;
                unsigned int blue = ptr[2] << EW_COLOR_CHANNEL_BIT_OFFSET_BLUE;
                unsigned int alpha;
                if (channels == 4)
                    alpha = ptr[3] << EW_COLOR_CHANNEL_BIT_OFFSET_ALPHA;
                else
                    alpha = 0xFF << EW_COLOR_CHANNEL_BIT_OFFSET_ALPHA;

                // Store the pixel data in the bitmap memory
                *dest++ = red | green | blue | alpha;
            }

        }

        png_free(png_ptr, row_pointer);
        row_pointer = NULL;
        png_read_end(png_ptr, info_ptr);

        /* Clean up after the read, and free any memory allocated. */
       png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

        /* Unlock the bitmap */
        EwUnlockBitmap(lock);
    }

    /* Decompression has finished, we can close the input file. */
    fclose(fil);

    /* Release temporary memory */
    free(name);

    /* all ok */
    return bitmap;
}

 

I am releasing the memory at the end of the loop
by

Yes, maybe the code snippet is correct, but your application has a memory leak at some other location...

Maybe there is memory allocated and never freed by your native code (could be strings, bitmaps or just memory that is allocated and never freed) or your GUI application is growing by collecting objects by keeping references to objects.

Please note, the point where you run into the out-of-memory situation does not indicate that this is the root cause of the issue!

Maybe you can check the memory consumption of your entire application -> see monitoring the memory usage. Does the memory consumption increase over the time? What does the Windows Taskmanager report concerning memory consumption?

 

by

Hi,

 

I started to montior the memory usage .And still fill the error is more like extern bitmap. 

i have image size as 901*543  , but if the bitmap failed i see in the log as 903*545 , it like increase with +2 pixel. 

Can you give me some input to check for the same

Below are the log details for the same .

Testing : Continous testing for 2 days

 https://ask.embedded-wizard.de/?qa=blob&qa_blobid=1872847626169524050

https://ask.embedded-wizard.de/?qa=blob&qa_blobid=13070449490622975466

 

by
Hi,

the image size is 901x543 pixel and the Graphics Engine will allocate a bitmap with the size 903x545 pixel. This is necessary to create a 1 pixel wide border with transparency around the bitmap - so this is correctly.

According to the provided log, it seems that there are already 183 MByte allocated for graphical objects. I assume they cannot be freed by the Garbage Collection, because they are kept by some references.

Have you seen that there are more than 28.000 Chora objects within your application? Is this really intended?

I assume that you build some chains of objects (e.g. adding views and never removing them) so that the number of objects are growing over the time.

Please check your application regarding this aspect.

Best regards,

Manfred.
by
sure I will check and thank you

Ask Embedded Wizard

Welcome to the question and answer site for Embedded Wizard users and UI developers.

Ask your question and receive answers from the Embedded Wizard support team or from other members of the community!

Embedded Wizard Website | Privacy Policy | Imprint

...