diff -r ad291138eebe -r 436102c3dabc Depth24Image.st --- a/Depth24Image.st Wed Aug 30 15:15:24 2017 +0200 +++ b/Depth24Image.st Wed Aug 30 15:15:34 2017 +0200 @@ -2987,12 +2987,12 @@ !Depth24Image methodsFor:'magnification'! -hardAntiAliasedMagnifiedBy:scalePoint +hardAntiAliasedMagnifiedBy:scaleArg "return a new image magnified by scalePoint, aPoint. This interpolates pixels and is therefore much slower, but generates nicer looking magnifications." - |mX + |scalePoint mX mY newWidth "{ Class: SmallInteger }" newHeight "{ Class: SmallInteger }" @@ -3002,6 +3002,7 @@ value srcRow pixelArray| + scalePoint := scaleArg asPoint. mX := scalePoint x. mY := scalePoint y. ((mX < 0) or:[mY < 0]) ifTrue:[^ nil]. @@ -3014,24 +3015,24 @@ newBytesPerRow := ((newWidth * bitsPerPixel) + 7) // 8. newBits := ByteArray new: "uninitializedNew:" (newBytesPerRow * newHeight). newBits isNil ifTrue:[ - 'Depth24Image [warning]: failed to allocate byteArray for image bits' errorPrintCR. - ^ nil + 'Depth24Image [warning]: failed to allocate byteArray for image bits' errorPrintCR. + ^ nil ]. mask notNil ifTrue:[ - newMask := (mask magnifiedBy:scalePoint) + newMask := (mask magnifiedBy:scalePoint) ]. newImage := self species new. newImage - width:newWidth - height:newHeight - photometric:photometric - samplesPerPixel:samplesPerPixel - bitsPerSample:bitsPerSample - colorMap:nil - bits:newBits - mask:newMask. + width:newWidth + height:newHeight + photometric:photometric + samplesPerPixel:samplesPerPixel + bitsPerSample:bitsPerSample + colorMap:nil + bits:newBits + mask:newMask. mY := mY asFloat. mX := mX asFloat. @@ -3050,86 +3051,86 @@ double _mY = __floatVal(mY); for (_row = 0; _row <= _h; _row++) { - double _srcY; - double _dY; - int _sR; - - _srcY = ((double)_row / _mY); - _sR = (int)_srcY; - _dY = _srcY - ((double)_sR); - _srcRowP = _srcP + (_width3 * _sR); - - for (_col = 0; _col <= _w; _col++) { - unsigned int rHere, gHere, bHere; - unsigned int rRight, gRight, bRight; - unsigned int rRightBelow, gRightBelow, bRightBelow; - unsigned int rBelow, gBelow, bBelow; - unsigned int _r, _g, _b; - double wHere, wRight, wRightBelow, wBelow, sumW; - double _srcX; - double _dX; - int _sC; - - _srcX = ((double)_col / _mX); - _sC = (int)_srcX; - _dX = _srcX - ((double)_sC); - sP = _srcRowP + (_sC * 3); - - rHere = sP[0]; - gHere = sP[1]; - bHere = sP[2]; - - if (_sC < _oldW) { - rRight = sP[3]; - gRight = sP[4]; - bRight = sP[5]; - - if (_sR < _oldH) { - rBelow = sP[0+_width3]; - gBelow = sP[1+_width3]; - bBelow = sP[2+_width3]; - rRightBelow = sP[3+_width3]; - gRightBelow = sP[4+_width3]; - bRightBelow = sP[5+_width3]; - } else { - rRightBelow = rHere; - gRightBelow = gHere; - bRightBelow = bHere; - rBelow = rHere; - gBelow = gHere; - bBelow = bHere; - } - } else { - rRight = rRightBelow = rHere; - gRight = gRightBelow = gHere; - bRight = bRightBelow = bHere; - if (_sR < _oldH) { - rBelow = sP[0+_width3]; - gBelow = sP[1+_width3]; - bBelow = sP[2+_width3]; - } else { - rBelow = rHere; - gBelow = gHere; - bBelow = bHere; - } - } - - wHere = (1.0 - _dX) * (1.0 - _dY); - wRight = _dX * (1.0 - _dY); - wBelow = _dY * (1.0 - _dX); - wRightBelow = _dX * _dY; - sumW = wHere + wRight + wBelow + wRightBelow; - - _r = ((rHere * wHere) + (rRight * wRight) + (rBelow * wBelow) + (rRightBelow * wRightBelow)) / sumW; - _g = ((gHere * wHere) + (gRight * wRight) + (gBelow * wBelow) + (gRightBelow * wRightBelow)) / sumW; - _b = ((bHere * wHere) + (bRight * wRight) + (bBelow * wBelow) + (bRightBelow * wRightBelow)) / sumW; - - _dstP[0] = _r; - _dstP[1] = _g; - _dstP[2] = _b; - - _dstP += 3; - } + double _srcY; + double _dY; + int _sR; + + _srcY = ((double)_row / _mY); + _sR = (int)_srcY; + _dY = _srcY - ((double)_sR); + _srcRowP = _srcP + (_width3 * _sR); + + for (_col = 0; _col <= _w; _col++) { + unsigned int rHere, gHere, bHere; + unsigned int rRight, gRight, bRight; + unsigned int rRightBelow, gRightBelow, bRightBelow; + unsigned int rBelow, gBelow, bBelow; + unsigned int _r, _g, _b; + double wHere, wRight, wRightBelow, wBelow, sumW; + double _srcX; + double _dX; + int _sC; + + _srcX = ((double)_col / _mX); + _sC = (int)_srcX; + _dX = _srcX - ((double)_sC); + sP = _srcRowP + (_sC * 3); + + rHere = sP[0]; + gHere = sP[1]; + bHere = sP[2]; + + if (_sC < _oldW) { + rRight = sP[3]; + gRight = sP[4]; + bRight = sP[5]; + + if (_sR < _oldH) { + rBelow = sP[0+_width3]; + gBelow = sP[1+_width3]; + bBelow = sP[2+_width3]; + rRightBelow = sP[3+_width3]; + gRightBelow = sP[4+_width3]; + bRightBelow = sP[5+_width3]; + } else { + rRightBelow = rHere; + gRightBelow = gHere; + bRightBelow = bHere; + rBelow = rHere; + gBelow = gHere; + bBelow = bHere; + } + } else { + rRight = rRightBelow = rHere; + gRight = gRightBelow = gHere; + bRight = bRightBelow = bHere; + if (_sR < _oldH) { + rBelow = sP[0+_width3]; + gBelow = sP[1+_width3]; + bBelow = sP[2+_width3]; + } else { + rBelow = rHere; + gBelow = gHere; + bBelow = bHere; + } + } + + wHere = (1.0 - _dX) * (1.0 - _dY); + wRight = _dX * (1.0 - _dY); + wBelow = _dY * (1.0 - _dX); + wRightBelow = _dX * _dY; + sumW = wHere + wRight + wBelow + wRightBelow; + + _r = ((rHere * wHere) + (rRight * wRight) + (rBelow * wBelow) + (rRightBelow * wRightBelow)) / sumW; + _g = ((gHere * wHere) + (gRight * wRight) + (gBelow * wBelow) + (gRightBelow * wRightBelow)) / sumW; + _b = ((bHere * wHere) + (bRight * wRight) + (bBelow * wBelow) + (bRightBelow * wRightBelow)) / sumW; + + _dstP[0] = _r; + _dstP[1] = _g; + _dstP[2] = _b; + + _dstP += 3; + } } %}. @@ -3143,31 +3144,38 @@ " |i| i := Depth24Image width:3 height:3 fromArray:#[ 0 0 0 0 0 0 0 0 0 - 0 0 0 255 255 255 0 0 0 - 0 0 0 0 0 0 0 0 0]. + 0 0 0 255 255 255 0 0 0 + 0 0 0 0 0 0 0 0 0]. i hardAntiAliasedMagnifiedBy:8@8 " - "Modified: 2.6.1997 / 12:28:18 / cg" - "Created: 2.6.1997 / 13:18:53 / cg" + "Created: / 02-06-1997 / 13:18:53 / cg" + "Modified: / 30-08-2017 / 13:35:20 / cg" ! -hardMagnifiedBy:scalePoint +hardMagnifiedBy:scaleArg "return a new image magnified by scalePoint, aPoint. - This is the general magnification method, handling non-integral values" - - |mX mY + This is the general magnification method, handling non-integral values. + It is slower than the integral magnification method. + + Notice: this is a naive algorithm, which simply samples the pixel value + at the corresponding original pixel's point, without taking neighbors into + consideration (i.e. it does not compute an average of those pixels). + As a consequence, this will generate bad shrunk images when the original contains + sharp lines." + + |scalePoint mX mY newWidth "{ Class: SmallInteger }" newHeight "{ Class: SmallInteger }" w "{ Class: SmallInteger }" h "{ Class: SmallInteger }" - newImage newBytes + newImage newBytes newMask value "{ Class: SmallInteger }" srcRowIdx "{ Class: SmallInteger }" srcIndex "{ Class: SmallInteger }" - dstIndex "{ Class: SmallInteger }" - newMask| - + dstIndex "{ Class: SmallInteger }"| + + scalePoint := scaleArg asPoint. mX := scalePoint x. mY := scalePoint y. ((mX < 0) or:[mY < 0]) ifTrue:[^ nil]. @@ -3183,14 +3191,10 @@ newImage := self species new. newImage - width:newWidth - height:newHeight - photometric:photometric - samplesPerPixel:samplesPerPixel - bitsPerSample:#[8 8 8] - colorMap:nil - bits:newBytes - mask:newMask. + width:newWidth height:newHeight photometric:photometric + samplesPerPixel:samplesPerPixel bitsPerSample:#[8 8 8] + colorMap:nil + bits:newBytes mask:newMask. "walk over destination image fetching pixels from source image" @@ -3240,7 +3244,7 @@ " ^ newImage - "Modified (comment): / 21-02-2017 / 17:15:18 / cg" + "Modified: / 30-08-2017 / 13:33:30 / cg" ! magnifyRowFrom:srcBytes offset:srcStart