private void specialProcessRow()

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


    private void specialProcessRow(Raster src, WritableRaster dest){
        final int w = src.getWidth();
        final int h = src.getHeight();

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

        // Offset defines where in the stack the real data begin
        SinglePixelPackedSampleModel sppsm;
        sppsm = (SinglePixelPackedSampleModel)src.getSampleModel();

        final int srcOff = srcDB.getOffset() +
            sppsm.getOffset(src.getMinX() - src.getSampleModelTranslateX(),
                            src.getMinY() - src.getSampleModelTranslateY());


        sppsm = (SinglePixelPackedSampleModel)dest.getSampleModel();
        final int dstOff = dstDB.getOffset() +
            sppsm.getOffset(dest.getMinX() - dest.getSampleModelTranslateX(),
                            dest.getMinY() - dest.getSampleModelTranslateY());

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

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

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

        // 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;

        // If image width is less than or equal to the radiusX,
        // all the pixels share the same max/min value
        if (w<=radiusX){
            for (int i=0; i<h; i++){
                // pointing to the first pixels of each row
                sp = srcOff + i*srcScanStride;
                dp = dstOff + i*dstScanStride;
                pel = srcPixels[sp++];
                a = pel>>>24;
                r = pel&0xff0000;
                g = pel&0xff00;
                b = pel&0xff;

                for (int k=1; k<w; k++){
                    currentPixel = srcPixels[sp++];
                    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;
                    }
                }
                // all the element share the same max/min value
                for (int k=0; k<w; k++){
                    destPixels[dp++] = (a << 24) | r | g | b;
                }
            }
        }

        // When radiusX < w <= 2*radiusX
        else {

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

            for (int i=0; i<h; i++){
                // initialization of pointers, indice
                // at the head of each row
                sp = srcOff + i*srcScanStride;
                dp = dstOff + i*dstScanStride;

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

                pel = srcPixels[sp++];
                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<=radiusX; k++){
                    currentPixel = srcPixels[sp++];
                    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;
                    }
                }
                destPixels[dp++] = (a << 24) | r | g | b;

                //
                // 1 <= j <= w-radiusX-1 : The left margin of each row.
                //
                for (int j=1; j<=w-radiusX-1; j++){
                    lastPixel = srcPixels[sp++];

                    // here is the Alpha channel

                    // we retrieve the previous max/min value
                    a = bufferA[maxIndexA];
                    a1 = lastPixel>>>24;
                    bufferA[j+radiusX] = a1;
                    if (isBetter(a1, a, doDilation)){
                        a = a1;
                        maxIndexA = j+radiusX;
                    }

                    // now we deal with the Red channel

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

                    // now we deal with the Green channel

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

                    // now we deal with the Blue channel

                    b = bufferB[maxIndexB];
                    b1 = lastPixel&0xff;
                    bufferB[j+radiusX] = b1;
                    if (isBetter(b1, b, doDilation)){
                        b = b1;
                        maxIndexB = j+radiusX;
                    }
                    // 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;
                }
                // Now is the inner body of the row:
                // all elements in this segment share the same max/min value
                for (int j = w-radiusX; j<= radiusX; j++){
                    destPixels[dp] = destPixels[dp-1];
                    dp++;
                }
                // Now the circular buffer is full
                // Now is the right margin of the row when radiusX < w <= 2*radiusX
                for (int j = radiusX+1; j<w; j++){

                    if (maxIndexA == bufferHead){
                        a = bufferA[bufferHead+1];
                        maxIndexA = bufferHead+1;
                        for (int m= bufferHead+2; m< w; 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< w; 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< w; 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< w; 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;
                }
                // return to the first pixel of the next row
            }
        }// When radiusX < w <=2*radiusX
    }