Memory Management in JPEG to BMP conversion using Intel IJL Library

Iam using Intel IPP library for converting a JPEG to BMP. This function is in a VC++ dll and it is called from C#.  Iam passing a chunk of memory for this conversion to the unmanaged code.   Each time the JpegToBitmap function is called, the page file/memory usage keeps on increasing and crashes the application. How do i take care of this.

The call to the function looks like this.
C# Code
public unsafe static extern bool JpegToBitmap(
                                    byte *ipJpegPtr,
                  UInt32 ipJpegBufferSize,
                  byte *ipBitmapPtr,
                  int       *ipPtrBmpSize,
                  int destWidth,
                  int destHeight);

byte[] bmpBytes = new byte[1024 * 1024*5];
GCHandle gcbmpBytes  = GCHandle.Alloc(bmpBytes, GCHandleType.Pinned);
byte *bmpPtr = (byte *)gcbmpBytes.AddrOfPinnedObject().ToPointer();
int *ptrBmpSize = &bmpSize;
JpegToBitmap(jpegPtr, (uint)localImageBytes.Length, bmpPtr, ptrBmpSize, this.Width, this.Height);

The VC++ function which does the conversion
bool JpegToBitmap(
                                                                  BYTE *ipJpegPtr,
                                    DWORD ipJpegBufferSize,
                          BYTE *ipBitmapPtr,
                          int *ipPtrBmpSize,
                          int ipDestWidth,
                          int ipDestHeight) {

      int scaleFactor;

      IJLERR                              jerr;
      JPEG_CORE_PROPERTIES      jcprops;
      DWORD                              dwWholeImageSize;
      DWORD                              dib_line_width;
      DWORD                              dib_pad_bytes;

      IJLIOTYPE readMode;

      if(IJL_OK == (jerr = ijlInit(&jcprops))) {

            jcprops.JPGFile      = NULL;
            jcprops.JPGBytes     = ipJpegPtr;
            jcprops.JPGSizeBytes = ipJpegBufferSize;

            if(IJL_OK == (jerr = ijlRead(&jcprops, IJL_JBUFF_READPARAMS)))
                  switch(jcprops.JPGChannels) {
                        case 1:
                              jcprops.JPGColor = IJL_G;
                              jcprops.DIBColor = IJL_RGB;
                              jcprops.DIBChannels = 3;
                        } // case 1

                        case 3:
                              jcprops.JPGColor = IJL_YCBCR;
                              jcprops.DIBColor = IJL_RGB;
                              jcprops.DIBChannels = 3;
                        } // case 3

                              // This catches everything else, but no
                              // color twist will be performed by the IJL.
                              jcprops.JPGColor = IJL_OTHER;
                              jcprops.DIBColor = IJL_OTHER;
                              jcprops.DIBChannels = jcprops.JPGChannels;
                        } // default
                  } // switch

                  readMode = IJL_JBUFF_READWHOLEIMAGE;
                  scaleFactor = 1;

                  // Compute DIB padding
                  dib_line_width = jcprops.JPGWidth * 3;
                  dib_pad_bytes = IJL_DIB_PAD_BYTES(jcprops.JPGWidth /* / scaleFactor*/, 3);
                  dwWholeImageSize = ( dib_line_width + dib_pad_bytes ) * jcprops.JPGHeight /* / scaleFactor*/;

                  // Allocate memory to hold the decompressed image data.
                  if(1) {
                        // Set up the info on the desired DIB properties.
                        jcprops.DIBWidth = jcprops.JPGWidth /* / scaleFactor*/;
                        jcprops.DIBHeight = jcprops.JPGHeight /* / scaleFactor*/;
                        jcprops.DIBPadBytes = 0;
                        if(1) {
                              BITMAPINFOHEADER*      memBMIH;
                              BITMAPFILEHEADER*      memBMFH;

                              memBMFH = reinterpret_cast<BITMAPFILEHEADER*>(ipBitmapPtr);
                              memBMFH->bfType      = 'MB';
                              memBMFH->bfSize      = dwWholeImageSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
                              memBMFH->bfReserved1 = 0;
                              memBMFH->bfReserved2 = 0;
                              memBMFH->bfOffBits   = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

                              memBMIH = reinterpret_cast<BITMAPINFOHEADER*>(ipBitmapPtr + sizeof(BITMAPFILEHEADER));
                              memBMIH->biSize = sizeof(BITMAPINFOHEADER);
                              memBMIH->biWidth = jcprops.JPGWidth /* / scaleFactor*/;
                              memBMIH->biHeight = -jcprops.JPGHeight /* / scaleFactor*/;
                              memBMIH->biPlanes = 1;

                              memBMIH->biBitCount = 24;
                              memBMIH->biCompression = BI_RGB;
                              memBMIH->biSizeImage = 0;
                              memBMIH->biXPelsPerMeter = 0;
                              memBMIH->biYPelsPerMeter = 0;
                              memBMIH->biClrUsed = 0;
                              memBMIH->biClrImportant = 0;                                    

                              // Set up the info on the desired DIB properties.
                              jcprops.DIBWidth = jcprops.JPGWidth /* / scaleFactor*/;
                              jcprops.DIBHeight = jcprops.JPGHeight /* / scaleFactor*/; // Implies a bottom-up DIB.
                              jcprops.DIBChannels = 3;
                              jcprops.DIBColor = IJL_BGR;
                              jcprops.DIBPadBytes = dib_pad_bytes;
                              jcprops.DIBBytes = reinterpret_cast<BYTE*>(ipBitmapPtr + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));

                              if(IJL_OK == (jerr = ijlRead(&jcprops, readMode)))
                                    *ipPtrBmpSize = memBMFH->bfSize;
                              } // ijlread whole image
                        }// create compatible DC
                              //logerror("create Compatible DC failed");
                        } // else create compatible dc
                  } // else lptemp create
            } // ijl read params
            ijlFree( & jcprops);
      return true;


Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

First try this function with unmanaged C++ client.
Bob LearnedCommented:
Is there a reason why you can just convert a Bitmap to JPEG natively:

public class Graphics_Library
public enum ImageType

 public static void ConvertImage(string file, ImageType type)
   Image imageCurrent = Image.FromFile(file);
   Imaging.ImageFormat format;
   if (type == ImageType.Bmp)
     format = Imaging.ImageFormat.Bmp;
   } else if (type == ImageType.Emf) {
     format = Imaging.ImageFormat.Emf;
   } else if (type == ImageType.Exif) {
     format = Imaging.ImageFormat.Exif;
   } else if (type == ImageType.Gif) {
     format = Imaging.ImageFormat.Gif;
   } else if (type == ImageType.Jpg) {
     format = Imaging.ImageFormat.Jpeg;
   } else if (type == ImageType.Png) {
     format = Imaging.ImageFormat.Png;
   } else if (type == ImageType.Tiff) {
     format = Imaging.ImageFormat.Tiff;
   } else if (type == ImageType.Wmf) {
     format = Imaging.ImageFormat.Wmf;
   string fileName = Path.GetFileNameWithoutExtension(file);
   string filePath = Path.GetDirectoryName(file);
   file = Path.Combine(filePath, fileName) + "." + type.ToString.ToLower;
   imageCurrent.Save(file, format);


sendhil_anAuthor Commented:
yeah, i could convert JPEG to BMP without using native code. But it takes more CPU to perform the operation. I need to do this conversion many times a second and there will be multiple instances of it. Intel JPEG library has been optimized to do it.

I will try the function from an  unmanged C++ client

If your unmanaged test will be successful, post here unmanaged C++ code which calls JpegToBitmap function. Having working unmanaged version it is always possible to translate it to C#.

Loking at your code now, I wonder what is ipJpegPtr which is passed directly to JpegToBitmap?
int *ptrBmpSize = &bmpSize;
looks strange. You need ref parameter instead of it. There is no need in unsafe prigramming. Be careful with bool return type. It is char in MS VC++ and can have other size in other compilers. It's better to use int.

int JpegToBitmap(BYTE *ipJpegPtr, DWORD ipJpegBufferSize, BYTE *ipBitmapPtr, int *ipPtrBmpSize, int ipDestWidth, int ipDestHeight)

should be translated to C# as:

public static extern int JpegToBitmap(IntPtr ipJpegPtr, Int32 ipJpegBufferSize, IntPtr ipBitmapPtr, ref int BmpSize, int destWidth, int destHeight);


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Fonts Typography

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.