@@ -37,6 +37,7 @@ void QgsCubicRasterResampler::resample( const QImage& srcImage, QImage& dstImage
3737 int * redMatrix = new int [ nCols * nRows ];
3838 int * greenMatrix = new int [ nCols * nRows ];
3939 int * blueMatrix = new int [ nCols * nRows ];
40+ int * alphaMatrix = new int [ nCols * nRows ];
4041
4142 for ( int i = 0 ; i < nRows; ++i )
4243 {
@@ -46,6 +47,7 @@ void QgsCubicRasterResampler::resample( const QImage& srcImage, QImage& dstImage
4647 redMatrix[pos] = qRed ( px );
4748 greenMatrix[pos] = qGreen ( px );
4849 blueMatrix[pos] = qBlue ( px );
50+ alphaMatrix[pos] = qAlpha ( px );
4951 ++pos;
5052 }
5153 }
@@ -57,6 +59,8 @@ void QgsCubicRasterResampler::resample( const QImage& srcImage, QImage& dstImage
5759 xDerivativeMatrix ( nCols, nRows, xDerivativeMatrixGreen, greenMatrix );
5860 double * xDerivativeMatrixBlue = new double [ nCols * nRows ];
5961 xDerivativeMatrix ( nCols, nRows, xDerivativeMatrixBlue, blueMatrix );
62+ double * xDerivativeMatrixAlpha = new double [ nCols * nRows ];
63+ xDerivativeMatrix ( nCols, nRows, xDerivativeMatrixAlpha, alphaMatrix );
6064
6165 // derivative y
6266 double * yDerivativeMatrixRed = new double [ nCols * nRows ];
@@ -65,6 +69,8 @@ void QgsCubicRasterResampler::resample( const QImage& srcImage, QImage& dstImage
6569 yDerivativeMatrix ( nCols, nRows, yDerivativeMatrixGreen, greenMatrix );
6670 double * yDerivativeMatrixBlue = new double [ nCols * nRows ];
6771 yDerivativeMatrix ( nCols, nRows, yDerivativeMatrixBlue, blueMatrix );
72+ double * yDerivativeMatrixAlpha = new double [ nCols * nRows ];
73+ yDerivativeMatrix ( nCols, nRows, yDerivativeMatrixAlpha, alphaMatrix );
6874
6975 // compute output
7076 double nSrcPerDstX = ( double ) srcImage.width () / ( double ) dstImage.width ();
@@ -77,7 +83,7 @@ void QgsCubicRasterResampler::resample( const QImage& srcImage, QImage& dstImage
7783 int lastSrcColInt = -1 ;
7884 int lastSrcRowInt = -1 ;
7985
80- int r, g, b;
86+ int r, g, b, a ;
8187 // bernstein polynomials
8288 double bp0u, bp1u, bp2u, bp3u, bp0v, bp1v, bp2v, bp3v;
8389 double u, v;
@@ -119,16 +125,17 @@ void QgsCubicRasterResampler::resample( const QImage& srcImage, QImage& dstImage
119125 px1 = srcImage.pixel ( currentSrcColInt, 0 );
120126 px2 = srcImage.pixel ( currentSrcColInt + 1 , 0 );
121127 dstImage.setPixel ( j, i, curveInterpolation ( px1, px2, u, xDerivativeMatrixRed[ currentSrcColInt ], xDerivativeMatrixGreen[ currentSrcColInt ],
122- xDerivativeMatrixBlue[ currentSrcColInt ], xDerivativeMatrixRed[ currentSrcColInt + 1 ], xDerivativeMatrixGreen[ currentSrcColInt + 1 ],
123- xDerivativeMatrixBlue[ currentSrcColInt + 1 ] ) );
128+ xDerivativeMatrixBlue[ currentSrcColInt ], xDerivativeMatrixAlpha[ currentSrcColInt ], xDerivativeMatrixRed[ currentSrcColInt + 1 ], xDerivativeMatrixGreen[ currentSrcColInt + 1 ],
129+ xDerivativeMatrixBlue[ currentSrcColInt + 1 ], xDerivativeMatrixAlpha[ currentSrcColInt + 1 ] ) );
124130 }
125131 else if ( currentSrcRowInt >= ( srcImage.height () - 1 ) )
126132 {
127133 int idx = ( srcImage.height () - 1 ) * srcImage.width () + currentSrcColInt;
128134 px1 = srcImage.pixel ( currentSrcColInt, srcImage.height () - 1 );
129135 px2 = srcImage.pixel ( currentSrcColInt + 1 , srcImage.height () - 1 );
130136 dstImage.setPixel ( j, i, curveInterpolation ( px1, px2, u, xDerivativeMatrixRed[ idx ], xDerivativeMatrixGreen[ idx ], xDerivativeMatrixBlue[idx],
131- xDerivativeMatrixRed[ idx + 1 ], xDerivativeMatrixGreen[ idx + 1 ], xDerivativeMatrixBlue[idx + 1 ] ) );
137+ xDerivativeMatrixAlpha[idx], xDerivativeMatrixRed[ idx + 1 ], xDerivativeMatrixGreen[ idx + 1 ], xDerivativeMatrixBlue[idx + 1 ],
138+ xDerivativeMatrixAlpha[idx + 1 ] ) );
132139 }
133140 else if ( currentSrcColInt < 0 )
134141 {
@@ -137,7 +144,8 @@ void QgsCubicRasterResampler::resample( const QImage& srcImage, QImage& dstImage
137144 px1 = srcImage.pixel ( 0 , currentSrcRowInt );
138145 px2 = srcImage.pixel ( 0 , currentSrcRowInt + 1 );
139146 dstImage.setPixel ( j, i, curveInterpolation ( px1, px2, v, yDerivativeMatrixRed[ idx1 ], yDerivativeMatrixGreen[ idx1 ], yDerivativeMatrixBlue[ idx1],
140- yDerivativeMatrixRed[ idx2 ], yDerivativeMatrixGreen[ idx2 ], yDerivativeMatrixBlue[ idx2] ) );
147+ yDerivativeMatrixAlpha[ idx1], yDerivativeMatrixRed[ idx2 ], yDerivativeMatrixGreen[ idx2 ], yDerivativeMatrixBlue[ idx2],
148+ yDerivativeMatrixAlpha[ idx2] ) );
141149 }
142150 else if ( currentSrcColInt >= ( srcImage.width () - 1 ) )
143151 {
@@ -146,7 +154,8 @@ void QgsCubicRasterResampler::resample( const QImage& srcImage, QImage& dstImage
146154 px1 = srcImage.pixel ( srcImage.width () - 1 , currentSrcRowInt );
147155 px2 = srcImage.pixel ( srcImage.width () - 1 , currentSrcRowInt + 1 );
148156 dstImage.setPixel ( j, i, curveInterpolation ( px1, px2, v, yDerivativeMatrixRed[ idx1 ], yDerivativeMatrixGreen[ idx1 ], yDerivativeMatrixBlue[ idx1],
149- yDerivativeMatrixRed[ idx2 ], yDerivativeMatrixGreen[ idx2 ], yDerivativeMatrixBlue[ idx2] ) );
157+ yDerivativeMatrixAlpha[ idx1], yDerivativeMatrixRed[ idx2 ], yDerivativeMatrixGreen[ idx2 ], yDerivativeMatrixBlue[ idx2],
158+ yDerivativeMatrixAlpha[ idx2] ) );
150159 }
151160 currentSrcCol += nSrcPerDstX;
152161 continue ;
@@ -155,9 +164,9 @@ void QgsCubicRasterResampler::resample( const QImage& srcImage, QImage& dstImage
155164 // first update the control points if necessary
156165 if ( currentSrcColInt != lastSrcColInt || currentSrcRowInt != lastSrcRowInt )
157166 {
158- calculateControlPoints ( nCols, nRows, currentSrcRowInt, currentSrcColInt, redMatrix, greenMatrix, blueMatrix,
159- xDerivativeMatrixRed, xDerivativeMatrixGreen, xDerivativeMatrixBlue,
160- yDerivativeMatrixRed, yDerivativeMatrixGreen, yDerivativeMatrixBlue );
167+ calculateControlPoints ( nCols, nRows, currentSrcRowInt, currentSrcColInt, redMatrix, greenMatrix, blueMatrix, alphaMatrix,
168+ xDerivativeMatrixRed, xDerivativeMatrixGreen, xDerivativeMatrixBlue, xDerivativeMatrixAlpha,
169+ yDerivativeMatrixRed, yDerivativeMatrixGreen, yDerivativeMatrixBlue, yDerivativeMatrixAlpha );
161170 }
162171
163172 // bernstein polynomials
@@ -219,7 +228,24 @@ void QgsCubicRasterResampler::resample( const QImage& srcImage, QImage& dstImage
219228 bp2u * bp3v * cBlue23 +
220229 bp3u * bp3v * cBlue33;
221230
222- dstImage.setPixel ( j, i, qRgb ( r, g, b ) );
231+ a = bp0u * bp0v * cAlpha00 +
232+ bp1u * bp0v * cAlpha10 +
233+ bp2u * bp0v * cAlpha20 +
234+ bp3u * bp0v * cAlpha30 +
235+ bp0u * bp1v * cAlpha01 +
236+ bp1u * bp1v * cAlpha11 +
237+ bp2u * bp1v * cAlpha21 +
238+ bp3u * bp1v * cAlpha31 +
239+ bp0u * bp2v * cAlpha02 +
240+ bp1u * bp2v * cAlpha12 +
241+ bp2u * bp2v * cAlpha22 +
242+ bp3u * bp2v * cAlpha32 +
243+ bp0u * bp3v * cAlpha03 +
244+ bp1u * bp3v * cAlpha13 +
245+ bp2u * bp3v * cAlpha23 +
246+ bp3u * bp3v * cAlpha33;
247+
248+ dstImage.setPixel ( j, i, qRgba ( r, g, b, a ) );
223249 lastSrcColInt = currentSrcColInt;
224250 currentSrcCol += nSrcPerDstX;
225251 }
@@ -295,47 +321,61 @@ void QgsCubicRasterResampler::yDerivativeMatrix( int nCols, int nRows, double* m
295321}
296322
297323void QgsCubicRasterResampler::calculateControlPoints ( int nCols, int nRows, int currentRow, int currentCol, int * redMatrix, int * greenMatrix, int * blueMatrix,
298- double * xDerivativeMatrixRed, double * xDerivativeMatrixGreen, double * xDerivativeMatrixBlue,
299- double * yDerivativeMatrixRed, double * yDerivativeMatrixGreen, double * yDerivativeMatrixBlue )
324+ int * alphaMatrix, double * xDerivativeMatrixRed, double * xDerivativeMatrixGreen, double * xDerivativeMatrixBlue, double * xDerivativeMatrixAlpha ,
325+ double * yDerivativeMatrixRed, double * yDerivativeMatrixGreen, double * yDerivativeMatrixBlue, double * yDerivativeMatrixAlpha )
300326{
301327 int idx00 = currentRow * nCols + currentCol;
302328 int idx10 = idx00 + 1 ;
303329 int idx01 = idx00 + nCols;
304330 int idx11 = idx01 + 1 ;
305331
306332 // corner points
307- cRed00 = redMatrix[idx00]; cGreen00 = greenMatrix[idx00]; cBlue00 = blueMatrix[idx00];
308- cRed30 = redMatrix[idx10]; cGreen30 = greenMatrix[idx10]; cBlue30 = blueMatrix[idx10];
309- cRed03 = redMatrix[idx01]; cGreen03 = greenMatrix[idx01]; cBlue03 = blueMatrix[idx01];
310- cRed33 = redMatrix[idx11]; cGreen33 = greenMatrix[idx11]; cBlue33 = blueMatrix[idx11];
333+ cRed00 = redMatrix[idx00]; cGreen00 = greenMatrix[idx00]; cBlue00 = blueMatrix[idx00]; cAlpha00 = alphaMatrix[idx00];
334+ cRed30 = redMatrix[idx10]; cGreen30 = greenMatrix[idx10]; cBlue30 = blueMatrix[idx10]; cAlpha30 = alphaMatrix[idx10];
335+ cRed03 = redMatrix[idx01]; cGreen03 = greenMatrix[idx01]; cBlue03 = blueMatrix[idx01]; cAlpha03 = alphaMatrix[idx01];
336+ cRed33 = redMatrix[idx11]; cGreen33 = greenMatrix[idx11]; cBlue33 = blueMatrix[idx11]; cAlpha33 = alphaMatrix[idx11];
311337
312338 // control points near c00
313- cRed10 = cRed00 + 0.333 * xDerivativeMatrixRed[idx00]; cGreen10 = cGreen00 + 0.333 * xDerivativeMatrixGreen[idx00]; cBlue10 = cBlue00 + 0.333 * xDerivativeMatrixBlue[idx00];
314- cRed01 = cRed00 + 0.333 * yDerivativeMatrixRed[idx00]; cGreen01 = cGreen00 + 0.333 * yDerivativeMatrixGreen[idx00]; cBlue01 = cBlue00 + 0.333 * yDerivativeMatrixBlue[idx00];
315- cRed11 = cRed10 + 0.333 * yDerivativeMatrixRed[idx00]; cGreen11 = cGreen10 + 0.333 * yDerivativeMatrixGreen[idx00]; cBlue11 = cBlue10 + 0.333 * yDerivativeMatrixBlue[idx00];
339+ cRed10 = cRed00 + 0.333 * xDerivativeMatrixRed[idx00]; cGreen10 = cGreen00 + 0.333 * xDerivativeMatrixGreen[idx00];
340+ cBlue10 = cBlue00 + 0.333 * xDerivativeMatrixBlue[idx00];cAlpha10 = cAlpha00 + 0.333 * xDerivativeMatrixAlpha[idx00];
341+ cRed01 = cRed00 + 0.333 * yDerivativeMatrixRed[idx00]; cGreen01 = cGreen00 + 0.333 * yDerivativeMatrixGreen[idx00];
342+ cBlue01 = cBlue00 + 0.333 * yDerivativeMatrixBlue[idx00];cAlpha01 = cAlpha00 + 0.333 * yDerivativeMatrixAlpha[idx00];
343+ cRed11 = cRed10 + 0.333 * yDerivativeMatrixRed[idx00]; cGreen11 = cGreen10 + 0.333 * yDerivativeMatrixGreen[idx00];
344+ cBlue11 = cBlue10 + 0.333 * yDerivativeMatrixBlue[idx00];cAlpha11 = cAlpha10 + 0.333 * yDerivativeMatrixAlpha[idx00];
316345
317346 // control points near c30
318- cRed20 = cRed30 - 0.333 * xDerivativeMatrixRed[idx10]; cGreen20 = cGreen30 - 0.333 * xDerivativeMatrixGreen[idx10]; cBlue20 = cBlue30 - 0.333 * xDerivativeMatrixBlue[idx10];
319- cRed31 = cRed30 + 0.333 * yDerivativeMatrixRed[idx10]; cGreen31 = cGreen30 + 0.333 * yDerivativeMatrixGreen[idx10]; cBlue31 = cBlue30 + 0.333 * yDerivativeMatrixBlue[idx10];
320- cRed21 = cRed20 + 0.333 * yDerivativeMatrixRed[idx10]; cGreen21 = cGreen20 + 0.333 * yDerivativeMatrixGreen[idx10]; cBlue21 = cBlue20 + 0.333 * yDerivativeMatrixBlue[idx10];
347+ cRed20 = cRed30 - 0.333 * xDerivativeMatrixRed[idx10]; cGreen20 = cGreen30 - 0.333 * xDerivativeMatrixGreen[idx10];
348+ cBlue20 = cBlue30 - 0.333 * xDerivativeMatrixBlue[idx10]; cAlpha20 = cAlpha30 - 0.333 * xDerivativeMatrixAlpha[idx10];
349+ cRed31 = cRed30 + 0.333 * yDerivativeMatrixRed[idx10]; cGreen31 = cGreen30 + 0.333 * yDerivativeMatrixGreen[idx10];
350+ cBlue31 = cBlue30 + 0.333 * yDerivativeMatrixBlue[idx10]; cAlpha31 = cAlpha30 + 0.333 * yDerivativeMatrixAlpha[idx10];
351+ cRed21 = cRed20 + 0.333 * yDerivativeMatrixRed[idx10]; cGreen21 = cGreen20 + 0.333 * yDerivativeMatrixGreen[idx10];
352+ cBlue21 = cBlue20 + 0.333 * yDerivativeMatrixBlue[idx10]; cAlpha21 = cAlpha20 + 0.333 * yDerivativeMatrixAlpha[idx10];
321353
322354 // control points near c03
323- cRed13 = cRed03 + 0.333 * xDerivativeMatrixRed[idx01]; cGreen13 = cGreen03 + 0.333 * xDerivativeMatrixGreen[idx01]; cBlue13 = cBlue03 + 0.333 * xDerivativeMatrixBlue[idx01];
324- cRed02 = cRed03 - 0.333 * yDerivativeMatrixRed[idx01]; cGreen02 = cGreen03 - 0.333 * yDerivativeMatrixGreen[idx01]; cBlue02 = cBlue03 - 0.333 * yDerivativeMatrixBlue[idx01];
325- cRed12 = cRed02 + 0.333 * xDerivativeMatrixRed[idx01]; cGreen12 = cGreen02 + 0.333 * xDerivativeMatrixGreen[idx01]; cBlue12 = cBlue02 + 0.333 * xDerivativeMatrixBlue[idx01];
355+ cRed13 = cRed03 + 0.333 * xDerivativeMatrixRed[idx01]; cGreen13 = cGreen03 + 0.333 * xDerivativeMatrixGreen[idx01];
356+ cBlue13 = cBlue03 + 0.333 * xDerivativeMatrixBlue[idx01]; cAlpha13 = cAlpha03 + 0.333 * xDerivativeMatrixAlpha[idx01];
357+ cRed02 = cRed03 - 0.333 * yDerivativeMatrixRed[idx01]; cGreen02 = cGreen03 - 0.333 * yDerivativeMatrixGreen[idx01];
358+ cBlue02 = cBlue03 - 0.333 * yDerivativeMatrixBlue[idx01]; cAlpha02 = cAlpha03 - 0.333 * yDerivativeMatrixAlpha[idx01];
359+ cRed12 = cRed02 + 0.333 * xDerivativeMatrixRed[idx01]; cGreen12 = cGreen02 + 0.333 * xDerivativeMatrixGreen[idx01];
360+ cBlue12 = cBlue02 + 0.333 * xDerivativeMatrixBlue[idx01]; cAlpha12 = cAlpha02 + 0.333 * xDerivativeMatrixAlpha[idx01];
326361
327362 // control points near c33
328- cRed23 = cRed33 - 0.333 * xDerivativeMatrixRed[idx11]; cGreen23 = cGreen33 - 0.333 * xDerivativeMatrixGreen[idx11]; cBlue23 = cBlue33 - 0.333 * xDerivativeMatrixBlue[idx11];
329- cRed32 = cRed33 - 0.333 * yDerivativeMatrixRed[idx11]; cGreen32 = cGreen33 - 0.333 * yDerivativeMatrixGreen[idx11]; cBlue32 = cBlue33 - 0.333 * yDerivativeMatrixBlue[idx11];
330- cRed22 = cRed32 - 0.333 * xDerivativeMatrixRed[idx11]; cGreen22 = cGreen32 - 0.333 * xDerivativeMatrixGreen[idx11]; cBlue22 = cBlue32 - 0.333 * xDerivativeMatrixBlue[idx11];
363+ cRed23 = cRed33 - 0.333 * xDerivativeMatrixRed[idx11]; cGreen23 = cGreen33 - 0.333 * xDerivativeMatrixGreen[idx11];
364+ cBlue23 = cBlue33 - 0.333 * xDerivativeMatrixBlue[idx11]; cAlpha23 = cAlpha33 - 0.333 * xDerivativeMatrixAlpha[idx11];
365+ cRed32 = cRed33 - 0.333 * yDerivativeMatrixRed[idx11]; cGreen32 = cGreen33 - 0.333 * yDerivativeMatrixGreen[idx11];
366+ cBlue32 = cBlue33 - 0.333 * yDerivativeMatrixBlue[idx11]; cAlpha32 = cAlpha33 - 0.333 * yDerivativeMatrixAlpha[idx11];
367+ cRed22 = cRed32 - 0.333 * xDerivativeMatrixRed[idx11]; cGreen22 = cGreen32 - 0.333 * xDerivativeMatrixGreen[idx11];
368+ cBlue22 = cBlue32 - 0.333 * xDerivativeMatrixBlue[idx11]; cAlpha22 = cAlpha32 - 0.333 * xDerivativeMatrixAlpha[idx11];
331369}
332370
333- QRgb QgsCubicRasterResampler::curveInterpolation ( QRgb pt1, QRgb pt2, double t, double d1red, double d1green, double d1blue , double d2red, double d2green, double d2blue )
371+ QRgb QgsCubicRasterResampler::curveInterpolation ( QRgb pt1, QRgb pt2, double t, double d1red, double d1green, double d1blue, double d1alpha,
372+ double d2red, double d2green, double d2blue, double d2alpha )
334373{
335374 // control points
336375 double p0r = qRed ( pt1 ); double p1r = p0r + 0.333 * d1red; double p3r = qRed ( pt2 ); double p2r = p3r - 0.333 * d2red;
337376 double p0g = qGreen ( pt1 ); double p1g = p0g + 0.333 * d1green; double p3g = qGreen ( pt2 ); double p2g = p3g - 0.333 * d2green;
338377 double p0b = qBlue ( pt1 ); double p1b = p0b + 0.333 * d1blue; double p3b = qBlue ( pt2 ); double p2b = p3b - 0.333 * d2blue;
378+ double p0a = qAlpha ( pt1 ); double p1a = p0a + 0.333 * d1alpha; double p3a = qAlpha ( pt2 ); double p2a = p3a - 0.333 * d2alpha;
339379
340380 // bernstein polynomials
341381 double bp0 = calcBernsteinPoly ( 3 , 0 , t );
@@ -346,8 +386,9 @@ QRgb QgsCubicRasterResampler::curveInterpolation( QRgb pt1, QRgb pt2, double t,
346386 int red = bp0 * p0r + bp1 * p1r + bp2 * p2r + bp3 * p3r;
347387 int green = bp0 * p0g + bp1 * p1g + bp2 * p2g + bp3 * p3g;
348388 int blue = bp0 * p0b + bp1 * p1b + bp2 * p2b + bp3 * p3b;
389+ int alpha = bp0 * p0a + bp1 * p1a + bp2 * p2a + bp3 * p3a;
349390
350- return qRgb ( red, green, blue );
391+ return qRgba ( red, green, blue, alpha );
351392}
352393
353394double QgsCubicRasterResampler::calcBernsteinPoly ( int n, int i, double t )
0 commit comments