| 1079 | /// |
| 1080 | /// mask object that can be used with applyMask |
| 1081 | public Object createMask() { |
| 1082 | int[] rgb = getRGBCached(); |
| 1083 | int rlen = rgb.length; |
| 1084 | byte[] mask; |
| 1085 | if (isSimdOptimizationsEnabled() && rlen >= 16) { |
| 1086 | Simd simd = Simd.get(); |
| 1087 | mask = simd.allocByte(rlen); |
| 1088 | // `rgb` came from getRGBCached() / allocateRgbArray() and is therefore |
| 1089 | // a Simd-registered buffer for sizes >= 16, so we can pack straight |
| 1090 | // from it without an intermediate scratch. The previous scratch was |
| 1091 | // allocated via `allocaInt(rlen)`, which on ParparVM lowers to a |
| 1092 | // stack alloca - for image-scale rlen this overflows the per-thread |
| 1093 | // stack on iOS (e.g. a 410x410 image needs ~656 KB). |
| 1094 | simd.packIntToByteTruncate(rgb, 0, mask, 0, rlen); |
| 1095 | } else { |
| 1096 | mask = new byte[rlen]; |
| 1097 | for (int iter = 0; iter < rlen; iter++) { |
| 1098 | mask[iter] = (byte) (rgb[iter] & 0xff); |
| 1099 | } |
| 1100 | } |
| 1101 | return new IndexedImage(getWidth(), getHeight(), null, mask); |
| 1102 | } |
| 1103 | |
| 1104 | /// Applies the given alpha mask onto this image and returns the resulting image |
| 1105 | /// see the createMask method for indication on how to convert an image into an alpha |