All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jpedal.images.ImageOps Maven / Gradle / Ivy

The newest version!
/*
 * ===========================================
 * Java Pdf Extraction Decoding Access Library
 * ===========================================
 *
 * Project Info:  http://www.idrsolutions.com
 * Help section for developers at http://www.idrsolutions.com/java-pdf-library-support/
 *
 * (C) Copyright 1997-2013, IDRsolutions and Contributors.
 *
 * 	This file is part of JPedal
 *
     This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


 *
 * ---------------
 * ImageOps.java
 * ---------------
 */
package org.jpedal.images;

public class ImageOps {

	private static int[] bitCheck = { 128, 64, 32, 16, 8, 4, 2, 1 };

	private static byte[] invertByteImage(int w, int h, int componentCount, byte[] data) {

		// System.out.println("w="+w);
		// System.out.println("h="+h);
		// System.out.println("components="+componentCount);
		// System.out.println("data="+data.length);

		// Double check the componentCount
		int temp = (data.length / (w * h));

		if (temp != componentCount) {
			componentCount = temp;
		}

		int bytesInRow = w * componentCount;
		int topByte = 0, bottomByte = ((h - 1) * bytesInRow);
		byte tempByte;

		while (topByte < bottomByte) {

			for (int row = 0; row < (bytesInRow); row += componentCount) {
				for (int c = 0; c < componentCount; c++) {
					tempByte = data[topByte + row + c];
					data[topByte + row + c] = data[bottomByte + row + c];
					data[bottomByte + row + c] = tempByte;
				}
			}
			topByte = topByte + bytesInRow;
			bottomByte = bottomByte - bytesInRow;
		}
		return data;
	}

	private static byte[] invertOneBitImage(int w, int h, byte[] data) {

		int bytesInRow = (w + 7) / 8;
		int topByte = 0, bottomByte = (h - 1) * bytesInRow;
		byte tempByte;

		while (topByte < bottomByte) {

			for (int row = 0; row < bytesInRow; row++) {
				tempByte = data[topByte + row];
				data[topByte + row] = data[bottomByte + row];
				data[bottomByte + row] = tempByte;
			}
			topByte = topByte + bytesInRow;
			bottomByte = bottomByte - bytesInRow;
		}
		return data;
	}

	private static byte[] rotateOneBitImage(int w, int h, byte[] data, int newH, int newW) {
		int bytesInRow = (w + 7) / 8;
		int newBytesInRow = (newW + 7) / 8;

		byte[] newData = new byte[newBytesInRow * newH];

		// read x,y and set as y,x
		for (int y = 0; y < h; y++) {
			for (int x = 0; x < w; x++) {

				// read pixel in existing array as x,y
				int byteUsed = (((h - 1) - y) * bytesInRow) + (x >> 3);

				byte pixelByte = data[byteUsed];

				// clever optimisation here when ready
				// 8 empty bits means ignore next 8 bits
				if (pixelByte == 0) {
					x = x + 7;
				}
				else {
					int bitUsed = x & 7;

					// if set we need to set in second array, set pixel in new array as y,x
					if ((pixelByte & bitCheck[bitUsed]) == bitCheck[bitUsed]) {

						// read pixel in existing array as x,y
						int newByteUsed = (x * newBytesInRow) + (y >> 3);

						byte newPixelByte = newData[newByteUsed];

						int newBitUsed = y & 7;

						// switch on
						newPixelByte = (byte) (newPixelByte | bitCheck[newBitUsed]);

						// write back
						newData[newByteUsed] = newPixelByte;

					}
				}
			}
		}

		return newData;
	}

	private static byte[] rotateByteImage(int w, int h, int componentCount, byte[] data) {

		int temp = (data.length / (w * h));
		if (temp != componentCount) {
			componentCount = temp;
		}

		int bytesInRow = w * componentCount;
		int newBytesInRow = h * componentCount;
		byte[] rotatedData = new byte[data.length];

		for (int y = 0; y < h; y++) {
			for (int x = 0; x < bytesInRow; x += componentCount) {
				int c = 0;

				// ClockWise
				int convertPoint = ((x / componentCount) * (newBytesInRow)) + (newBytesInRow - (y * componentCount) - componentCount);

				// Anti-ClockWise
				// int convertPoint = (((w-1)-(x/componentCount))*newBytesInRow)+(y*componentCount);

				while (c < componentCount) {

					// x=(x+c)
					// y=(y*bytesInRow)
					rotatedData[convertPoint + c] = data[(y * bytesInRow) + (x + c)];
					c++;
				}
			}
		}
		return rotatedData;
	}

	public static byte[] invertImage(byte[] data, int w, int h, int d, int comp, byte[] index) {

		// either process or just return
		if (d == 8) { // add in next
			if (index != null) comp = 1;
			else // will fail if wrong size
			data = checkSize(data, w, h, comp);

			return ImageOps.invertByteImage(w, h, comp, data);

			// }else if(d==4){

		}
		else
			if (d == 1) {

				return ImageOps.invertOneBitImage(w, h, data);

			}
		return null;
	}

	public static byte[] rotateImage(byte[] data, int w, int h, int d, int comp, byte[] index) {

		// either process or just return
		if (d == 8) { // add in next
			if (index != null) comp = 1;
			/** Rotated H and W are calcualted within method */
			return ImageOps.rotateByteImage(w, h, comp, data);

		}
		else
			if (d == 4) {

			}
			else
				if (d == 1) {
					/** The W and H are swapped for the new values, this gives rotated coords */
					return ImageOps.rotateOneBitImage(w, h, data, w, h);

				}
		return null;
	}

	public static byte[] checkSize(byte[] data, int w, int h, int comp) {

		int correctSize = w * h * comp;
		if (data.length < correctSize) {
			byte[] newData = new byte[correctSize];
			System.arraycopy(data, 0, newData, 0, data.length);
			data = newData;
		}

		return data;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy