Page 1 of 1

[MagickCore] ImageToBlob

Posted: 2010-12-03T07:36:31-07:00
by Wim
Hello,

I think i have a bug with the function ImageToBlob because it takes a large amount of memory.

Here is my code :

Code: Select all

void            modify_img(t_list *params, t_final_img *output)
{
  size_t                        size;
  unsigned char                 *blob;
  MagickPixelPacket             background;
  ImageInfo                     *image_info;
  ExceptionInfo                 *exception;

  background.red = 0;
  background.blue = 0;
  background.green = 0;
  background.opacity = 0;
  size = 0;
  image_info = AcquireImageInfo();
  exception = AcquireExceptionInfo();
  strcpy(image_info->filename, "dummy.");
  strcat(image_info->filename, output->extend);
  image_info->quality = output->quality;
  output->image = NewMagickImage(image_info, 512, 512, &background);
  calc_pixel(params, output);
  write_header_http(output);
  blob = ImageToBlob(image_info, output->image, &size, exception);
  if (exception->severity != UndefinedException)
    CatchException(exception);
  fwrite(blob, size, 1, stdout);
  fflush(stdout);
  if (cache_activated)
    writeInCache(blob, output, size);
  blob = xfree(blob);
  DestroyImageInfo(image_info);
  DestroyExceptionInfo(exception);
  DestroyImage(output->image);
}
When ImageToBlob is executed, 2GO of memory are consumed. This is a lot of memory for a simple 512x512 image.
Strace :
munmap(0xb6033000, 2101248) = 0
mmap2(NULL, 135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb6213000
mmap2(NULL, 135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb61f2000
mmap2(NULL, 135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb61d1000
mmap2(NULL, 834367488, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x8427b000
mmap2(NULL, 834367488, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x526c4000
mremap(0xb6213000, 135168, 430080, MREMAP_MAYMOVE) = 0xb6168000
munmap(0x8427b000, 834367488) = 0
The second param of the 2 big mmap change every time I restart the program.
$ MagickCore-config --version
6.6.2 Q16
My function calc_pixel is just copying an image into output->image. write_header_http is writing a content-type in stdout.

Did I make some mistake or is it a bug ?

Thanks for help.

Re: [MagickCore] ImageToBlob

Posted: 2010-12-03T08:24:15-07:00
by magick
We have
  • -> MagickCore-config --version
    6.6.6 Q16
For a variation of your code (see below) we get 2MB of memory allocation (per valgrind) and no memory leaks:
  • ==24316== HEAP SUMMARY:
    ==24316== total heap usage: 637 allocs, 142 frees, 2,479,187 bytes allocated
    ==24316==
    ==24316== LEAK SUMMARY:
    ==24316== definitely lost: 0 bytes in 0 blocks
    ==24316== indirectly lost: 0 bytes in 0 blocks
The program we ran:

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <magick/MagickCore.h>

void            modify_img()
{
  size_t                        size;
  unsigned char                 *blob;
  MagickPixelPacket             background;
  ImageInfo                     *image_info;
  Image *image;
  ExceptionInfo                 *exception;
  FILE *file;

  memset(&background,0,sizeof(MagickPixelPacket));
  exception = AcquireExceptionInfo();
  image_info = AcquireImageInfo();
  strcpy(image_info->filename, "dummy.pnm");
  image_info->quality = 90;
  image = NewMagickImage(image_info, 512, 512, &background);
  size = 0;
  blob = ImageToBlob(image_info, image, &size, exception);
  if (exception->severity != UndefinedException)
    CatchException(exception);
  file=fopen("test.miff","wb");
  fwrite(blob, size, 1, file);
  fclose(file);
  free(blob);
  DestroyImage(image);
  DestroyImageInfo(image_info);
  DestroyExceptionInfo(exception);
}

main()
{
  modify_img();
}

Re: [MagickCore] ImageToBlob

Posted: 2010-12-03T09:25:33-07:00
by Wim
Problem solved by upgrading in the last version.

But I've another question :
==24316== total heap usage: 637 allocs, 142 frees, 2,479,187 bytes allocated
Nothing shocks you here ?

It's a FCGI program so i must not leak.

Thanks for your help anyway :)

Re: [MagickCore] ImageToBlob

Posted: 2010-12-03T09:54:25-07:00
by magick
Not sure what you're asking. Valgrind reports "==24316== definitely lost: 0 bytes in 0 blocks" confirming there are no memory leaks.

Re: [MagickCore] ImageToBlob

Posted: 2010-12-03T10:24:32-07:00
by Wim
If I run a valgrind on my program, it reports :

Code: Select all

==23454== LEAK SUMMARY:
==23454==    definitely lost: 0 bytes in 0 blocks
==23454==    indirectly lost: 0 bytes in 0 blocks
==23454==      possibly lost: 176 bytes in 1 blocks
==23454==    still reachable: 21,278 bytes in 767 blocks
==23454==         suppressed: 0 bytes in 0 blocks
==23454== Reachable blocks (those to which a pointer was found) are not shown.
==23454== To see them, rerun with: --leak-check=full --show-reachable=yes
So there is 21kb which are still reachable.

Code: Select all

==23540== 16,644 bytes in 1 blocks are definitely lost in loss record 82 of 82
==23540==    at 0x4024DB9: memalign (vg_replace_malloc.c:581)
==23540==    by 0x4024E16: posix_memalign (vg_replace_malloc.c:709)
==23540==    by 0x414B939: AcquireAlignedMemory (in /usr/lib/libMagickCore.so.3.0.0)
==23540==    by 0x4136C7A: AcquireImageInfo (in /usr/lib/libMagickCore.so.3.0.0)
==23540==    by 0x4136D2B: CloneImageInfo (in /usr/lib/libMagickCore.so.3.0.0)
==23540==    by 0x804B7D9: sendCacheImg (texgen.c:881)
==23540==    by 0x804BFBC: main (texgen.c:1053)
Here is my function :

Code: Select all

void            sendCacheImg(t_final_img *output)
{
  ImageInfo     *image_info;
  unsigned char *blob;
  size_t        size;
  ExceptionInfo *exception;

  write_header_http(output);
  image_info = CloneImageInfo(NULL);
  exception = AcquireExceptionInfo();
  strcpy(image_info->filename, cache_path);
  strcat(image_info->filename, output->name);
  output->image = ReadImage(image_info, exception);
  if (exception->severity != UndefinedException)
    fprintf(stderr, "[TEXGEN] Erreur dans le cache : %s\n", image_info);
  blob = ImageToBlob(image_info, output->image, &size, exception);
  fwrite(blob, 1, size, stdout);
  fflush(stdout);
  blob = xfree(blob);
  DestroyImage(output->image);
  DestroyImageInfo(image_info);
  DestroyExceptionInfo(exception);
}
I destroy my image, so is it a false-positive ?