/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @author Igor V. Stolyarov */ package com.google.code.appengine.awt.image; import java.util.Hashtable; import org.apache.harmony.awt.internal.nls.Messages; import com.google.code.appengine.awt.image.ColorModel; import com.google.code.appengine.awt.image.ImageFilter; public class ReplicateScaleFilter extends ImageFilter { protected int srcWidth; protected int srcHeight; protected int destWidth; protected int destHeight; protected int[] srcrows; protected int[] srccols; protected Object outpixbuf; public ReplicateScaleFilter(int width, int height) { if(width == 0 || height == 0) { // awt.234=Width or Height equals zero throw new IllegalArgumentException(Messages.getString("awt.234")); //$NON-NLS-1$ } this.destWidth = width; this.destHeight = height; } @SuppressWarnings("unchecked") @Override public void setProperties(Hashtable<?, ?> props) { Hashtable<Object, Object> fprops; if(props == null) { fprops = new Hashtable<Object, Object>(); } else { fprops = (Hashtable<Object, Object>) props.clone(); } String propName = "Rescale Filters"; //$NON-NLS-1$ String prop = "destWidth=" + destWidth + "; " + //$NON-NLS-1$ //$NON-NLS-2$ "destHeight=" + destHeight; //$NON-NLS-1$ Object o = fprops.get(propName); if(o != null){ if(o instanceof String){ prop = (String)o + "; " + prop; //$NON-NLS-1$ }else{ prop = o.toString() + "; " + prop; //$NON-NLS-1$ } } fprops.put(propName, prop); consumer.setProperties(fprops); } // setPixels methods produce pixels according to Java API Specification @Override public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize) { if(srccols == null) { initArrays(); } int buff[]; if(outpixbuf == null || !(outpixbuf instanceof int[])){ buff = new int[destWidth]; outpixbuf = buff; }else{ buff = (int[])outpixbuf; } int wa = (srcWidth - 1) >>> 1; int ha = (srcHeight - 1) >>> 1; int dstX = (x * destWidth + wa) / srcWidth; int dstY = (y * destHeight + ha) / srcHeight; int sx, sy, dx, dy; dy = dstY; while((dy < destHeight) && ((sy = srcrows[dy]) < y + h)){ dx = dstX; int srcOff = off + (sy - y) * scansize; while((dx < destWidth) && ((sx = srccols[dx]) < x + w)){ buff[dx] = pixels[srcOff + (sx - x)]; dx++; } consumer.setPixels(dstX, dy, dx - dstX, 1, model, buff, dstX, destWidth); dy++; } } @Override public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize) { if(srccols == null) { initArrays(); } byte buff[]; if(outpixbuf == null || !(outpixbuf instanceof byte[])){ buff = new byte[destWidth]; outpixbuf = buff; }else{ buff = (byte[])outpixbuf; } int wa = (srcWidth - 1) >>> 1; int ha = (srcHeight - 1) >>> 1; int dstX = (x * destWidth + wa) / srcWidth; int dstY = (y * destHeight + ha) / srcHeight; int sx, sy, dx, dy; dy = dstY; while((dy < destHeight) && ((sy = srcrows[dy]) < y + h)){ dx = dstX; int srcOff = off + (sy - y) * scansize; while((dx < destWidth) && ((sx = srccols[dx]) < x + w)){ buff[dx] = pixels[srcOff + (sx - x)]; dx++; } consumer.setPixels(dstX, dy, dx - dstX, 1, model, buff, dstX, destWidth); dy++; } } @Override public void setDimensions(int w, int h) { srcWidth = w; srcHeight = h; if(destWidth < 0 && destHeight < 0){ destWidth = srcWidth; destHeight = srcHeight; }else if(destWidth < 0){ destWidth = destHeight * srcWidth / srcHeight; }else if(destHeight < 0){ destHeight = destWidth * srcHeight / srcWidth; } consumer.setDimensions(destWidth, destHeight); } /** * Initialization of srccols and srcrows arrays */ private void initArrays(){ if ((destWidth < 0) || (destHeight < 0)) { throw new IndexOutOfBoundsException(); } srccols = new int[destWidth]; int ca = srcWidth >>> 1; for(int i = 0; i < destWidth; i++){ srccols[i] = (i * srcWidth + ca) / destWidth; } srcrows = new int[destHeight]; int ra = srcHeight >>> 1; for(int i = 0; i < destHeight; i++){ srcrows[i] = (i * srcHeight + ra) / destHeight; } } }