1 18 package org.apache.batik.ext.awt.image.rendered; 19 20 import java.awt.Rectangle ; 21 import java.awt.Transparency ; 22 import java.awt.color.ColorSpace ; 23 import java.awt.image.ColorModel ; 24 import java.awt.image.ComponentColorModel ; 25 import java.awt.image.ComponentSampleModel ; 26 import java.awt.image.DataBuffer ; 27 import java.awt.image.DataBufferByte ; 28 import java.awt.image.DataBufferInt ; 29 import java.awt.image.PixelInterleavedSampleModel ; 30 import java.awt.image.Raster ; 31 import java.awt.image.SampleModel ; 32 import java.awt.image.SinglePixelPackedSampleModel ; 33 import java.awt.image.WritableRaster ; 34 import java.util.ArrayList ; 35 import java.util.List ; 36 37 38 44 public class MultiplyAlphaRed extends AbstractRed { 45 46 56 public MultiplyAlphaRed(CachableRed src, CachableRed alpha) { 57 super(makeList(src, alpha), 58 makeBounds(src,alpha), 59 fixColorModel(src), 60 fixSampleModel(src), 61 src.getTileGridXOffset(), 62 src.getTileGridYOffset(), 63 null); 64 } 65 66 public boolean is_INT_PACK_BYTE_COMP(SampleModel srcSM, 67 SampleModel alpSM) { 68 if(!(srcSM instanceof SinglePixelPackedSampleModel )) return false; 70 if(!(alpSM instanceof ComponentSampleModel )) return false; 71 72 if(srcSM.getDataType() != DataBuffer.TYPE_INT) return false; 74 if(alpSM.getDataType() != DataBuffer.TYPE_BYTE) return false; 75 76 77 SinglePixelPackedSampleModel sppsm; 78 sppsm = (SinglePixelPackedSampleModel )srcSM; 79 80 int [] masks = sppsm.getBitMasks(); 81 if(masks.length != 4) return false; 82 if(masks[0] != 0x00ff0000) return false; 83 if(masks[1] != 0x0000ff00) return false; 84 if(masks[2] != 0x000000ff) return false; 85 if(masks[3] != 0xff000000) return false; 86 87 ComponentSampleModel csm; 88 csm = (ComponentSampleModel )alpSM; 89 if (csm.getNumBands() != 1) return false; 90 if (csm.getPixelStride() != 1) return false; 91 92 return true; 93 } 94 95 public WritableRaster INT_PACK_BYTE_COMP_Impl (WritableRaster wr) { 96 CachableRed srcRed = (CachableRed)getSources().get(0); 98 CachableRed alphaRed = (CachableRed)getSources().get(1); 99 100 srcRed.copyData(wr); 102 103 Rectangle rgn = wr.getBounds(); 104 rgn = rgn.intersection(alphaRed.getBounds()); 105 106 Raster r = alphaRed.getData(rgn); 107 108 ComponentSampleModel csm; 109 csm = (ComponentSampleModel )r.getSampleModel(); 110 final int alpScanStride = csm.getScanlineStride(); 111 112 DataBufferByte alpDB = (DataBufferByte )r.getDataBuffer(); 113 final int alpBase 114 = (alpDB.getOffset() + 115 csm.getOffset(rgn.x-r.getSampleModelTranslateX(), 116 rgn.y-r.getSampleModelTranslateY())); 117 118 119 final byte alpPixels[] = alpDB.getBankData()[0]; 121 122 SinglePixelPackedSampleModel sppsm; 123 sppsm = (SinglePixelPackedSampleModel )wr.getSampleModel(); 124 final int srcScanStride = sppsm.getScanlineStride(); 125 126 DataBufferInt srcDB = (DataBufferInt )wr.getDataBuffer(); 127 final int srcBase 128 = (srcDB.getOffset() + 129 sppsm.getOffset(rgn.x-wr.getSampleModelTranslateX(), 130 rgn.y-wr.getSampleModelTranslateY())); 131 132 final int srcPixels[] = srcDB.getBankData()[0]; 134 135 ColorModel cm = srcRed.getColorModel(); 136 137 if (cm.isAlphaPremultiplied()) { 138 for (int y=0; y<rgn.height; y++) { 140 int sp = srcBase + y*srcScanStride; 141 int ap = alpBase + y*alpScanStride; 142 int end = sp + rgn.width; 143 144 while (sp<end) { 145 int a = ((int)alpPixels[ap++])&0xFF; 146 final int pix = srcPixels[sp]; 147 srcPixels[sp] = 148 ((((((pix>>>24) ) *a)&0xFF00)<<16) | 149 (((((pix>>>16)&0xFF) *a)&0xFF00)<<8 ) | 150 (((((pix>>> 8)&0xFF) *a)&0xFF00) ) | 151 (((((pix )&0xFF) *a)&0xFF00)>>8 )); 152 sp++; 153 } 154 } 155 156 } else { 157 for (int y=0; y<rgn.height; y++) { 159 int sp = srcBase + y*srcScanStride; 160 int ap = alpBase + y*alpScanStride; 161 int end = sp + rgn.width; 162 while (sp<end) { 163 int a = ((int)alpPixels[ap++])&0xFF; 164 int sa = srcPixels[sp]>>>24; 165 srcPixels[sp] = ((((sa*a) & 0xFF00)<<16)| 166 srcPixels[sp]&0x00FFFFFF); 167 sp++; 168 } 169 } 170 } 171 172 return wr; 173 } 174 175 public WritableRaster copyData(WritableRaster wr) { 176 CachableRed srcRed = (CachableRed)getSources().get(0); 178 CachableRed alphaRed = (CachableRed)getSources().get(1); 179 180 if (is_INT_PACK_BYTE_COMP(srcRed.getSampleModel(), 181 alphaRed.getSampleModel())) 182 return INT_PACK_BYTE_COMP_Impl(wr); 183 184 ColorModel cm = srcRed.getColorModel(); 185 if (cm.hasAlpha()) { 186 srcRed.copyData(wr); 188 189 Rectangle rgn = wr.getBounds(); 190 if (rgn.intersects(alphaRed.getBounds())) 191 rgn = rgn.intersection(alphaRed.getBounds()); 192 else 193 return wr; 194 195 int [] wrData = null; 196 int [] alphaData = null; 197 198 Raster r = alphaRed.getData(rgn); 199 int w = rgn.width; 200 201 final int bands = wr.getSampleModel().getNumBands(); 202 203 if (cm.isAlphaPremultiplied()) { 204 for (int y=rgn.y; y<rgn.y+rgn.height; y++) { 205 wrData = wr.getPixels (rgn.x, y, w, 1, wrData); 206 alphaData = r .getSamples(rgn.x, y, w, 1, 0, alphaData); 207 int i=0, a, b; 208 switch (bands) { 211 case 2: 212 for (int x=0; x<alphaData.length; x++) { 213 a = alphaData[x]&0xFF; 214 wrData[i] = ((wrData[i]&0xFF)*a)>>8; ++i; 215 wrData[i] = ((wrData[i]&0xFF)*a)>>8; ++i; 216 } 217 break; 218 case 4: 219 for (int x=0; x<alphaData.length; x++) { 220 a = alphaData[x]&0xFF; 221 wrData[i] = ((wrData[i]&0xFF)*a)>>8; ++i; 222 wrData[i] = ((wrData[i]&0xFF)*a)>>8; ++i; 223 wrData[i] = ((wrData[i]&0xFF)*a)>>8; ++i; 224 wrData[i] = ((wrData[i]&0xFF)*a)>>8; ++i; 225 } 226 break; 227 default: 228 for (int x=0; x<alphaData.length; x++) { 229 a = alphaData[x]&0xFF; 230 for (b=0; b<bands; b++) { 231 wrData[i] = ((wrData[i]&0xFF)*a)>>8; 232 ++i; 233 } 234 } 235 } 236 wr.setPixels(rgn.x, y, w, 1, wrData); 237 } 238 } else { 239 int b = srcRed.getSampleModel().getNumBands()-1; 240 for (int y=rgn.y; y<rgn.y+rgn.height; y++) { 241 wrData = wr.getSamples(rgn.x, y, w, 1, b, wrData); 242 alphaData = r .getSamples(rgn.x, y, w, 1, 0, alphaData); 243 for (int i=0; i<wrData.length; i++) { 244 wrData[i] = ((wrData[i]&0xFF)*(alphaData[i]&0xFF))>>8; 245 } 246 wr.setSamples(rgn.x, y, w, 1, b, wrData); 247 } 248 } 249 250 return wr; 251 } 252 253 int [] bands = new int[wr.getNumBands()-1]; 256 for (int i=0; i<bands.length; i++) 257 bands[i] = i; 258 259 WritableRaster subWr; 260 subWr = wr.createWritableChild(wr.getMinX(), wr.getMinY(), 261 wr.getWidth(), wr.getHeight(), 262 wr.getMinX(), wr.getMinY(), 263 bands); 264 265 srcRed.copyData(subWr); 266 267 Rectangle rgn = wr.getBounds(); 268 rgn = rgn.intersection(alphaRed.getBounds()); 269 270 271 bands = new int [] { wr.getNumBands()-1 }; 272 subWr = wr.createWritableChild(rgn.x, rgn.y, 273 rgn.width, rgn.height, 274 rgn.x, rgn.y, 275 bands); 276 alphaRed.copyData(subWr); 277 278 return wr; 279 } 280 281 public static List makeList(CachableRed src1, CachableRed src2) { 282 List ret = new ArrayList (2); 283 ret.add(src1); 284 ret.add(src2); 285 return ret; 286 } 287 288 public static Rectangle makeBounds(CachableRed src1, CachableRed src2) { 289 Rectangle r1 = src1.getBounds(); 290 Rectangle r2 = src2.getBounds(); 291 return r1.intersection(r2); 292 } 293 294 public static SampleModel fixSampleModel(CachableRed src) { 295 ColorModel cm = src.getColorModel(); 296 SampleModel srcSM = src.getSampleModel(); 297 298 if (cm.hasAlpha()) 299 return srcSM; 300 301 int w = srcSM.getWidth(); 302 int h = srcSM.getHeight(); 303 int b = srcSM.getNumBands()+1; 304 int [] offsets = new int[b]; 305 for (int i=0; i < b; i++) 306 offsets[i] = i; 307 308 return new PixelInterleavedSampleModel (DataBuffer.TYPE_BYTE, 310 w, h, b, w*b, offsets); 311 } 312 313 public static ColorModel fixColorModel(CachableRed src) { 314 ColorModel cm = src.getColorModel(); 315 316 if (cm.hasAlpha()) 317 return cm; 318 319 int b = src.getSampleModel().getNumBands()+1; 320 int [] bits = new int[b]; 321 for (int i=0; i < b; i++) 322 bits[i] = 8; 323 324 ColorSpace cs = cm.getColorSpace(); 325 326 return new ComponentColorModel (cs, bits, true, false, 327 Transparency.TRANSLUCENT, 328 DataBuffer.TYPE_BYTE); 329 } 330 } 331 | Popular Tags |