Performs wavelet shrinking using the specified rule and by computing a threshold
for each subband.

@param transform The image being transformed.
@param numLevels Number of levels in the transform.
970236
protected void performShrinkage( I transform , int numLevels ) {

		// step through each layer in the pyramid.
		for( int i = 0; i < numLevels; i++ ) {
			int w = transform.width;
			int h = transform.height;
			int ww = w/2;
			int hh = h/2;
			Number threshold;
			I subband;

			// HL
			subband = transform.subimage(ww,0,w,hh, null);
			threshold = computeThreshold(subband);
			rule.process(subband,threshold);

//			System.out.print("HL = "+threshold);

			// LH
			subband = transform.subimage(0,hh,ww,h, null);
			threshold = computeThreshold(subband);
			rule.process(subband,threshold);

//			System.out.print("  LH = "+threshold);

			// HH
			subband = transform.subimage(ww,hh,w,h, null);
			threshold = computeThreshold(subband);
			rule.process(subband,threshold);

//			System.out.println("  HH = "+threshold);

			transform = transform.subimage(0,0,ww,hh, null);
		}

	}
984864
private void removeMapping(int num) {
		if (num < numMappings) {
			System.arraycopy(mappings, num * 2, mappings, (num - 1) * 2, (numMappings - num) * 2);
		}
		mappings[numMappings * 2 - 1] = null;
		mappings[numMappings * 2 - 2] = null;
		numMappings--;
	}
409772
private static void processBufferedImage(BufferedImage buffimage,
            String formatName, NodeList nodes) throws Exception {
        HashMap<Object, Object> bandMap = new HashMap<Object, Object>();

        for (int i = 0; i < nodes.getLength(); i++) {
            Node node = nodes.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                if (node.getLocalName().equals("subimage")) {
                    Element e = (Element) node;
                    int x = Integer.parseInt(e.getAttribute("x"));
                    int y = Integer.parseInt(e.getAttribute("y"));
                    int w = Integer.parseInt(e.getAttribute("width"));
                    int h = Integer.parseInt(e.getAttribute("height"));
                    processBufferedImage(buffimage.getSubimage(x, y, w, h),
                            formatName, e.getChildNodes());
                } else if (node.getLocalName().equals("checksum")) {
                    CRC32 checksum = new CRC32();
                    Raster raster = buffimage.getRaster();
                    DataBufferByte buffer;
                    if (node.getParentNode().getLocalName().equals("subimage")) {
                        WritableRaster outRaster = raster
                                .createCompatibleWritableRaster();
                        buffimage.copyData(outRaster);
                        buffer = (DataBufferByte) outRaster.getDataBuffer();
                    } else {
                        buffer = (DataBufferByte) raster.getDataBuffer();
                    }
                    int numbanks = buffer.getNumBanks();
                    for (int j = 0; j < numbanks; j++) {
                        checksum.update(buffer.getData(j));
                    }
                    Document doc = node.getOwnerDocument();
                    node.appendChild(doc.createTextNode(Long.toString(checksum
                            .getValue())));
                } else if (node.getLocalName().equals("count")) {
                    String band = ((Element) node).getAttribute("bands");
                    String sample = ((Element) node).getAttribute("sample");
                    if (sample.equals("all")) {
                        bandMap.put(band, null);
                    } else {
                        HashMap<Object, Object> sampleMap = (HashMap<Object, Object>) bandMap
                                .get(band);
                        if (sampleMap == null && !bandMap.containsKey(band)) {
                            sampleMap = new HashMap<Object, Object>();
                            bandMap.put(band, sampleMap);
                        }
                        sampleMap.put(Integer.decode(sample), new Integer(0));
                    }
                } else if (node.getLocalName().equals("transparentNodata")) { // 2011-08-24
                                                                              // PwD
                    String transparentNodata = checkTransparentNodata(
                            buffimage, node);
                    node.setTextContent(transparentNodata);
                }
            }
        }

        Iterator bandIt = bandMap.keySet().iterator();
        while (bandIt.hasNext()) {
            String band_str = (String) bandIt.next();
            int[] band_indexes;
            if (buffimage.getType() == BufferedImage.TYPE_BYTE_BINARY
                    || buffimage.getType() == BufferedImage.TYPE_BYTE_GRAY) {
                band_indexes = new int[1];
                band_indexes[0] = 0;
            } else {
                band_indexes = new int[band_str.length()];
                for (int i = 0; i < band_str.length(); i++) {
                    if (band_str.charAt(i) == 'A')
                        band_indexes[i] = 3;
                    if (band_str.charAt(i) == 'B')
                        band_indexes[i] = 2;
                    if (band_str.charAt(i) == 'G')
                        band_indexes[i] = 1;
                    if (band_str.charAt(i) == 'R')
                        band_indexes[i] = 0;
                }
            }

            Raster raster = buffimage.getRaster();
            java.util.HashMap sampleMap = (java.util.HashMap) bandMap
                    .get(band_str);
            boolean addall = (sampleMap == null);
            if (sampleMap == null) {
                sampleMap = new java.util.HashMap();
                bandMap.put(band_str, sampleMap);
            }

            int minx = raster.getMinX();
            int maxx = minx + raster.getWidth();
            int miny = raster.getMinY();
            int maxy = miny + raster.getHeight();
            int[][] bands = new int[band_indexes.length][raster.getWidth()];

            for (int y = miny; y < maxy; y++) {
                for (int i = 0; i < band_indexes.length; i++) {
                    raster.getSamples(minx, y, maxx, 1, band_indexes[i],
                            bands[i]);
                }
                for (int x = minx; x < maxx; x++) {
                    int sample = 0;
                    for (int i = 0; i < band_indexes.length; i++) {
                        sample |= bands[i][x] << ((band_indexes.length - i - 1) * 8);
                    }

                    Integer sampleObj = new Integer(sample);

                    boolean add = addall;
                    if (!addall) {
                        add = sampleMap.containsKey(sampleObj);
                    }
                    if (add) {
                        Integer count = (Integer) sampleMap.get(sampleObj);
                        if (count == null) {
                            count = new Integer(0);
                        }
                        count = new Integer(count.intValue() + 1);
                        sampleMap.put(sampleObj, count);
                    }
                }
            }
        }

        Node node = nodes.item(0);
        while (node != null) {
            if (node.getNodeType() == Node.ELEMENT_NODE && node.getLocalName().equals("count")) {
                String band = ((Element) node).getAttribute("bands");
                String sample = ((Element) node).getAttribute("sample");
                HashMap sampleMap = (HashMap) bandMap.get(band);
                Document doc = node.getOwnerDocument();
                if (sample.equals("all")) {
                    Node parent = node.getParentNode();
                    Node prevSibling = node.getPreviousSibling();
                    Iterator sampleIt = sampleMap.keySet().iterator();
                    Element countnode = null;
                    int digits;
                    String prefix;
                    switch (buffimage.getType()) {
                    case BufferedImage.TYPE_BYTE_BINARY:
                        digits = 1;
                        prefix = "";
                        break;
                    case BufferedImage.TYPE_BYTE_GRAY:
                        digits = 2;
                        prefix = "0x";
                        break;
                    default:
                        prefix = "0x";
                        digits = band.length() * 2;
                    }
                    while (sampleIt.hasNext()) {
                        countnode = doc.createElementNS(
                                node.getNamespaceURI(), "count");
                        Integer sampleInt = (Integer) sampleIt.next();
                        Integer count = (Integer) sampleMap.get(sampleInt);
                        if (band.length() > 0) {
                            countnode.setAttribute("bands", band);
                        }
                        countnode.setAttribute("sample", prefix
                                + HexString(sampleInt.intValue(), digits));
                        Node textnode = doc
                                .createTextNode(count.toString());
                        countnode.appendChild(textnode);
                        parent.insertBefore(countnode, node);
                        if (sampleIt.hasNext() && prevSibling != null && prevSibling.getNodeType() == Node.TEXT_NODE) {
                            parent.insertBefore(
                                    prevSibling.cloneNode(false), node);
                        }
                    }
                    parent.removeChild(node);
                    // Fortify Mod: If the Iterator sampleIt is empty, then countnode will never be set.
                    // This will result in a null derefernce of node at the end of the loop.  Test for this
                    // case and mitigate the damage.
                    if( countnode == null ) {
                        countnode = (Element) node;
                        jlogger.log(Level.SEVERE, "Error processing image node");
                    }
                    node = countnode;
                } else {
                    Integer count = (Integer) sampleMap.get(Integer
                            .decode(sample));
                    if (count == null)
                        count = new Integer(0);
                    Node textnode = doc.createTextNode(count.toString());
                    node.appendChild(textnode);
                }
            }
            node = node.getNextSibling();
        }
    }
961048
public static void applyTransform(GrayS8 input , int transform[] , int minValue, GrayS8 output ) {
		output.reshape(input.width,input.height);

		if( BoofConcurrency.USE_CONCURRENT ) {
			ImplEnhanceHistogram_MT.applyTransform(input, transform, minValue, output);
		} else {
			ImplEnhanceHistogram.applyTransform(input, transform, minValue, output);
		}
	}
939654
private static void scaleDownTenRoundUp(Slice decimal, int tenScale, Slice result)
    {
        boolean round;
        do {
            int powerTen = Math.min(tenScale, MAX_POWER_OF_TEN_INT);
            tenScale -= powerTen;

            int divisor = POWERS_OF_TEN_INT[powerTen];
            round = divideCheckRound(decimal, divisor, result);
            decimal = result;
        }
        while (tenScale > 0);

        if (round) {
            incrementUnsafe(decimal);
        }
    }
444827
public static void displayTransform( InterleavedF32 transform , String name ) {

		// declare storage
		GrayF32 magnitude = new GrayF32(transform.width,transform.height);
		GrayF32 phase = new GrayF32(transform.width,transform.height);

		// Make a copy so that you don't modify the input
		transform = transform.clone();

		// shift the zero-frequency into the image center, as is standard in image processing
		DiscreteFourierTransformOps.shiftZeroFrequency(transform,true);

		// Compute the transform's magnitude and phase
		DiscreteFourierTransformOps.magnitude(transform,magnitude);
		DiscreteFourierTransformOps.phase(transform, phase);

		// Convert it to a log scale for visibility
		PixelMath.log(magnitude,magnitude);

		// Display the results
		BufferedImage visualMag = VisualizeImageData.grayMagnitude(magnitude, null, -1);
		BufferedImage visualPhase = VisualizeImageData.colorizeSign(phase, null, Math.PI);

		ImageGridPanel dual = new ImageGridPanel(1,2,visualMag,visualPhase);
		ShowImages.showWindow(dual,"Magnitude and Phase of "+name);
	}
1141569
static void pruneIncorrectShape(FastQueue<Grid> grids , int numRows, int numCols ) {
		// prune clusters which can't be a member calibration target
		for (int i = grids.size()-1; i >= 0; i--) {
			Grid g = grids.get(i);
			if ((g.rows != numRows || g.columns != numCols) && (g.rows != numCols || g.columns != numRows)) {
				grids.remove(i);
			}
		}
	}
444801
public void shrinkTo(int newSize) {
    if (newSize < this.size) {
      for (int i = this.size; i > newSize; i--)
        this.elements[i - 1] = null;
      this.size = newSize;
    }
  }
1353456
private <T> Collection<Integer> transformSplit(SplitTransformation<T> split) {

		StreamTransformation<T> input = split.getInput();
		Collection<Integer> resultIds = transform(input);

		validateSplitTransformation(input);

		// the recursive transform call might have transformed this already
		if (alreadyTransformed.containsKey(split)) {
			return alreadyTransformed.get(split);
		}

		for (int inputId : resultIds) {
			streamGraph.addOutputSelector(inputId, split.getOutputSelector());
		}

		return resultIds;
	}
1040264
public static void magnitude( InterleavedF32 transform , GrayF32 magnitude ) {
		checkImageArguments(magnitude,transform);

		for( int y = 0; y < transform.height; y++ ) {

			int indexTran = transform.startIndex + y*transform.stride;
			int indexMag = magnitude.startIndex + y*magnitude.stride;

			for( int x = 0; x < transform.width; x++, indexTran += 2 ) {

				float real = transform.data[indexTran];
				float img = transform.data[indexTran+1];

				magnitude.data[indexMag++] = (float)Math.sqrt(real * real + img * img);
			}
		}
	}
584715
void shrink()
  {

    int n = m_opMap.elementAt(MAPINDEX_LENGTH);
    m_opMap.setToSize(n + 4);

    m_opMap.setElementAt(0,n);
    m_opMap.setElementAt(0,n+1);
    m_opMap.setElementAt(0,n+2);


    n = m_tokenQueue.size();
    m_tokenQueue.setToSize(n + 4);

    m_tokenQueue.setElementAt(null,n);
    m_tokenQueue.setElementAt(null,n + 1);
    m_tokenQueue.setElementAt(null,n + 2);
  }
995962
public static WaveletDescription<WlCoef_F32> generate_F32( int I ) {
		if( I != 6 ) {
			throw new IllegalArgumentException("Only 6 is currently supported");
		}

		WlCoef_F32 coef = new WlCoef_F32();

		coef.offsetScaling = -2;
		coef.offsetWavelet = -2;

		coef.scaling = new float[6];
		coef.wavelet = new float[6];

		double sqrt7 = Math.sqrt(7);
		double div = 16.0*Math.sqrt(2);
		coef.scaling[0] = (float)((1.0-sqrt7)/div);
		coef.scaling[1] = (float)((5.0+sqrt7)/div);
		coef.scaling[2] = (float)((14.0+2.0*sqrt7)/div);
		coef.scaling[3] = (float)((14.0-2.0*sqrt7)/div);
		coef.scaling[4] = (float)((1.0-sqrt7)/div);
		coef.scaling[5] = (float)((-3.0+sqrt7)/div);

		coef.wavelet[0] = coef.scaling[5];
		coef.wavelet[1] = -coef.scaling[4];
		coef.wavelet[2] = coef.scaling[3];
		coef.wavelet[3] = -coef.scaling[2];
		coef.wavelet[4] = coef.scaling[1];
		coef.wavelet[5] = -coef.scaling[0];

		WlBorderCoefStandard<WlCoef_F32> inverse = new WlBorderCoefStandard<>(coef);

		return new WaveletDescription<>(new BorderIndex1D_Wrap(), coef, inverse);
	}
600729
public void extractScaleTransform(Transformation2D scale,
			Transformation2D rotateNshearNshift) {

		scale.setScale(Math.sqrt(xx * xx + xy * xy),
				Math.sqrt(yx * yx + yy * yy));
		rotateNshearNshift.setScale(1.0 / scale.xx, 1.0 / scale.yy);
		rotateNshearNshift.multiply(this);
	}
701549
private static WaveletTransform createDefaultShrinkTransform(ImageDataType imageType, int numLevels,
																 double minPixelValue , double maxPixelValue ) {

		WaveletTransform descTran;

		if( !imageType.isInteger()) {
			WaveletDescription<WlCoef_F32> waveletDesc_F32 = FactoryWaveletDaub.daubJ_F32(4);
			descTran = FactoryWaveletTransform.create_F32(waveletDesc_F32,numLevels,
					(float)minPixelValue,(float)maxPixelValue);
		} else {
			WaveletDescription<WlCoef_I32> waveletDesc_I32 = FactoryWaveletDaub.biorthogonal_I32(5, BorderType.REFLECT);
			descTran = FactoryWaveletTransform.create_I(waveletDesc_I32,numLevels,
					(int)minPixelValue,(int)maxPixelValue,
					ImageType.getImageClass(ImageType.Family.GRAY, imageType));
		}
		return descTran;
	}
1035259
private void process(ImmutableSetMultimap<Class<? extends Annotation>, Element> validElements) {
    for (ProcessingStep step : steps) {
      ImmutableSetMultimap<Class<? extends Annotation>, Element> stepElements =
          new ImmutableSetMultimap.Builder<Class<? extends Annotation>, Element>()
              .putAll(indexByAnnotation(elementsDeferredBySteps.get(step), step.annotations()))
              .putAll(filterKeys(validElements, Predicates.<Object>in(step.annotations())))
              .build();
      if (stepElements.isEmpty()) {
        elementsDeferredBySteps.removeAll(step);
      } else {
        Set<? extends Element> rejectedElements = step.process(stepElements);
        elementsDeferredBySteps.replaceValues(
            step,
            transform(
                rejectedElements,
                new Function<Element, ElementName>() {
                  @Override
                  public ElementName apply(Element element) {
                    return ElementName.forAnnotatedElement(element);
                  }
                }));
      }
    }
  }
323267
function applyTransformationsGroup( filter, element, group ) {
		var i, rule;

		for ( i = 0; i < group.length; ++i ) {
			rule = group[ i ];

			// Test with #check or #left only if it's set.
			// Do not apply transformations because that creates infinite loop.
			if ( ( !rule.check || filter.check( rule.check, false ) ) &&
				( !rule.left || rule.left( element ) ) ) {
				rule.right( element, transformationsTools );
				return; // Only first matching rule in a group is executed.
			}
		}
	}
575661
public void shrink(int count) {
        char[] keepAllocated;

        if (count == 0) {
            throw new IllegalArgumentException();
        }
        if (count > lastNo) {
            throw new IllegalArgumentException(count + " vs " + lastNo);
        }
        lastNo -= count;
        keepAllocated = pages[0];
        System.arraycopy(pages, count, pages, 0, lastNo + 1);
        pages[lastNo + 1] = keepAllocated;
        for (int i = lastNo + 2; i < pages.length; i++) {
            pages[i] = null;
        }
    }