private void specialProcessColumn()

in batik-awt-util/src/main/java/org/apache/batik/ext/awt/image/rendered/MorphologyOp.java [539:818]


    private void specialProcessColumn(Raster src, WritableRaster dest){

        final int w = src.getWidth();
        final int h = src.getHeight();

        // Access the integer buffer for each image.
        DataBufferInt dstDB = (DataBufferInt)dest.getDataBuffer();

        // Offset defines where in the stack the real data begin
        final int dstOff = dstDB.getOffset();

        // Stride is the distance between two consecutive column elements,
        // in the one-dimention dataBuffer
        final int dstScanStride = ((SinglePixelPackedSampleModel)dest.getSampleModel()).getScanlineStride();

        // Access the pixel value array
        final int[] destPixels = dstDB.getBankData()[0];

        // The pointer of src and dest indicating where the pixel values are
        int dp, cp;

        // Declaration for the circular buffer's implementation
        // These are the circular buffers' head pointer and
        // the index pointers

        // bufferHead points to the leftmost element in the circular buffer
        int bufferHead;

        int maxIndexA;
        int maxIndexR;
        int maxIndexG;
        int maxIndexB;

        // Temp variables
        int pel, currentPixel, lastPixel;
        int a,r,g,b;
        int a1,r1,g1,b1;

        // Here all the pixels share the same
        // max/min value
        if (h<=radiusY){
            for (int j=0; j<w; j++){
                dp = dstOff + j;
                cp = dstOff + j;
                pel = destPixels[cp];
                cp += dstScanStride;
                a = pel>>>24;
                r = pel&0xff0000;
                g = pel&0xff00;
                b = pel&0xff;

                for (int k=1; k<h; k++){
                    currentPixel = destPixels[cp];
                    cp += dstScanStride;
                    a1 = currentPixel>>>24;
                    r1 = currentPixel&0xff0000;
                    g1 = currentPixel&0xff00;
                    b1 = currentPixel&0xff;

                    if (isBetter(a1, a, doDilation)){
                        a = a1;
                    }
                    if (isBetter(r1, r, doDilation)){
                        r = r1;
                    }
                    if (isBetter(g1, g, doDilation)){
                        g = g1;
                    }
                    if (isBetter(b1, b, doDilation)){
                        b = b1;
                    }
                }
                for (int k=0; k<h; k++){
                    destPixels[dp] = (a << 24) | r | g | b;
                    dp += dstScanStride;
                }
                // return to the first pixel of the next column
            }
        }

        // When radiusY < h <= 2*radiusY
        else {

            // The height of the circular buffer is h
            final int [] bufferA = new int [h];
            final int [] bufferR = new int [h];
            final int [] bufferG = new int [h];
            final int [] bufferB = new int [h];

            for (int j=0; j<w; j++){
                // initialization of pointers, indice
                // at the head of each column
                dp = dstOff + j;
                cp = dstOff + j;

                bufferHead = 0;
                maxIndexA = 0;
                maxIndexR = 0;
                maxIndexG = 0;
                maxIndexB = 0;

                pel = destPixels[cp];
                cp += dstScanStride;
                a = pel>>>24;
                r = pel&0xff0000;
                g = pel&0xff00;
                b = pel&0xff;
                bufferA[0] = a;
                bufferR[0] = r;
                bufferG[0] = g;
                bufferB[0] = b;

                for (int k=1; k<=radiusY; k++){
                    currentPixel = destPixels[cp];
                    cp += dstScanStride;
                    a1 = currentPixel>>>24;
                    r1 = currentPixel&0xff0000;
                    g1 = currentPixel&0xff00;
                    b1 = currentPixel&0xff;
                    bufferA[k] = a1;
                    bufferR[k] = r1;
                    bufferG[k] = g1;
                    bufferB[k] = b1;

                    if (isBetter(a1, a, doDilation)){
                        a = a1;
                        maxIndexA = k;
                    }
                    if (isBetter(r1, r, doDilation)){
                        r = r1;
                        maxIndexR = k;
                    }
                    if (isBetter(g1, g, doDilation)){
                        g = g1;
                        maxIndexG = k;
                    }
                    if (isBetter(b1, b, doDilation)){
                        b = b1;
                        maxIndexB = k;
                    }
                }
                // fill the first pixel of each column
                destPixels[dp] = (a << 24) | r | g | b;
                dp += dstScanStride;

                //
                // 1 <= i <= h-1-radiusY : The upper margin of each column.
                //
                for (int i=1; i<=h-radiusY-1; i++){
                    lastPixel = destPixels[cp];
                    cp += dstScanStride;

                    // here is the Alpha channel

                    a = bufferA[maxIndexA];
                    a1 = lastPixel>>>24;
                    bufferA[i+radiusY] = a1;
                    if (isBetter(a1, a, doDilation)){
                        a = a1;
                        maxIndexA = i+radiusY;
                    }

                    // now we deal with the Red channel

                    r = bufferR[maxIndexR];
                    r1 = lastPixel&0xff0000;
                    bufferR[i+radiusY] = r1;
                    if (isBetter(r1, r, doDilation)){
                        r = r1;
                        maxIndexR = i+radiusY;
                    }

                    // now we deal with the Green channel

                    g = bufferG[maxIndexG];
                    g1 = lastPixel&0xff00;
                    bufferG[i+radiusY] = g1;
                    if (isBetter(g1, g, doDilation)){
                        g = g1;
                        maxIndexG = i+radiusY;
                    }

                    // now we deal with the Blue channel

                    b = bufferB[maxIndexB];
                    b1 = lastPixel&0xff;
                    bufferB[i+radiusY] = b1;
                    if (isBetter(b1, b, doDilation)){
                        b = b1;
                        maxIndexB = i+radiusY;
                    }
                    // now we have gone through the four channels and
                    // updated the index array. then we'll pack the
                    // new max/min value according to each channel's
                    // max/min vlue

                    destPixels[dp] = (a << 24) | r | g | b;
                    dp += dstScanStride;
                }
                // Now is the inner body of the column
                // when radiusY < h <= 2*radiusY
                for (int i = h-radiusY; i<= radiusY; i++){
                    destPixels[dp] = destPixels[dp-dstScanStride];
                    dp += dstScanStride;
                }
                // The circular buffer is full now

                for (int i = radiusY+1; i<h; i++){

                    if (maxIndexA == bufferHead){
                        a = bufferA[bufferHead+1];
                        maxIndexA = bufferHead+1;
                        for (int m= bufferHead+2; m< h; m++){
                            a1 = bufferA[m];
                            if (isBetter(a1, a, doDilation)){
                                a = a1;
                                maxIndexA = m;
                            }
                        }
                    }
                    else {
                        a = bufferA[maxIndexA];
                    }
                    if (maxIndexR == bufferHead){
                        r = bufferR[bufferHead+1];
                        maxIndexR = bufferHead+1;
                        for (int m= bufferHead+2; m< h; m++){
                            r1 = bufferR[m];
                            if (isBetter(r1, r, doDilation)){
                                r = r1;
                                maxIndexR = m;
                            }
                        }
                    }
                    else {
                        r = bufferR[maxIndexR];
                    }

                    if (maxIndexG == bufferHead){
                        g = bufferG[bufferHead+1];
                        maxIndexG = bufferHead+1;
                        for (int m= bufferHead+2; m< h; m++){
                            g1 = bufferG[m];
                            if (isBetter(g1, g, doDilation)){
                                g = g1;
                                maxIndexG = m;
                            }
                        }
                    }
                    // we can reuse the previous max/min value
                    else {
                        g = bufferG[maxIndexG];
                    }

                    if (maxIndexB == bufferHead){
                        b = bufferB[bufferHead+1];
                        maxIndexB = bufferHead+1;
                        for (int m= bufferHead+2; m< h; m++){
                            b1 = bufferB[m];
                            if (isBetter(b1, b, doDilation)){
                                b = b1;
                                maxIndexB = m;
                            }
                        }
                    }
                    // we can reuse the previous max/min value
                    else {
                        b = bufferB[maxIndexB];
                    }

                    // discard the leftmost element
                    bufferHead++;

                    destPixels[dp] = (a << 24) | r | g | b;
                    dp += dstScanStride;
                }
                // return to the first pixel of the next column
            }
        } // when radiusY < h <= 2*radiusY
    }