content: /*
   * Copyright (C) 2019 Adaptech s.r.o., Robert Pösel
   * Copyright (C) 2011 Google Inc.
   *
   * Licensed 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.
   */
  
  package com.googlecode.leptonica.android;
  
  import org.junit.Test;
  
  import static org.junit.Assert.assertEquals;
  import static org.junit.Assert.assertTrue;
  
  public class PixaTest {
  	@Test
  	public void testPixaCreate() {
  		internalTestPixaCreate(0, 0, 0);
  		internalTestPixaCreate(1, 0, 0);
  		internalTestPixaCreate(0, 640, 480);
  		internalTestPixaCreate(5, 640, 480);
  	}
  
  	private void internalTestPixaCreate(int initialCapacity, int width, int height) {
  		Pixa pixa = Pixa.createPixa(initialCapacity, width, height);
  
  		// Make sure the dimensions were set correctly.
  		assertEquals(0, pixa.size());
  		assertEquals(width, pixa.getWidth());
  		assertEquals(height, pixa.getHeight());
  
  		// Fill the Pixa to capacity.
  		for (int i = 0; i < initialCapacity; i++) {
  			addBlockToPixa(pixa, 0, 0, 640, 480, 8);
  		}
  
  		// Make sure the size is reflected correctly.
  		assertEquals(initialCapacity, pixa.size());
  
  		// Make sure we can recycle the Pixa.
  		pixa.recycle();
  	}
  
  	@Test
  	public void testPixaCopy() {
  		internalTestPixaCopy(0, 0, 0);
  		internalTestPixaCopy(5, 0, 0);
  		internalTestPixaCopy(0, 640, 480);
  		internalTestPixaCopy(5, 640, 480);
  	}
  
  	private void internalTestPixaCopy(int initialCapacity, int width, int height) {
  		Pixa pixa = Pixa.createPixa(initialCapacity, width, height);
  
  		// Fill the Pixa to capacity.
  		for (int i = 0; i < initialCapacity; i++) {
  			addBlockToPixa(pixa, 0, 0, 640, 640, 8);
  		}
  
  		// Create a shallow copy of the Pixa.
  		Pixa pixaCopy = pixa.copy();
  
  		// Add a new Pix to the copy.
  		addBlockToPixa(pixaCopy, 0, 0, 640, 640, 8);
  
  		// Ensure that both copies changed size.
  		assertEquals(initialCapacity + 1, pixaCopy.size());
  		assertEquals(pixaCopy.size(), pixa.size());
  
  		// Finally, we should be able to recycle both Pixa.
  		pixa.recycle();
  		pixaCopy.recycle();
  	}
  
  	@Test
  	public void testPixaSort() {
  		Pixa pixa = Pixa.createPixa(0);
  
  		// Add contained Pix in arbitrary order.
  		addBlockToPixa(pixa, 0, 0, 640, 640, 8);
  		addBlockToPixa(pixa, 160, 160, 64, 64, 8);
  		addBlockToPixa(pixa, 32, 32, 320, 320, 8);
  		addBlockToPixa(pixa, 64, 64, 160, 160, 8);
  		addBlockToPixa(pixa, 320, 320, 32, 32, 8);
  
  		// Sort by increasing height.
  		Pixa pixaSorted = pixa.sort(Constants.L_SORT_BY_HEIGHT, Constants.L_SORT_INCREASING);
  
  		// Ensure sort was successful.
  		int[] currentDimensions = new int[4];
  		int previousHeight = -1;
  
  		for (int i = 0; i < pixa.size(); i++) {
  			assertTrue(pixaSorted.getBoxGeometry(i, currentDimensions));
  			int currentHeight = currentDimensions[Box.INDEX_H];
  			assertTrue(currentHeight > previousHeight);
  			previousHeight = currentHeight;
  		}
  
  		pixa.recycle();
  		pixaSorted.recycle();
  	}
  
  	@Test
  	public void testPixaJoin() {
  		internalTestPixaJoin(0, 0);
  		internalTestPixaJoin(1, 0);
  		internalTestPixaJoin(0, 1);
  		internalTestPixaJoin(1, 1);
  	}
  
  	private void internalTestPixaJoin(int sizeA, int sizeB) {
  		Pixa pixaA = Pixa.createPixa(0);
  		Pixa pixaB = Pixa.createPixa(0);
  
  		// Populate both Pixa.
  		for (int i = 0; i < sizeA; i++) {
  			addBlockToPixa(pixaA, 0, 0, 640, 640, 8);
  		}
  
  		for (int i = 0; i < sizeB; i++) {
  			addBlockToPixa(pixaB, 0, 0, 640, 640, 8);
  		}
  
  		// Join pixaB into pixaA.
  		pixaA.join(pixaB);
  
  		// Ensure the join was successful.
  		assertEquals(pixaA.size(), sizeA + sizeB);
  		assertEquals(pixaB.size(), sizeB);
  
  		pixaA.recycle();
  		pixaB.recycle();
  	}
  
  	@Test
  	public void testPixaReplacePix() {
  		Pixa pixa = Pixa.createPixa(0, 640, 480);
  
  		// Populate the Pixa.
  		addBlockToPixa(pixa, 0, 0, 640, 480, 8);
  
  		Pix pix = new Pix(320, 240, 8);
  		Box box = new Box(320, 240, 320, 240);
  
  		// Replace the existing Pix.
  		pixa.replacePix(0, pix, box);
  		// Pixa took ownership of the given pix/box, we shouldn't use or recycle these anymore!
  		// Note we actually use them below, just to compare the internal native address is the same.
  		//pix = null;
  		//box = null;
  
  		// Ensure the replacement was successful.
  		Pix returnedPix = pixa.getPix(0);
  		Box returnedBox = pixa.getBox(0);
  
  		// Returned instance points to the same native object
  		assertEquals(pix.getNativePix(), returnedPix.getNativePix());
  		assertEquals(box.getNativeBox(), returnedBox.getNativeBox());
  
  		// We've got clone of the pix/box stored inside Pixa, we should recycle them.
  		returnedPix.recycle();
  		returnedBox.recycle();
  
  		pixa.recycle();
  	}
  
  	@Test
  	public void testPixaMergeAndReplacePix() {
  		Pixa pixa = Pixa.createPixa(0, 640, 480);
  
  		// Populate the Pixa.
  		addBlockToPixa(pixa, 0, 0, 320, 240, 8);
  		addBlockToPixa(pixa, 320, 240, 320, 240, 8);
  
  		// Merge both Pix, removing the second Pix.
  		pixa.mergeAndReplacePix(0, 1);
  
  		// Ensure the merge was successful.
  		Pix pix = pixa.getPix(0);
  		Box box = pixa.getBox(0);
  
  		assertEquals(pixa.size(), 1);
  
  		assertEquals(pix.getWidth(), 640);
  		assertEquals(pix.getHeight(), 480);
  		assertEquals(pix.getDepth(), 8);
  
  		assertEquals(box.getX(), 0);
  		assertEquals(box.getY(), 0);
  		assertEquals(box.getWidth(), 640);
  		assertEquals(box.getHeight(), 480);
  
  		// We've got clone of the pix/box, recycle it.
  		pix.recycle();
  		box.recycle();
  
  		pixa.recycle();
  	}
  
  	/**
  	 * Adds a block to the specified Pixa.
  	 *
  	 * @param pixa   The existing Pixa.
  	 * @param x      X-coordinate of the top-left corner of the block.
  	 * @param y      Y-coordinate of the top-left corner of the block.
  	 * @param width  Width of the block.
  	 * @param height Height of the block.
  	 * @param depth  Bit-depth of the block.
  	 */
  	private static void addBlockToPixa(Pixa pixa, int x, int y, int width, int height, int depth) {
  		final Pix pix = new Pix(width, height, depth);
  		final Box box = new Box(x, y, width, height);
  
  		pixa.add(pix, box, Constants.L_COPY);
  
  		pix.recycle();
  		box.recycle();
  	}
  }
  