|
SVN commit 1196146 by cgilles:
Andy, this is not understadable. All CImg::*blur() method crash under MacOsX. and i don't know why... Probably, this is fixed with last CImg 1.4.x release, as digiKam still use 1.3.0... but we cannot update because all Greystoration algorithm have been removed from CImg and migrated to GMic library The solution is to port greystoration code to GMic, as it have been recommended by CImg author in the past by a private mail. But it's a long and complex task. Note : Greystoration tools do not crash under MAC Os X !!! I'm lost... So, I restore old gaussian blur algorithm for Mac only... CCMAIL: [hidden email] M +266 -3 blurfilter.cpp M +35 -1 blurfilter.h --- trunk/extragear/graphics/digikam/libs/dimg/filters/fx/blurfilter.cpp #1196145:1196146 @@ -66,13 +66,16 @@ void BlurFilter::filterImage() { +#if defined(__MACOSX__) || defined(__APPLE__) gaussianBlurImage(m_orgImage.bits(), m_orgImage.width(), m_orgImage.height(), + m_orgImage.sixteenBit(), (int)(m_radius*10.0)); +#else + cimgBlurImage(m_orgImage.bits(), m_orgImage.width(), m_orgImage.height(), m_orgImage.sixteenBit(), m_radius); +#endif } -/** Function to apply the Gaussian Blur on an image. - */ -void BlurFilter::gaussianBlurImage(uchar* data, int width, int height, bool sixteenBit, double radius) +void BlurFilter::cimgBlurImage(uchar* data, int width, int height, bool sixteenBit, double radius) { if (!data || !width || !height) { @@ -143,4 +146,264 @@ } } +void BlurFilter::gaussianBlurImage(uchar* data, int width, int height, bool sixteenBit, int radius) +{ + if (!data || !width || !height) + { + kWarning(50003) << ("DImgGaussianBlur::gaussianBlurImage: no image data available!") << endl; + return; + } + + if (radius > 100) radius = 100; + if (radius <= 0) + { + m_destImage = m_orgImage; + return; + } + + // Gaussian kernel computation using the Radius parameter. + + int nKSize, nCenter; + double x, sd, factor, lnsd, lnfactor; + register int i, j, n, h, w; + + nKSize = 2 * radius + 1; + nCenter = nKSize / 2; + int *Kernel = new int[nKSize]; + + lnfactor = (4.2485 - 2.7081) / 10 * nKSize + 2.7081; + lnsd = (0.5878 + 0.5447) / 10 * nKSize - 0.5447; + factor = exp (lnfactor); + sd = exp (lnsd); + + for (i = 0; !runningFlag() && (i < nKSize); ++i) + { + x = sqrt ((i - nCenter) * (i - nCenter)); + Kernel[i] = (int)(factor * exp (-0.5 * pow ((x / sd), 2)) / (sd * sqrt (2.0 * M_PI))); + } + + // Now, we need to convolve the image descriptor. + // I've worked hard here, but I think this is a very smart + // way to convolve an array, its very hard to explain how I reach + // this, but the trick here its to store the sum used by the + // previous pixel, so we sum with the other pixels that wasn't get. + + int nSumA, nSumR, nSumG, nSumB, nCount, progress; + int nKernelWidth = radius * 2 + 1; + + // We need to alloc a 2d array to help us to store the values + + int** arrMult = Alloc2DArray (nKernelWidth, sixteenBit ? 65536 : 256); + + for (i = 0; !runningFlag() && (i < nKernelWidth); ++i) + for (j = 0; !runningFlag() && (j < (sixteenBit ? 65536 : 256)); ++j) + arrMult[i][j] = j * Kernel[i]; + + // We need to copy our bits to blur bits + + uchar* pOutBits = m_destImage.bits(); + uchar* pBlur = new uchar[m_destImage.numBytes()]; + + memcpy (pBlur, data, m_destImage.numBytes()); + + // We need to initialize all the loop and iterator variables + + nSumA = nSumR = nSumG = nSumB = nCount = i = j = 0; + unsigned short* data16 = (unsigned short*)data; + unsigned short* pBlur16 = (unsigned short*)pBlur; + unsigned short* pOutBits16 = (unsigned short*)pOutBits; + + // Now, we enter in the main loop + + for (h = 0; !runningFlag() && (h < height); ++h) + { + for (w = 0; !runningFlag() && (w < width); ++w, i+=4) + { + if (!sixteenBit) // 8 bits image. + { + uchar *org, *dst; + + // first of all, we need to blur the horizontal lines + + for (n = -radius; !runningFlag() && (n <= radius); ++n) + { + // if is inside... + if (IsInside (width, height, w + n, h)) + { + // we points to the pixel + j = i + 4*n; + + // finally, we sum the pixels using a method similar to assigntables + + org = &data[j]; + nSumA += arrMult[n + radius][org[3]]; + nSumR += arrMult[n + radius][org[2]]; + nSumG += arrMult[n + radius][org[1]]; + nSumB += arrMult[n + radius][org[0]]; + + // we need to add to the counter, the kernel value + nCount += Kernel[n + radius]; + } + } + + if (nCount == 0) nCount = 1; + + // now, we return to blur bits the horizontal blur values + dst = &pBlur[i]; + dst[3] = (uchar)CLAMP (nSumA / nCount, 0, 255); + dst[2] = (uchar)CLAMP (nSumR / nCount, 0, 255); + dst[1] = (uchar)CLAMP (nSumG / nCount, 0, 255); + dst[0] = (uchar)CLAMP (nSumB / nCount, 0, 255); + + // ok, now we reinitialize the variables + nSumA = nSumR = nSumG = nSumB = nCount = 0; + } + else // 16 bits image. + { + unsigned short *org, *dst; + + // first of all, we need to blur the horizontal lines + + for (n = -radius; !runningFlag() && (n <= radius); ++n) + { + // if is inside... + if (IsInside (width, height, w + n, h)) + { + // we points to the pixel + j = i + 4*n; + + // finally, we sum the pixels using a method similar to assigntables + + org = &data16[j]; + nSumA += arrMult[n + radius][org[3]]; + nSumR += arrMult[n + radius][org[2]]; + nSumG += arrMult[n + radius][org[1]]; + nSumB += arrMult[n + radius][org[0]]; + + // we need to add to the counter, the kernel value + nCount += Kernel[n + radius]; + } + } + + if (nCount == 0) nCount = 1; + + // now, we return to blur bits the horizontal blur values + dst = &pBlur16[i]; + dst[3] = (unsigned short)CLAMP (nSumA / nCount, 0, 65535); + dst[2] = (unsigned short)CLAMP (nSumR / nCount, 0, 65535); + dst[1] = (unsigned short)CLAMP (nSumG / nCount, 0, 65535); + dst[0] = (unsigned short)CLAMP (nSumB / nCount, 0, 65535); + + // ok, now we reinitialize the variables + nSumA = nSumR = nSumG = nSumB = nCount = 0; + } + } + + progress = (int) (((double)h * 50.0) / height); + if ( progress%5 == 0 ) + postProgress( progress ); + } + + // getting the blur bits, we initialize position variables + i = j = 0; + + // We enter in the second main loop + for (w = 0; !runningFlag() && (w < width); ++w, i = w*4) + { + for (h = 0; !runningFlag() && (h < height); ++h, i += width*4) + { + if (!sixteenBit) // 8 bits image. + { + uchar *org, *dst; + + // first of all, we need to blur the vertical lines + for (n = -radius; !runningFlag() && (n <= radius); ++n) + { + // if is inside... + if (IsInside(width, height, w, h + n)) + { + // we points to the pixel + j = i + n * 4 * width; + + // finally, we sum the pixels using a method similar to assigntables + org = &pBlur[j]; + nSumA += arrMult[n + radius][org[3]]; + nSumR += arrMult[n + radius][org[2]]; + nSumG += arrMult[n + radius][org[1]]; + nSumB += arrMult[n + radius][org[0]]; + + // we need to add to the counter, the kernel value + nCount += Kernel[n + radius]; + } + } + + if (nCount == 0) nCount = 1; + + // To preserve Alpha channel. + memcpy (&pOutBits[i], &data[i], 4); + + // now, we return to bits the vertical blur values + dst = &pOutBits[i]; + dst[3] = (uchar)CLAMP (nSumA / nCount, 0, 255); + dst[2] = (uchar)CLAMP (nSumR / nCount, 0, 255); + dst[1] = (uchar)CLAMP (nSumG / nCount, 0, 255); + dst[0] = (uchar)CLAMP (nSumB / nCount, 0, 255); + + // ok, now we reinitialize the variables + nSumA = nSumR = nSumG = nSumB = nCount = 0; + } + else // 16 bits image. + { + unsigned short *org, *dst; + + // first of all, we need to blur the vertical lines + for (n = -radius; !runningFlag() && (n <= radius); ++n) + { + // if is inside... + if (IsInside(width, height, w, h + n)) + { + // we points to the pixel + j = i + n * 4 * width; + + // finally, we sum the pixels using a method similar to assigntables + org = &pBlur16[j]; + nSumA += arrMult[n + radius][org[3]]; + nSumR += arrMult[n + radius][org[2]]; + nSumG += arrMult[n + radius][org[1]]; + nSumB += arrMult[n + radius][org[0]]; + + // we need to add to the counter, the kernel value + nCount += Kernel[n + radius]; + } + } + + if (nCount == 0) nCount = 1; + + // To preserve Alpha channel. + memcpy (&pOutBits16[i], &data16[i], 8); + + // now, we return to bits the vertical blur values + dst = &pOutBits16[i]; + dst[3] = (unsigned short)CLAMP (nSumA / nCount, 0, 65535); + dst[2] = (unsigned short)CLAMP (nSumR / nCount, 0, 65535); + dst[1] = (unsigned short)CLAMP (nSumG / nCount, 0, 65535); + dst[0] = (unsigned short)CLAMP (nSumB / nCount, 0, 65535); + + // ok, now we reinitialize the variables + nSumA = nSumR = nSumG = nSumB = nCount = 0; + } + } + + progress = (int) (50.0 + ((double)w * 50.0) / width); + if ( progress%5 == 0 ) + postProgress( progress ); + } + + // now, we must free memory + Free2DArray (arrMult, nKernelWidth); + delete [] pBlur; + delete [] Kernel; +} + + } // namespace Digikam --- trunk/extragear/graphics/digikam/libs/dimg/filters/fx/blurfilter.h #1196145:1196146 @@ -50,8 +50,42 @@ private: void filterImage(); - void gaussianBlurImage(uchar* data, int width, int height, bool sixteenBit, double radius); + void cimgBlurImage(uchar* data, int width, int height, bool sixteenBit, double radius); + void gaussianBlurImage(uchar* data, int width, int height, bool sixteenBit, int radius); + // function to allocate a 2d array + int** Alloc2DArray (int Columns, int Rows) + { + // First, we declare our future 2d array to be returned + int** lpcArray = 0L; + + // Now, we alloc the main pointer with Columns + lpcArray = new int*[Columns]; + + for (int i = 0; i < Columns; ++i) + lpcArray[i] = new int[Rows]; + + return (lpcArray); + }; + + // Function to deallocates the 2d array previously created + void Free2DArray (int** lpcArray, int Columns) + { + // loop to deallocate the columns + for (int i = 0; i < Columns; ++i) + delete [] lpcArray[i]; + + // now, we delete the main pointer + delete [] lpcArray; + }; + + inline bool IsInside (int Width, int Height, int X, int Y) + { + bool bIsWOk = ((X < 0) ? false : (X >= Width ) ? false : true); + bool bIsHOk = ((Y < 0) ? false : (Y >= Height) ? false : true); + return (bIsWOk && bIsHOk); + }; + private: double m_radius; _______________________________________________ Digikam-devel mailing list [hidden email] https://mail.kde.org/mailman/listinfo/digikam-devel |
|
> SVN commit 1196146 by cgilles: > > Andy, this is not understadable. > All CImg::*blur() method crash under MacOsX. and i don't know why... > Probably, this is fixed with last CImg 1.4.x release, as digiKam still use > 1.3.0... but we cannot update because all Greystoration algorithm have > been removed from CImg and migrated to GMic library The solution is to > port greystoration code to GMic, as it have been recommended by CImg > author in the past by a private mail. But it's a long and complex task. > Note : Greystoration tools do not crash under MAC Os X !!! I'm lost... > So, I restore old gaussian blur algorithm for Mac only... What is the advantage of generally using the CImg variant instead of our own code? Do they produce different results? _______________________________________________ Digikam-devel mailing list [hidden email] https://mail.kde.org/mailman/listinfo/digikam-devel |
|
The result look similar.
Andi have patched blur filter to use CImg for speed reason. That all. I can see that gaussian blur code use double kernel loop to blur image. Also code is not really optimized. i know some others algorithm from Mosfet very optimized for speed, but code is not really understandable. If somebody is interested, code is in this archive : http://digikam3rdparty.free.fr/misc.tarballs/libkimageeffect2.tar.bz2 This archive come from Mosfet himself, few year ago. He have contacted me directly to know how he could contribute to digiKam. I said that we need algorithm to process image... Gilles _______________________________________________ Digikam-devel mailing list [hidden email] https://mail.kde.org/mailman/listinfo/digikam-devel |
|
In reply to this post by Marcel Wiesweg
I used CImg because it is nearly 20 times faster.
Why implement such algorithmns on our own if there are ready-to-use, well known and tested libraries :-) ? Andi Clemens ----------------- www.digikam.org On Friday 12 November 2010 18:53:57 Marcel Wiesweg wrote: > > SVN commit 1196146 by cgilles: > > > > Andy, this is not understadable. > > All CImg::*blur() method crash under MacOsX. and i don't know why... > > Probably, this is fixed with last CImg 1.4.x release, as digiKam still > > use 1.3.0... but we cannot update because all Greystoration algorithm > > have been removed from CImg and migrated to GMic library The solution is > > to port greystoration code to GMic, as it have been recommended by CImg > > author in the past by a private mail. But it's a long and complex task. > > Note : Greystoration tools do not crash under MAC Os X !!! I'm lost... > > So, I restore old gaussian blur algorithm for Mac only... > > What is the advantage of generally using the CImg variant instead of our > own code? Do they produce different results? > _______________________________________________ > Digikam-devel mailing list > [hidden email] > https://mail.kde.org/mailman/listinfo/digikam-devel Digikam-devel mailing list [hidden email] https://mail.kde.org/mailman/listinfo/digikam-devel |
|
because, we don't control it.
CImg is a large libs. blur is a simple effect. It's more easy to maintain our code. I imported CImg only for greystoration feature, which is a very complex algorithm. Since One year this code have been moved to another library named GMic. Why ? To provide a script framework. http://gmic.sourceforge.net/ The problem is that all is broken now with CImg. This lib has progressed but is not compatible since 1.3.1. CImg 1.3.0, imported in digiKam core is pretty old now. The solution is to use CMig now. I started this job, but it's complex and long job... http://digikam3rdparty.free.fr/misc.tarballs/gmicport.patch.gz Gilles 2010/11/12 Andi Clemens <[hidden email]>: > I used CImg because it is nearly 20 times faster. > Why implement such algorithmns on our own if there are ready-to-use, well > known and tested libraries :-) ? > > > Andi Clemens > ----------------- > www.digikam.org > > On Friday 12 November 2010 18:53:57 Marcel Wiesweg wrote: >> > SVN commit 1196146 by cgilles: >> > >> > Andy, this is not understadable. >> > All CImg::*blur() method crash under MacOsX. and i don't know why... >> > Probably, this is fixed with last CImg 1.4.x release, as digiKam still >> > use 1.3.0... but we cannot update because all Greystoration algorithm >> > have been removed from CImg and migrated to GMic library The solution is >> > to port greystoration code to GMic, as it have been recommended by CImg >> > author in the past by a private mail. But it's a long and complex task. >> > Note : Greystoration tools do not crash under MAC Os X !!! I'm lost... >> > So, I restore old gaussian blur algorithm for Mac only... >> >> What is the advantage of generally using the CImg variant instead of our >> own code? Do they produce different results? >> _______________________________________________ >> Digikam-devel mailing list >> [hidden email] >> https://mail.kde.org/mailman/listinfo/digikam-devel > _______________________________________________ > Digikam-devel mailing list > [hidden email] > https://mail.kde.org/mailman/listinfo/digikam-devel > Digikam-devel mailing list [hidden email] https://mail.kde.org/mailman/listinfo/digikam-devel |
|
Ah ok so we are going to remove CImg? If so, we could remove the blur effect
anyway, without using the compile flag now...? Andi Clemens ----------------- www.digikam.org On Friday 12 November 2010 22:31:23 Gilles Caulier wrote: > because, we don't control it. > > CImg is a large libs. blur is a simple effect. It's more easy to > maintain our code. > > I imported CImg only for greystoration feature, which is a very > complex algorithm. Since One year this code have been moved to another > library named GMic. Why ? To provide a script framework. > > http://gmic.sourceforge.net/ > > The problem is that all is broken now with CImg. This lib has > progressed but is not compatible since 1.3.1. > > CImg 1.3.0, imported in digiKam core is pretty old now. The solution > is to use CMig now. I started this job, but it's complex and long > job... > > http://digikam3rdparty.free.fr/misc.tarballs/gmicport.patch.gz > > Gilles > > 2010/11/12 Andi Clemens <[hidden email]>: > > I used CImg because it is nearly 20 times faster. > > Why implement such algorithmns on our own if there are ready-to-use, well > > known and tested libraries :-) ? > > > > > > Andi Clemens > > ----------------- > > www.digikam.org > > > > On Friday 12 November 2010 18:53:57 Marcel Wiesweg wrote: > >> > SVN commit 1196146 by cgilles: > >> > > >> > Andy, this is not understadable. > >> > All CImg::*blur() method crash under MacOsX. and i don't know why... > >> > Probably, this is fixed with last CImg 1.4.x release, as digiKam still > >> > use 1.3.0... but we cannot update because all Greystoration algorithm > >> > have been removed from CImg and migrated to GMic library The solution > >> > is to port greystoration code to GMic, as it have been recommended by > >> > CImg author in the past by a private mail. But it's a long and > >> > complex task. Note : Greystoration tools do not crash under MAC Os X > >> > !!! I'm lost... So, I restore old gaussian blur algorithm for Mac > >> > only... > >> > >> What is the advantage of generally using the CImg variant instead of our > >> own code? Do they produce different results? > >> _______________________________________________ > >> Digikam-devel mailing list > >> [hidden email] > >> https://mail.kde.org/mailman/listinfo/digikam-devel > > > > _______________________________________________ > > Digikam-devel mailing list > > [hidden email] > > https://mail.kde.org/mailman/listinfo/digikam-devel > > _______________________________________________ > Digikam-devel mailing list > [hidden email] > https://mail.kde.org/mailman/listinfo/digikam-devel Digikam-devel mailing list [hidden email] https://mail.kde.org/mailman/listinfo/digikam-devel |
|
Yes, old CImg will be removed, and replaced by GMic. This one include
the new CImg without greystoration, and a kernel script which include greystoration core. In fact GMic provide Greystoration + all others image manupilation methods from CImg, by a script interface. It's possible to call script through C++. There are some example in GMic archive. From CImg author, who is also GMic author, CImg code will be stabilized, and all lead developpement will be done in GMic script interface. About Blur stuff, i don't know yet. I would to use another code, more simple and faster, as Mostfet one from libkimageeffect2 archive fro example... Gilles 2010/11/12 Andi Clemens <[hidden email]>: > Ah ok so we are going to remove CImg? If so, we could remove the blur effect > anyway, without using the compile flag now...? > > > Andi Clemens > ----------------- > www.digikam.org > > On Friday 12 November 2010 22:31:23 Gilles Caulier wrote: >> because, we don't control it. >> >> CImg is a large libs. blur is a simple effect. It's more easy to >> maintain our code. >> >> I imported CImg only for greystoration feature, which is a very >> complex algorithm. Since One year this code have been moved to another >> library named GMic. Why ? To provide a script framework. >> >> http://gmic.sourceforge.net/ >> >> The problem is that all is broken now with CImg. This lib has >> progressed but is not compatible since 1.3.1. >> >> CImg 1.3.0, imported in digiKam core is pretty old now. The solution >> is to use CMig now. I started this job, but it's complex and long >> job... >> >> http://digikam3rdparty.free.fr/misc.tarballs/gmicport.patch.gz >> >> Gilles >> >> 2010/11/12 Andi Clemens <[hidden email]>: >> > I used CImg because it is nearly 20 times faster. >> > Why implement such algorithmns on our own if there are ready-to-use, well >> > known and tested libraries :-) ? >> > >> > >> > Andi Clemens >> > ----------------- >> > www.digikam.org >> > >> > On Friday 12 November 2010 18:53:57 Marcel Wiesweg wrote: >> >> > SVN commit 1196146 by cgilles: >> >> > >> >> > Andy, this is not understadable. >> >> > All CImg::*blur() method crash under MacOsX. and i don't know why... >> >> > Probably, this is fixed with last CImg 1.4.x release, as digiKam still >> >> > use 1.3.0... but we cannot update because all Greystoration algorithm >> >> > have been removed from CImg and migrated to GMic library The solution >> >> > is to port greystoration code to GMic, as it have been recommended by >> >> > CImg author in the past by a private mail. But it's a long and >> >> > complex task. Note : Greystoration tools do not crash under MAC Os X >> >> > !!! I'm lost... So, I restore old gaussian blur algorithm for Mac >> >> > only... >> >> >> >> What is the advantage of generally using the CImg variant instead of our >> >> own code? Do they produce different results? >> >> _______________________________________________ >> >> Digikam-devel mailing list >> >> [hidden email] >> >> https://mail.kde.org/mailman/listinfo/digikam-devel >> > >> > _______________________________________________ >> > Digikam-devel mailing list >> > [hidden email] >> > https://mail.kde.org/mailman/listinfo/digikam-devel >> >> _______________________________________________ >> Digikam-devel mailing list >> [hidden email] >> https://mail.kde.org/mailman/listinfo/digikam-devel > _______________________________________________ > Digikam-devel mailing list > [hidden email] > https://mail.kde.org/mailman/listinfo/digikam-devel > Digikam-devel mailing list [hidden email] https://mail.kde.org/mailman/listinfo/digikam-devel |
|
In reply to this post by Bugzilla from andi.clemens@gmx.net
> I used CImg because it is nearly 20 times faster. > Why implement such algorithmns on our own if there are ready-to-use, well > known and tested libraries :-) ? The intention behind my question was to be able to provide some sort of stability for the image plugins now that we have non-destructive editing and possibly reproducible filter actions. That doesn't mean filters cannot change, of course they can, but if they change substantially, we'll increment the version. Now blur is a central component reused by other filters, it would be desirable to have a good, future-proof solution for all platforms. Though it seems this solution is not available. Marcel _______________________________________________ Digikam-devel mailing list [hidden email] https://mail.kde.org/mailman/listinfo/digikam-devel |
| Free forum by Nabble | Edit this page |
