1 18 package org.apache.batik.svggen; 19 20 import java.awt.Rectangle ; 21 import java.awt.image.BufferedImageOp ; 22 import java.awt.image.ByteLookupTable ; 23 import java.awt.image.LookupOp ; 24 import java.awt.image.LookupTable ; 25 26 import org.w3c.dom.Document ; 27 import org.w3c.dom.Element ; 28 29 40 public class SVGLookupOp extends AbstractSVGFilterConverter { 41 44 private static final double GAMMA = 1./2.4; 45 46 50 private static final int linearToSRGBLut[] = new int[256]; 51 private static final int sRGBToLinear[] = new int[256]; 52 53 static { 54 for(int i=0; i<256; i++) { 55 float value = i/255f; 57 if (value <= 0.0031308) { 58 value *= 12.92f; 59 } else { 60 value = 1.055f * ((float) Math.pow(value, GAMMA)) - 0.055f; 61 } 62 linearToSRGBLut[i] = Math.round(value*255); 63 64 value = i/255f; 66 if(value <= 0.04045){ 67 value /= 12.92f; 68 } else { 69 value = (float)Math.pow((value + 0.055f)/1.055f, 1/GAMMA); 70 } 71 72 sRGBToLinear[i] = Math.round(value*255); 73 } 74 } 75 76 79 public SVGLookupOp(SVGGeneratorContext generatorContext) { 80 super(generatorContext); 81 } 82 83 95 public SVGFilterDescriptor toSVG(BufferedImageOp filter, 96 Rectangle filterRect) { 97 if (filter instanceof LookupOp ) 98 return toSVG((LookupOp )filter); 99 else 100 return null; 101 } 102 103 109 public SVGFilterDescriptor toSVG(LookupOp lookupOp) { 110 SVGFilterDescriptor filterDesc = 112 (SVGFilterDescriptor)descMap.get(lookupOp); 113 114 Document domFactory = generatorContext.domFactory; 115 116 if (filterDesc == null) { 117 Element filterDef = domFactory.createElementNS(SVG_NAMESPACE_URI, 122 SVG_FILTER_TAG); 123 Element feComponentTransferDef = 124 domFactory.createElementNS(SVG_NAMESPACE_URI, 125 SVG_FE_COMPONENT_TRANSFER_TAG); 126 127 String lookupTables[] = convertLookupTables(lookupOp); 138 139 Element feFuncR = domFactory.createElementNS(SVG_NAMESPACE_URI, 140 SVG_FE_FUNC_R_TAG); 141 Element feFuncG = domFactory.createElementNS(SVG_NAMESPACE_URI, 142 SVG_FE_FUNC_G_TAG); 143 Element feFuncB = domFactory.createElementNS(SVG_NAMESPACE_URI, 144 SVG_FE_FUNC_B_TAG); 145 Element feFuncA = null; 146 String type = SVG_TABLE_VALUE; 147 148 if(lookupTables.length == 1){ 149 feFuncR.setAttributeNS(null, SVG_TYPE_ATTRIBUTE, type); 150 feFuncG.setAttributeNS(null, SVG_TYPE_ATTRIBUTE, type); 151 feFuncB.setAttributeNS(null, SVG_TYPE_ATTRIBUTE, type); 152 feFuncR.setAttributeNS(null, SVG_TABLE_VALUES_ATTRIBUTE, 153 lookupTables[0]); 154 feFuncG.setAttributeNS(null, SVG_TABLE_VALUES_ATTRIBUTE, 155 lookupTables[0]); 156 feFuncB.setAttributeNS(null, SVG_TABLE_VALUES_ATTRIBUTE, 157 lookupTables[0]); 158 } 159 else if(lookupTables.length >= 3){ 160 feFuncR.setAttributeNS(null, SVG_TYPE_ATTRIBUTE, type); 161 feFuncG.setAttributeNS(null, SVG_TYPE_ATTRIBUTE, type); 162 feFuncB.setAttributeNS(null, SVG_TYPE_ATTRIBUTE, type); 163 feFuncR.setAttributeNS(null, SVG_TABLE_VALUES_ATTRIBUTE, 164 lookupTables[0]); 165 feFuncG.setAttributeNS(null, SVG_TABLE_VALUES_ATTRIBUTE, 166 lookupTables[1]); 167 feFuncB.setAttributeNS(null, SVG_TABLE_VALUES_ATTRIBUTE, 168 lookupTables[2]); 169 170 if(lookupTables.length == 4){ 171 feFuncA = domFactory.createElementNS(SVG_NAMESPACE_URI, 172 SVG_FE_FUNC_A_TAG); 173 feFuncA.setAttributeNS(null, SVG_TYPE_ATTRIBUTE, type); 174 feFuncA.setAttributeNS(null, SVG_TABLE_VALUES_ATTRIBUTE, 175 lookupTables[3]); 176 } 177 } 178 179 feComponentTransferDef.appendChild(feFuncR); 180 feComponentTransferDef.appendChild(feFuncG); 181 feComponentTransferDef.appendChild(feFuncB); 182 if(feFuncA != null) 183 feComponentTransferDef.appendChild(feFuncA); 184 185 filterDef.appendChild(feComponentTransferDef); 186 187 filterDef. 188 setAttributeNS(null, ATTR_ID, 189 generatorContext.idGenerator. 190 generateID(ID_PREFIX_FE_COMPONENT_TRANSFER)); 191 195 StringBuffer filterAttrBuf = new StringBuffer (URL_PREFIX); 197 filterAttrBuf.append(SIGN_POUND); 198 filterAttrBuf.append(filterDef.getAttributeNS(null, ATTR_ID)); 199 filterAttrBuf.append(URL_SUFFIX); 200 201 filterDesc = new SVGFilterDescriptor(filterAttrBuf.toString(), 202 filterDef); 203 204 defSet.add(filterDef); 205 descMap.put(lookupOp, filterDesc); 206 } 207 208 return filterDesc; 209 } 210 211 215 private String [] convertLookupTables(LookupOp lookupOp){ 216 LookupTable lookupTable = lookupOp.getTable(); 217 int nComponents = lookupTable.getNumComponents(); 218 219 if((nComponents != 1) && (nComponents != 3) && (nComponents != 4)) 220 throw new SVGGraphics2DRuntimeException(ERR_ILLEGAL_BUFFERED_IMAGE_LOOKUP_OP); 221 222 StringBuffer lookupTableBuf[] = new StringBuffer [nComponents]; 223 for(int i=0; i<nComponents; i++) 224 lookupTableBuf[i] = new StringBuffer (); 225 226 if(!(lookupTable instanceof ByteLookupTable )){ 227 int src[] = new int[nComponents]; 228 int dest[] = new int[nComponents]; 229 int offset = lookupTable.getOffset(); 230 231 for(int i=0; i<offset; i++){ 236 for(int j=0; j<nComponents; j++){ 238 lookupTableBuf[j].append(doubleString(i/255.)); 240 lookupTableBuf[j].append(SPACE); 241 } 242 } 243 244 for(int i=offset; i<=255; i++){ 245 for(int j=0; j<nComponents; j++) src[j] = i; 247 248 lookupTable.lookupPixel(src, dest); 250 251 for(int j=0; j<nComponents; j++){ 253 lookupTableBuf[j].append(doubleString(dest[j]/255.)); 254 lookupTableBuf[j].append(SPACE); 256 } 257 } 258 } 259 else{ 260 byte src[] = new byte[nComponents]; 261 byte dest[] = new byte[nComponents]; 262 263 int offset = lookupTable.getOffset(); 264 265 for(int i=0; i<offset; i++){ 270 for(int j=0; j<nComponents; j++){ 272 lookupTableBuf[j].append(doubleString(i/255.)); 274 lookupTableBuf[j].append(SPACE); 275 } 276 } 277 for(int i=0; i<=255; i++){ 278 for(int j=0; j<nComponents; j++) { 280 src[j] = (byte)(0xff & i); 281 } 282 283 ((ByteLookupTable )lookupTable).lookupPixel(src, dest); 285 286 for(int j=0; j<nComponents; j++){ 288 lookupTableBuf[j].append(doubleString((0xff & dest[j])/255.)); 289 lookupTableBuf[j].append(SPACE); 290 } 291 } 292 } 293 294 String lookupTables[] = new String [nComponents]; 295 for(int i=0; i<nComponents; i++) 296 lookupTables[i] = lookupTableBuf[i].toString().trim(); 297 298 301 302 return lookupTables; 303 } 304 } 305 | Popular Tags |