Package net.algart.matrices.morphology

Source Code of net.algart.matrices.morphology.RankOperationProcessor

/*
* The MIT License (MIT)
*
* Copyright (c) 2007-2014 Daniel Alievsky, AlgART Laboratory (http://algart.net)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package net.algart.matrices.morphology;

import net.algart.arrays.*;
import net.algart.math.functions.Func;
import net.algart.math.patterns.Pattern;
import net.algart.math.patterns.UniformGridPattern;
import net.algart.matrices.StreamingApertureProcessor;

import java.util.List;
import java.util.ArrayList;

abstract class RankOperationProcessor extends StreamingApertureProcessor {
    static final int BUFFER_BLOCK_SIZE = 65536;
    static boolean OPTIMIZE_GET_DATA = Arrays.SystemSettings.getBooleanProperty(
        "net.algart.matrices.morphology.RankMorphology.optimizeGetData", true);
    static boolean OPTIMIZE_DIRECT_ARRAYS = Arrays.SystemSettings.getBooleanProperty(
        "net.algart.matrices.morphology.RankMorphology.optimizeDirectArrays", true);
    static boolean INLINE_ONE_LEVEL = Arrays.SystemSettings.getBooleanProperty(
        "net.algart.matrices.morphology.RankMorphology.inlineOneLevel", true);
    static boolean OPTIMIZE_SEGMENTS_ALONG_AXES = Arrays.SystemSettings.getBooleanProperty(
        "net.algart.matrices.morphology.RankMorphology.optimizeSegmentsAlongAxes", true);
    static boolean SPECIAL_OPTIMIZE_THIN_PATTERNS_POWERS_OF_TWO = Arrays.SystemSettings.getBooleanProperty(
        "net.algart.matrices.morphology.RankMorphology.specialOptimizeThinPatternsPowersOfTwo", true);
    // - these constants are not final to allow changing via reflection in special tests

    final int[] bitLevels; // we never change them, so the standard cloning scheme is suitable
    final int numberOfAnalyzedBits;

    RankOperationProcessor(ArrayContext context, int[] bitLevels) {
        super(context);
        if (bitLevels == null)
            throw new NullPointerException("Null bitLevels argument");
        if (bitLevels.length == 0)
            throw new IllegalArgumentException("Empty bitLevels argument");
        bitLevels = bitLevels.clone();
        // clone before checking to guarantee correct check while multithreading
        Histogram.newIntHistogram(0, bitLevels); // checking bitLevels
        this.numberOfAnalyzedBits = bitLevels[bitLevels.length - 1];
        if (this.numberOfAnalyzedBits > CustomRankPrecision.MAX_NUMBER_OF_ANALYZED_BITS)
            throw new IllegalArgumentException("Last bitLevel is greater than "
                + CustomRankPrecision.MAX_NUMBER_OF_ANALYZED_BITS);
        this.bitLevels = JArrays.copyOfRange(bitLevels, 0, bitLevels.length - 1);
    }

    public final int[] bitLevels() {
        int[] result = new int[bitLevels.length + 1];
        System.arraycopy(bitLevels, 0, result, 0, bitLevels.length);
        result[bitLevels.length] = numberOfAnalyzedBits;
        return result;
    }

    @Override
    public final <T extends PArray> Matrix<T> asProcessed(Class<? extends T> requiredType,
        Matrix<? extends PArray> src,
        List<? extends Matrix<? extends PArray>> additionalMatrices,
        Pattern pattern)
    {
        if (additionalMatrices == null)
            throw new NullPointerException("Null additionalMatrices argument");
        additionalMatrices = new ArrayList<Matrix<? extends PArray>>(additionalMatrices);
        // - to avoid changing by parallel threads
        checkArguments(src, src, additionalMatrices, pattern);
        PArray srcArray = src.array();
        long[] dimensions = src.dimensions();
        PArray[] additionalArrays = new PArray[additionalMatrices.size()];
        for (int k = 0; k < additionalArrays.length; k++) {
            additionalArrays[k] = additionalMatrices.get(k).array();
        }
        long size = srcArray.length();
        long[] shifts = BasicMorphology.toShifts(null, size, dimensions, pattern, false);
        if (shifts.length == 0)
            throw new AssertionError("Empty pattern: it is impossible");
        UniformGridPattern roundedPattern = pattern.round();
        long[] leftShifts = BasicMorphology.toShifts(null, size, dimensions, roundedPattern.lowerSurface(0), false);
        long[] rightShifts = BasicMorphology.toShifts(null, size, dimensions, roundedPattern.upperSurface(0), false);
        if (leftShifts.length != rightShifts.length)
            throw new AssertionError("Unbalanced pattern.lowerSurface / pattern.upperSurface: different lengths");
        PArray processed = asProcessed(requiredType, srcArray, additionalArrays, dimensions,
            shifts, leftShifts, rightShifts);
        T result;
        if (processed.type() != requiredType) { // in particular, if requiredType is not one of 9 basic interfaces
            result = Arrays.asFuncArray(true, Func.IDENTITY, requiredType, processed);
        } else {
            result = requiredType.cast(processed);
        }
        return Matrices.matrix(result, dimensions);
    }

    // desiredType can be ignored: in any case, the result wil be casted to it.
    // But it is possible to optimize calculations by correct creating the array of necessary type.
    abstract PArray asProcessed(Class<? extends PArray> desiredType, PArray src, PArray[] additional,
        long[] dimensions, long[] shifts, long[] left, long[] right);
}
TOP

Related Classes of net.algart.matrices.morphology.RankOperationProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.