1 Reply Latest reply on Apr 10, 2009 9:14 AM by noemata

    Intel IPP crashes, see code comments below.

    noemata

      // Look for comments with !!! and ???

      // Authored By: Mario Pintaric

       

      // ippTest.cpp : Defines the entry point for the console application.

      //

       

      #include"stdafx.h"

       

      #include<windows.h>

      #include<comdef.h>

      #include<gdiplus.h>

       

      #pragmacomment(lib, "gdiplus")

       

      #include"ipp.h"

       

      #pragmacomment(lib, "ippcore.lib")

      #pragmacomment(lib, "ippi.lib")

       

      usingnamespace Gdiplus;

       

      classGdiplusInit  

      {

      public:  

            GdiplusInit()  

            {

                  GdiplusStartup(&gdiplusToken,   &gdiplusStartupInput,   NULL);  

            }  

            ~GdiplusInit()  

            {

                  GdiplusShutdown(gdiplusToken);  

            }  

      protected:  

      private:  

            GdiplusStartupInput gdiplusStartupInput;  

            ULONG_PTR gdiplusToken;  

      };  

       

      GdiplusInit InitGDIPlus;

       

      Bitmap *imgPage1Big;

       

      voidResizeBitmap(Bitmap **bmpInput, int newWidth, int newHeight)

      {

           Bitmap *bmpTemp=(*bmpInput)->Clone(0, 0, newWidth, newHeight, PixelFormat32bppRGB);

           delete *bmpInput;

           *bmpInput = bmpTemp;

      }

       

      intGetEncoderClsid(const WCHAR* format, CLSID* pClsid)

      {

         UINT   num = 0;               // number of image encoders

         UINT   size = 0;            // size of the image encoder array

                                             // in bytes

         Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;

       

         Gdiplus::GetImageEncodersSize(&num, &size);

         if(size == 0)

            return -1;

       

         pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));

         if(pImageCodecInfo == NULL)

            return -1;

       

         GetImageEncoders(num, size, pImageCodecInfo);

       

         for(UINT j = 0; j < num; ++j)

         {

            if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )

            {

               *pClsid = pImageCodecInfo[j].Clsid;

               free(pImageCodecInfo);

               return j;   // Success

            }

         }

       

         free(pImageCodecInfo);

         return -1;

      }

       

      IppStatus GaussBmp(Ipp8u *pSrc, IppiSize srcSize, int nChannels, IppiMaskSize op)

      {

            int nPad, step;

            IppiSize padSize, fltSize;

            Ipp8u *pad, *flt;

            IppStatus status = ippStsNoMemErr;

       

            // Set mask operation.  Intel IPP docs do not provide an adequate explanation of border value condition hadling.

            // Overall, the docs are riddled with mistakes, poor grammar and incomplete explanations.

            if ( op == ippMskSize3x3 )

            {

                  nPad = 4;

            }

            else if ( op == ippMskSize5x5 )

            {

                  nPad = 8;

            }

            else

                  return ippStsNotSupportedModeErr;

       

            // Calculate padded and filtered bitmap sizes.

            padSize.width  = fltSize.width  = srcSize.width  + (2 * nPad);

            padSize.height = fltSize.height = srcSize.height + (2 * nPad);

       

            // Allocate padded bitmap that will contain replicated border of source bitmap and corresponding filter target bitmap.

            if (nChannels == 1)

            {

                  pad = ippiMalloc_8u_C1(padSize.width, padSize.height, &step);

                  if ( !pad )

                        goto Fault;

                  flt = ippiMalloc_8u_C1(fltSize.width, fltSize.height, &step);

                  if ( !flt )

                        goto Fault;

            }

            else if (nChannels == 3)

            {

                  pad = ippiMalloc_8u_C3(padSize.width, padSize.height, &step);

                  if ( !pad )

                        goto Fault;

                  flt = ippiMalloc_8u_C3(fltSize.width, fltSize.height, &step);

                  if ( !flt )

                        goto Fault;

            }

            else if (nChannels == 4)

            {

                  pad = ippiMalloc_8u_C4(padSize.width, padSize.height, &step);

                  if ( !pad )

                        goto Fault;

                  flt = ippiMalloc_8u_C4(fltSize.width, fltSize.height, &step);

                  if ( !flt )

                        goto Fault;

            }

            else

                  return ippStsNotSupportedModeErr;

       

            // Note: Intel IPP seems to incorrectly caclulate the step value!!!  Why???

            step = padSize.width * nChannels;

       

            if (nChannels == 1)

            {

                  status = ippiCopyReplicateBorder_8u_C1R(pSrc, srcSize.width * nChannels, srcSize, pad, step, padSize, nPad, nPad);

            }

            else if (nChannels == 3)

            {

                  status = ippiCopyReplicateBorder_8u_C3R(pSrc, srcSize.width * nChannels, srcSize, pad, step, padSize, nPad, nPad);

            }

            else if (nChannels == 4)

            {

                  status = ippiCopyReplicateBorder_8u_C4R(pSrc, srcSize.width * nChannels, srcSize, pad, step, padSize, nPad, nPad);

            }

       

            if ( status )

                  goto Fault;

       

            // Depending on image size, Intel IPP crashes here!!!  Why???  Crashes are also random, in other words, not every time!!!!!

            if (nChannels == 1)

            {

                  status = ippiFilterGauss_8u_C1R(pad, step, flt, step, fltSize, op);

            }

            else if (nChannels == 3)

            {

                  status = ippiFilterGauss_8u_C3R(pad, step, flt, step, fltSize, op);

            }

            else if (nChannels == 4)

            {

                  status = ippiFilterGauss_8u_C4R(pad, step, flt, step, fltSize, op);

            }

       

            if ( status )

                  goto Fault;

       

            // Copy filtered bitmap back to source.  We need to set the row and colomn of filtered

            // bitmap so that it starts at the offset that corresponds to the border padding value.

            status = ippiCopy_8u_C1R(&flt[(fltSize.width * nPad * nChannels) + (nPad * nChannels)], step, pSrc, srcSize.width * nChannels, srcSize);

       

      Fault:

            if ( pad )

                  ippiFree(pad);

            if ( flt )

                  ippiFree(flt);

       

            return status;

      }

       

      int_tmain(int argc, _TCHAR* argv[])

      {

            const IppLibraryVersion* ippVersion = ippiGetLibVersion();

       

            printf("IPP: [ %s %s ]", ippVersion->Name, ippVersion->Version);

       

            Bitmap inBmp(L"bg.bmp");

       

            if ( inBmp.GetLastStatus() == Ok )

            {

                  PixelFormat fmt = inBmp.GetPixelFormat();

       

                  if ( PixelFormat24bppRGB == fmt )

                  {

                        BitmapData InData, growData, shrinkData;

       

                        int growwidth = inBmp.GetWidth() * 4;

                        int growheight = inBmp.GetHeight() * 4;

       

                        int shrinkwidth = growwidth / 8;

                        int shrinkheight = growheight / 8;

       

                        Bitmap growBmp(growwidth, growheight, PixelFormat24bppRGB);

                        Bitmap shrinkBmp(shrinkwidth, shrinkheight, PixelFormat24bppRGB);

       

                        inBmp.LockBits(0, ImageLockModeRead, PixelFormat24bppRGB, &InData);

                        growBmp.LockBits(0, ImageLockModeWrite, PixelFormat24bppRGB, &growData);

                        shrinkBmp.LockBits(0, ImageLockModeWrite, PixelFormat24bppRGB, &shrinkData);

       

                        IppStatus status1, status2;

                  IppiSize inSize  = { inBmp.GetWidth(), inBmp.GetHeight() };

                  IppiRect inRect  = { 0, 0, inBmp.GetWidth(), inBmp.GetHeight() };

                  IppiSize shrinkSize = { shrinkwidth, shrinkheight };

                  IppiRect shrinkRect = { 0, 0, shrinkwidth, shrinkheight };

                  IppiSize growSize = { growwidth, growheight };

                  IppiRect growRect = { 0, 0, growwidth, growheight };

       

                        double xgrowFactor = growwidth  / (double)inBmp.GetWidth();

                  double ygrowFactor = growheight / (double)inBmp.GetHeight();

                        double xshrinkFactor = shrinkwidth  / (double)growwidth;

                  double yshrinkFactor = shrinkheight / (double)growheight;

                  double xShift = 0.0;

                  double yShift = 0.0;

                  int    nChannel = 3;

       

                        int   bufferSize;

                        Ipp8u *pshrinkBuffer, *pgrowBuffer;

       

                        // IPPI_INTER_NN

                        // IPPI_INTER_LINEAR

                        // IPPI_INTER_CUBIC

                        // IPPI_INTER_CUBIC2P_BSPLINE

                        // IPPI_INTER_CUBIC2P_CATMULLROM

                        // IPPI_INTER_CUBIC2P_B05C03

                        // IPPI_INTER_SUPER

                        // IPPI_INTER_LANCZOS

                        int interpolation = IPPI_INTER_LANCZOS;

       

                        //ippiResizeGetBufSize(inRect, outshrinkRect, 3, interpolation, &bufferSize);

       

                  status1 = ippiResizeSqrPixelGetBufSize(shrinkSize, nChannel, interpolation, &bufferSize);

       

                  pshrinkBuffer = (Ipp8u *)ippMalloc(bufferSize);

       

                  status1 = ippiResizeSqrPixelGetBufSize(growSize, nChannel, interpolation, &bufferSize);

       

                  pgrowBuffer = (Ipp8u *)ippMalloc(bufferSize);

       

                        status2 = ippiResizeSqrPixel_8u_C3R((Ipp8u*)InData.Scan0, inSize, inBmp.GetWidth() * nChannel, inRect, (Ipp8u*)growData.Scan0, growwidth * nChannel, growRect, xgrowFactor, ygrowFactor, 0, 0, interpolation, pgrowBuffer);

       

                        status2 = GaussBmp((Ipp8u*)growData.Scan0, growSize, nChannel, ippMskSize5x5);

                        status2 = GaussBmp((Ipp8u*)growData.Scan0, growSize, nChannel, ippMskSize5x5);

       

                        status2 = ippiResizeSqrPixel_8u_C3R((Ipp8u*)growData.Scan0, growSize, growBmp.GetWidth() * nChannel, growRect, (Ipp8u*)shrinkData.Scan0, shrinkwidth * nChannel, shrinkRect, xshrinkFactor, yshrinkFactor, 0, 0, interpolation, pshrinkBuffer);

       

                        ippFree(pshrinkBuffer);

                        ippFree(pgrowBuffer);

       

                        inBmp.UnlockBits(&InData);

                        growBmp.UnlockBits(&growData);

                        shrinkBmp.UnlockBits(&shrinkData);

       

                        if ( status2 == ippStsNoErr )

                        {

                              CLSID clsidBMP;

       

                              GetEncoderClsid(L"image/bmp", &clsidBMP);

       

                              growBmp.Save(L"grow.bmp", &clsidBMP);

                              shrinkBmp.Save(L"shrink.bmp", &clsidBMP);

                        }

                  }

            }

       

            //imgPage1Big = new Bitmap(500, 500, PixelFormat32bppRGB);

          //ResizeBitmap(&imgPage1Big, 300, 300);

          //delete imgPage1Big;

       

            return 0;

      }

       

       

        • 1. Revised code does not crash, but the changes required are spooky.
          noemata

          // Authored by: Mario Pintaric

           

          // ippTest.cpp : Defines the entry point for the console application.

          //

           

          #include"stdafx.h"

           

          #include<windows.h>

          #include<comdef.h>

          #include<gdiplus.h>

           

          #pragmacomment(lib, "gdiplus")

           

          #include"ipp.h"

           

          #pragmacomment(lib, "ippcore.lib")

          #pragmacomment(lib, "ippi.lib")

           

          usingnamespace Gdiplus;

           

          classGdiplusInit  

          {

          public:  

                GdiplusInit()  

                {

                      GdiplusStartup(&gdiplusToken,   &gdiplusStartupInput,   NULL);  

                }  

                ~GdiplusInit()  

                {

                      GdiplusShutdown(gdiplusToken);  

                }  

          protected:  

          private:  

                GdiplusStartupInput gdiplusStartupInput;  

                ULONG_PTR gdiplusToken;  

          };  

           

          GdiplusInit InitGDIPlus;

           

          Bitmap *imgPage1Big;

           

          voidResizeBitmap(Bitmap **bmpInput, int newWidth, int newHeight)

          {

               Bitmap *bmpTemp=(*bmpInput)->Clone(0, 0, newWidth, newHeight, PixelFormat32bppRGB);

               delete *bmpInput;

               *bmpInput = bmpTemp;

          }

           

          intGetEncoderClsid(const WCHAR* format, CLSID* pClsid)

          {

             UINT   num = 0;               // number of image encoders

             UINT   size = 0;            // size of the image encoder array

                                                 // in bytes

             Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;

           

             Gdiplus::GetImageEncodersSize(&num, &size);

             if(size == 0)

                return -1;

           

             pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));

             if(pImageCodecInfo == NULL)

                return -1;

           

             GetImageEncoders(num, size, pImageCodecInfo);

           

             for(UINT j = 0; j < num; ++j)

             {

                if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )

                {

                   *pClsid = pImageCodecInfo[j].Clsid;

                   free(pImageCodecInfo);

                   return j;   // Success

                }

             }

           

             free(pImageCodecInfo);

             return -1;

          }

           

          IppStatus GaussBmp(Ipp8u *pSrc, IppiSize srcSize, int nChannels, IppiMaskSize op)

          {

                int nPad, step;

                IppiSize padSize, fltSize;

                Ipp8u *pad, *flt;

                IppStatus status = ippStsNoMemErr;

           

                // Set mask operation.  Intel IPP docs do not provide an adequate explanation of border value condition handling.

                // Overall, the docs are riddled with mistakes, poor grammar and incomplete explanations.

                if ( op == ippMskSize3x3 )

                {

                      nPad = 4;

                }

                else if ( op == ippMskSize5x5 )

                {

                      nPad = 8; // Crashes when set to 5.  Why???

                }

                else

                      return ippStsNotSupportedModeErr;

           

                // Calculate padded and filtered bitmap sizes.

                padSize.width  = fltSize.width  = srcSize.width  + (2 * nPad);

                padSize.height = fltSize.height = srcSize.height + (2 * nPad);

           

                // Allocate padded bitmap that will contain replicated border of source bitmap and corresponding filter target bitmap.

                if (nChannels == 1)

                {

                      pad = ippiMalloc_8u_C1(padSize.width, padSize.height, &step);

                      if ( !pad )

                            goto Fault;

                      flt = ippiMalloc_8u_C1(fltSize.width, fltSize.height, &step);

                      if ( !flt )

                            goto Fault;

                }

                else if (nChannels == 3)

                {

                      pad = ippiMalloc_8u_C3(padSize.width, padSize.height, &step);

                      if ( !pad )

                            goto Fault;

                      flt = ippiMalloc_8u_C3(fltSize.width, fltSize.height, &step);

                      if ( !flt )

                            goto Fault;

                }

                else if (nChannels == 4)

                {

                      pad = ippiMalloc_8u_C4(padSize.width, padSize.height, &step);

                      if ( !pad )

                            goto Fault;

                      flt = ippiMalloc_8u_C4(fltSize.width, fltSize.height, &step);

                      if ( !flt )

                            goto Fault;

                }

                else

                      return ippStsNotSupportedModeErr;

           

                // Note: Intel IPP seems to incorrectly caclulate the step value!!!  Why???

                step = padSize.width * nChannels;

           

                if (nChannels == 1)

                {

                      status = ippiCopyReplicateBorder_8u_C1R(pSrc, srcSize.width * nChannels, srcSize, pad, step, padSize, nPad, nPad);

                }

                else if (nChannels == 3)

                {

                      status = ippiCopyReplicateBorder_8u_C3R(pSrc, srcSize.width * nChannels, srcSize, pad, step, padSize, nPad, nPad);

                }

                else if (nChannels == 4)

                {

                      status = ippiCopyReplicateBorder_8u_C4R(pSrc, srcSize.width * nChannels, srcSize, pad, step, padSize, nPad, nPad);

                }

           

                if ( status )

                      goto Fault;

           

                // If we do not increase value of buffersize calculated by ippiResizeSqrPixelGetBufSize, we crash ...

                // Depending on image size, Intel IPP crashes here!!!  Why???  Crashes are also random, in other words, not every time for same operation!!!!!

                if (nChannels == 1)

                {

                      status = ippiFilterGauss_8u_C1R(pad, step, flt, step, fltSize, op);

                }

                else if (nChannels == 3)

                {

                      status = ippiFilterGauss_8u_C3R(pad, step, flt, step, fltSize, op);

                }

                else if (nChannels == 4)

                {

                      status = ippiFilterGauss_8u_C4R(pad, step, flt, step, fltSize, op);

                }

           

                if ( status )

                      goto Fault;

           

                // Copy filtered bitmap back to source.  We need to set the row and colomn of the filtered

                // bitmap so that it starts at the offset that corresponds to our border padding value.

                if (nChannels == 1)

                {

                      status = ippiCopy_8u_C1R(&flt[(fltSize.width * nPad * nChannels) + (nPad * nChannels)], step, pSrc, srcSize.width * nChannels, srcSize);

                }

                else if (nChannels == 3)

                {

                      status = ippiCopy_8u_C3R(&flt[(fltSize.width * nPad * nChannels) + (nPad * nChannels)], step, pSrc, srcSize.width * nChannels, srcSize);

                }

                else if (nChannels == 4)

                {

                      status = ippiCopy_8u_C4R(&flt[(fltSize.width * nPad * nChannels) + (nPad * nChannels)], step, pSrc, srcSize.width * nChannels, srcSize);

                }

           

          Fault:

                if ( pad )

                      ippiFree(pad);

                if ( flt )

                      ippiFree(flt);

           

                return status;

          }

           

          int_tmain(int argc, _TCHAR* argv[])

          {

                const IppLibraryVersion* ippVersion = ippiGetLibVersion();

           

                printf("IPP: [ %s %s ]\n", ippVersion->Name, ippVersion->Version);

           

                Bitmap inBmp(L"bg.bmp");

           

                if ( inBmp.GetLastStatus() == Ok )

                {

                      PixelFormat fmt = inBmp.GetPixelFormat();

           

                      if ( PixelFormat24bppRGB == fmt )

                      {

                            BitmapData InData, growData, shrinkData;

           

                            int growwidth = inBmp.GetWidth() * 4;

                            int growheight = inBmp.GetHeight() * 4;

           

                            int shrinkwidth = growwidth / 8;

                            int shrinkheight = growheight / 8;

           

                            Bitmap growBmp(growwidth, growheight, PixelFormat24bppRGB);

                            Bitmap shrinkBmp(shrinkwidth, shrinkheight, PixelFormat24bppRGB);

           

                            inBmp.LockBits(0, ImageLockModeRead, PixelFormat24bppRGB, &InData);

                            growBmp.LockBits(0, ImageLockModeWrite, PixelFormat24bppRGB, &growData);

                            shrinkBmp.LockBits(0, ImageLockModeWrite, PixelFormat24bppRGB, &shrinkData);

           

                            IppStatus status;

                      IppiSize inSize  = { inBmp.GetWidth(), inBmp.GetHeight() };

                      IppiRect inRect  = { 0, 0, inBmp.GetWidth(), inBmp.GetHeight() };

                      IppiSize shrinkSize = { shrinkwidth, shrinkheight };

                      IppiRect shrinkRect = { 0, 0, shrinkwidth, shrinkheight };

                      IppiSize growSize = { growwidth, growheight };

                      IppiRect growRect = { 0, 0, growwidth, growheight };

           

                            double xgrowFactor = growwidth  / (double)inBmp.GetWidth();

                      double ygrowFactor = growheight / (double)inBmp.GetHeight();

                            double xshrinkFactor = shrinkwidth  / (double)growwidth;

                      double yshrinkFactor = shrinkheight / (double)growheight;

                      double xShift = 0.0;

                      double yShift = 0.0;

                      int    nChannel = 3;

           

                            int   bufferSize = 0;

                            Ipp8u *pshrinkBuffer = NULL, *pgrowBuffer = NULL;

           

                            // IPPI_INTER_NN

                            // IPPI_INTER_LINEAR

                            // IPPI_INTER_CUBIC

                            // IPPI_INTER_CUBIC2P_BSPLINE

                            // IPPI_INTER_CUBIC2P_CATMULLROM

                            // IPPI_INTER_CUBIC2P_B05C03

                            // IPPI_INTER_SUPER

                            // IPPI_INTER_LANCZOS

                            int interpolation = IPPI_INTER_LANCZOS;

           

                            // Note: docs imply IPPI_INTER_SUPER is supported by ippiResizeSqrPixel, but it is not???

                      status = ippiResizeSqrPixelGetBufSize(shrinkSize, nChannel, interpolation, &bufferSize);

           

                            if ( status )

                                  goto Fault;

           

                            // Note: increasing bufferSize resolves crash problem, why???

                      pshrinkBuffer = (Ipp8u *)ippMalloc(bufferSize * 2);

           

                            if ( !pshrinkBuffer )

                                  goto Fault;

           

                      status = ippiResizeSqrPixelGetBufSize(growSize, nChannel, interpolation, &bufferSize);

           

                            if ( status )

                                  goto Fault;

           

                            // Note: increasing bufferSize resolves crash problem, why???

                      pgrowBuffer = (Ipp8u *)ippMalloc(bufferSize * 2);

           

                            // Guess: just as with step size, bufferSize is probably not caclulated correctly.

           

                            if ( !pgrowBuffer )

                                  goto Fault;

           

                            status = ippiResizeSqrPixel_8u_C3R((Ipp8u*)InData.Scan0, inSize, inBmp.GetWidth() * nChannel, inRect, (Ipp8u*)growData.Scan0, growwidth * nChannel, growRect, xgrowFactor, ygrowFactor, 0, 0, interpolation, pgrowBuffer);

           

                            if ( status )

                                  goto Fault;

           

                            status = GaussBmp((Ipp8u*)growData.Scan0, growSize, nChannel, ippMskSize5x5);

           

                            if ( status )

                                  goto Fault;

           

                            status = GaussBmp((Ipp8u*)growData.Scan0, growSize, nChannel, ippMskSize5x5);

           

                            if ( status )

                                  goto Fault;

           

                            status = ippiResizeSqrPixel_8u_C3R((Ipp8u*)growData.Scan0, growSize, growBmp.GetWidth() * nChannel, growRect, (Ipp8u*)shrinkData.Scan0, shrinkwidth * nChannel, shrinkRect, xshrinkFactor, yshrinkFactor, 0, 0, interpolation, pshrinkBuffer);

           

          Fault:

                            if ( status == ippStsInterpolationErr )

                                  printf("Invalid interpolation mode!\n");

           

                            if ( pshrinkBuffer )

                                  ippFree(pshrinkBuffer);

           

                            if ( pgrowBuffer )

                                  ippFree(pgrowBuffer);

           

                            inBmp.UnlockBits(&InData);

                            growBmp.UnlockBits(&growData);

                            shrinkBmp.UnlockBits(&shrinkData);

           

                            if ( status == ippStsNoErr )

                            {

                                  CLSID clsidBMP;

           

                                  GetEncoderClsid(L"image/bmp", &clsidBMP);

           

                                  growBmp.Save(L"grow.bmp", &clsidBMP);

                                  shrinkBmp.Save(L"shrink.bmp", &clsidBMP);

                            }

                      }

                }

           

                return 0;

          }