2985 "Modified: / 30-01-2017 / 18:29:01 / stefan" |
2985 "Modified: / 30-01-2017 / 18:29:01 / stefan" |
2986 ! ! |
2986 ! ! |
2987 |
2987 |
2988 !Depth24Image methodsFor:'magnification'! |
2988 !Depth24Image methodsFor:'magnification'! |
2989 |
2989 |
2990 hardAntiAliasedMagnifiedBy:scalePoint |
2990 hardAntiAliasedMagnifiedBy:scaleArg |
2991 "return a new image magnified by scalePoint, aPoint. |
2991 "return a new image magnified by scalePoint, aPoint. |
2992 This interpolates pixels and is therefore much slower, |
2992 This interpolates pixels and is therefore much slower, |
2993 but generates nicer looking magnifications." |
2993 but generates nicer looking magnifications." |
2994 |
2994 |
2995 |mX |
2995 |scalePoint mX |
2996 mY |
2996 mY |
2997 newWidth "{ Class: SmallInteger }" |
2997 newWidth "{ Class: SmallInteger }" |
2998 newHeight "{ Class: SmallInteger }" |
2998 newHeight "{ Class: SmallInteger }" |
2999 w "{ Class: SmallInteger }" |
2999 w "{ Class: SmallInteger }" |
3000 h "{ Class: SmallInteger }" |
3000 h "{ Class: SmallInteger }" |
3001 newImage newBits bitsPerPixel newBytesPerRow newMask |
3001 newImage newBits bitsPerPixel newBytesPerRow newMask |
3002 value |
3002 value |
3003 srcRow pixelArray| |
3003 srcRow pixelArray| |
3004 |
3004 |
|
3005 scalePoint := scaleArg asPoint. |
3005 mX := scalePoint x. |
3006 mX := scalePoint x. |
3006 mY := scalePoint y. |
3007 mY := scalePoint y. |
3007 ((mX < 0) or:[mY < 0]) ifTrue:[^ nil]. |
3008 ((mX < 0) or:[mY < 0]) ifTrue:[^ nil]. |
3008 ((mX = 1) and:[mY = 1]) ifTrue:[^ self]. |
3009 ((mX = 1) and:[mY = 1]) ifTrue:[^ self]. |
3009 |
3010 |
3012 |
3013 |
3013 bitsPerPixel := self depth. |
3014 bitsPerPixel := self depth. |
3014 newBytesPerRow := ((newWidth * bitsPerPixel) + 7) // 8. |
3015 newBytesPerRow := ((newWidth * bitsPerPixel) + 7) // 8. |
3015 newBits := ByteArray new: "uninitializedNew:" (newBytesPerRow * newHeight). |
3016 newBits := ByteArray new: "uninitializedNew:" (newBytesPerRow * newHeight). |
3016 newBits isNil ifTrue:[ |
3017 newBits isNil ifTrue:[ |
3017 'Depth24Image [warning]: failed to allocate byteArray for image bits' errorPrintCR. |
3018 'Depth24Image [warning]: failed to allocate byteArray for image bits' errorPrintCR. |
3018 ^ nil |
3019 ^ nil |
3019 ]. |
3020 ]. |
3020 |
3021 |
3021 mask notNil ifTrue:[ |
3022 mask notNil ifTrue:[ |
3022 newMask := (mask magnifiedBy:scalePoint) |
3023 newMask := (mask magnifiedBy:scalePoint) |
3023 ]. |
3024 ]. |
3024 |
3025 |
3025 newImage := self species new. |
3026 newImage := self species new. |
3026 newImage |
3027 newImage |
3027 width:newWidth |
3028 width:newWidth |
3028 height:newHeight |
3029 height:newHeight |
3029 photometric:photometric |
3030 photometric:photometric |
3030 samplesPerPixel:samplesPerPixel |
3031 samplesPerPixel:samplesPerPixel |
3031 bitsPerSample:bitsPerSample |
3032 bitsPerSample:bitsPerSample |
3032 colorMap:nil |
3033 colorMap:nil |
3033 bits:newBits |
3034 bits:newBits |
3034 mask:newMask. |
3035 mask:newMask. |
3035 |
3036 |
3036 mY := mY asFloat. |
3037 mY := mY asFloat. |
3037 mX := mX asFloat. |
3038 mX := mX asFloat. |
3038 |
3039 |
3039 %{ |
3040 %{ |
3048 int _row, _col; |
3049 int _row, _col; |
3049 double _mX = __floatVal(mX); |
3050 double _mX = __floatVal(mX); |
3050 double _mY = __floatVal(mY); |
3051 double _mY = __floatVal(mY); |
3051 |
3052 |
3052 for (_row = 0; _row <= _h; _row++) { |
3053 for (_row = 0; _row <= _h; _row++) { |
3053 double _srcY; |
3054 double _srcY; |
3054 double _dY; |
3055 double _dY; |
3055 int _sR; |
3056 int _sR; |
3056 |
3057 |
3057 _srcY = ((double)_row / _mY); |
3058 _srcY = ((double)_row / _mY); |
3058 _sR = (int)_srcY; |
3059 _sR = (int)_srcY; |
3059 _dY = _srcY - ((double)_sR); |
3060 _dY = _srcY - ((double)_sR); |
3060 _srcRowP = _srcP + (_width3 * _sR); |
3061 _srcRowP = _srcP + (_width3 * _sR); |
3061 |
3062 |
3062 for (_col = 0; _col <= _w; _col++) { |
3063 for (_col = 0; _col <= _w; _col++) { |
3063 unsigned int rHere, gHere, bHere; |
3064 unsigned int rHere, gHere, bHere; |
3064 unsigned int rRight, gRight, bRight; |
3065 unsigned int rRight, gRight, bRight; |
3065 unsigned int rRightBelow, gRightBelow, bRightBelow; |
3066 unsigned int rRightBelow, gRightBelow, bRightBelow; |
3066 unsigned int rBelow, gBelow, bBelow; |
3067 unsigned int rBelow, gBelow, bBelow; |
3067 unsigned int _r, _g, _b; |
3068 unsigned int _r, _g, _b; |
3068 double wHere, wRight, wRightBelow, wBelow, sumW; |
3069 double wHere, wRight, wRightBelow, wBelow, sumW; |
3069 double _srcX; |
3070 double _srcX; |
3070 double _dX; |
3071 double _dX; |
3071 int _sC; |
3072 int _sC; |
3072 |
3073 |
3073 _srcX = ((double)_col / _mX); |
3074 _srcX = ((double)_col / _mX); |
3074 _sC = (int)_srcX; |
3075 _sC = (int)_srcX; |
3075 _dX = _srcX - ((double)_sC); |
3076 _dX = _srcX - ((double)_sC); |
3076 sP = _srcRowP + (_sC * 3); |
3077 sP = _srcRowP + (_sC * 3); |
3077 |
3078 |
3078 rHere = sP[0]; |
3079 rHere = sP[0]; |
3079 gHere = sP[1]; |
3080 gHere = sP[1]; |
3080 bHere = sP[2]; |
3081 bHere = sP[2]; |
3081 |
3082 |
3082 if (_sC < _oldW) { |
3083 if (_sC < _oldW) { |
3083 rRight = sP[3]; |
3084 rRight = sP[3]; |
3084 gRight = sP[4]; |
3085 gRight = sP[4]; |
3085 bRight = sP[5]; |
3086 bRight = sP[5]; |
3086 |
3087 |
3087 if (_sR < _oldH) { |
3088 if (_sR < _oldH) { |
3088 rBelow = sP[0+_width3]; |
3089 rBelow = sP[0+_width3]; |
3089 gBelow = sP[1+_width3]; |
3090 gBelow = sP[1+_width3]; |
3090 bBelow = sP[2+_width3]; |
3091 bBelow = sP[2+_width3]; |
3091 rRightBelow = sP[3+_width3]; |
3092 rRightBelow = sP[3+_width3]; |
3092 gRightBelow = sP[4+_width3]; |
3093 gRightBelow = sP[4+_width3]; |
3093 bRightBelow = sP[5+_width3]; |
3094 bRightBelow = sP[5+_width3]; |
3094 } else { |
3095 } else { |
3095 rRightBelow = rHere; |
3096 rRightBelow = rHere; |
3096 gRightBelow = gHere; |
3097 gRightBelow = gHere; |
3097 bRightBelow = bHere; |
3098 bRightBelow = bHere; |
3098 rBelow = rHere; |
3099 rBelow = rHere; |
3099 gBelow = gHere; |
3100 gBelow = gHere; |
3100 bBelow = bHere; |
3101 bBelow = bHere; |
3101 } |
3102 } |
3102 } else { |
3103 } else { |
3103 rRight = rRightBelow = rHere; |
3104 rRight = rRightBelow = rHere; |
3104 gRight = gRightBelow = gHere; |
3105 gRight = gRightBelow = gHere; |
3105 bRight = bRightBelow = bHere; |
3106 bRight = bRightBelow = bHere; |
3106 if (_sR < _oldH) { |
3107 if (_sR < _oldH) { |
3107 rBelow = sP[0+_width3]; |
3108 rBelow = sP[0+_width3]; |
3108 gBelow = sP[1+_width3]; |
3109 gBelow = sP[1+_width3]; |
3109 bBelow = sP[2+_width3]; |
3110 bBelow = sP[2+_width3]; |
3110 } else { |
3111 } else { |
3111 rBelow = rHere; |
3112 rBelow = rHere; |
3112 gBelow = gHere; |
3113 gBelow = gHere; |
3113 bBelow = bHere; |
3114 bBelow = bHere; |
3114 } |
3115 } |
3115 } |
3116 } |
3116 |
3117 |
3117 wHere = (1.0 - _dX) * (1.0 - _dY); |
3118 wHere = (1.0 - _dX) * (1.0 - _dY); |
3118 wRight = _dX * (1.0 - _dY); |
3119 wRight = _dX * (1.0 - _dY); |
3119 wBelow = _dY * (1.0 - _dX); |
3120 wBelow = _dY * (1.0 - _dX); |
3120 wRightBelow = _dX * _dY; |
3121 wRightBelow = _dX * _dY; |
3121 sumW = wHere + wRight + wBelow + wRightBelow; |
3122 sumW = wHere + wRight + wBelow + wRightBelow; |
3122 |
3123 |
3123 _r = ((rHere * wHere) + (rRight * wRight) + (rBelow * wBelow) + (rRightBelow * wRightBelow)) / sumW; |
3124 _r = ((rHere * wHere) + (rRight * wRight) + (rBelow * wBelow) + (rRightBelow * wRightBelow)) / sumW; |
3124 _g = ((gHere * wHere) + (gRight * wRight) + (gBelow * wBelow) + (gRightBelow * wRightBelow)) / sumW; |
3125 _g = ((gHere * wHere) + (gRight * wRight) + (gBelow * wBelow) + (gRightBelow * wRightBelow)) / sumW; |
3125 _b = ((bHere * wHere) + (bRight * wRight) + (bBelow * wBelow) + (bRightBelow * wRightBelow)) / sumW; |
3126 _b = ((bHere * wHere) + (bRight * wRight) + (bBelow * wBelow) + (bRightBelow * wRightBelow)) / sumW; |
3126 |
3127 |
3127 _dstP[0] = _r; |
3128 _dstP[0] = _r; |
3128 _dstP[1] = _g; |
3129 _dstP[1] = _g; |
3129 _dstP[2] = _b; |
3130 _dstP[2] = _b; |
3130 |
3131 |
3131 _dstP += 3; |
3132 _dstP += 3; |
3132 } |
3133 } |
3133 } |
3134 } |
3134 %}. |
3135 %}. |
3135 |
3136 |
3136 ^ newImage |
3137 ^ newImage |
3137 |
3138 |
3141 i hardAntiAliasedMagnifiedBy:2@2 |
3142 i hardAntiAliasedMagnifiedBy:2@2 |
3142 " |
3143 " |
3143 " |
3144 " |
3144 |i| |
3145 |i| |
3145 i := Depth24Image width:3 height:3 fromArray:#[ 0 0 0 0 0 0 0 0 0 |
3146 i := Depth24Image width:3 height:3 fromArray:#[ 0 0 0 0 0 0 0 0 0 |
3146 0 0 0 255 255 255 0 0 0 |
3147 0 0 0 255 255 255 0 0 0 |
3147 0 0 0 0 0 0 0 0 0]. |
3148 0 0 0 0 0 0 0 0 0]. |
3148 i hardAntiAliasedMagnifiedBy:8@8 |
3149 i hardAntiAliasedMagnifiedBy:8@8 |
3149 " |
3150 " |
3150 |
3151 |
3151 "Modified: 2.6.1997 / 12:28:18 / cg" |
3152 "Created: / 02-06-1997 / 13:18:53 / cg" |
3152 "Created: 2.6.1997 / 13:18:53 / cg" |
3153 "Modified: / 30-08-2017 / 13:35:20 / cg" |
3153 ! |
3154 ! |
3154 |
3155 |
3155 hardMagnifiedBy:scalePoint |
3156 hardMagnifiedBy:scaleArg |
3156 "return a new image magnified by scalePoint, aPoint. |
3157 "return a new image magnified by scalePoint, aPoint. |
3157 This is the general magnification method, handling non-integral values" |
3158 This is the general magnification method, handling non-integral values. |
3158 |
3159 It is slower than the integral magnification method. |
3159 |mX mY |
3160 |
|
3161 Notice: this is a naive algorithm, which simply samples the pixel value |
|
3162 at the corresponding original pixel's point, without taking neighbors into |
|
3163 consideration (i.e. it does not compute an average of those pixels). |
|
3164 As a consequence, this will generate bad shrunk images when the original contains |
|
3165 sharp lines." |
|
3166 |
|
3167 |scalePoint mX mY |
3160 newWidth "{ Class: SmallInteger }" |
3168 newWidth "{ Class: SmallInteger }" |
3161 newHeight "{ Class: SmallInteger }" |
3169 newHeight "{ Class: SmallInteger }" |
3162 w "{ Class: SmallInteger }" |
3170 w "{ Class: SmallInteger }" |
3163 h "{ Class: SmallInteger }" |
3171 h "{ Class: SmallInteger }" |
3164 newImage newBytes |
3172 newImage newBytes newMask |
3165 value "{ Class: SmallInteger }" |
3173 value "{ Class: SmallInteger }" |
3166 srcRowIdx "{ Class: SmallInteger }" |
3174 srcRowIdx "{ Class: SmallInteger }" |
3167 srcIndex "{ Class: SmallInteger }" |
3175 srcIndex "{ Class: SmallInteger }" |
3168 dstIndex "{ Class: SmallInteger }" |
3176 dstIndex "{ Class: SmallInteger }"| |
3169 newMask| |
3177 |
3170 |
3178 scalePoint := scaleArg asPoint. |
3171 mX := scalePoint x. |
3179 mX := scalePoint x. |
3172 mY := scalePoint y. |
3180 mY := scalePoint y. |
3173 ((mX < 0) or:[mY < 0]) ifTrue:[^ nil]. |
3181 ((mX < 0) or:[mY < 0]) ifTrue:[^ nil]. |
3174 ((mX = 1) and:[mY = 1]) ifTrue:[^ self]. |
3182 ((mX = 1) and:[mY = 1]) ifTrue:[^ self]. |
3175 |
3183 |