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

org.jpedal.color.LabColorSpace 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


 *
 * ---------------
 * LabColorSpace.java
 * ---------------
 */
package org.jpedal.color;

import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.util.HashMap;
import java.util.Map;

import org.jpedal.io.ColorSpaceConvertor;
import org.jpedal.objects.raw.PdfObject;
import org.jpedal.utils.LogWriter;

/**
 * handle LabColorSpace
 */
public class LabColorSpace extends GenericColorSpace {

	private static final long serialVersionUID = 9204166205367322647L;
	private int r, g, b;
	private float lastL = -1, lastA = 65536, lastBstar;

	/** holds values we have already calculated to speed-up */
	private Map cache = new HashMap();

	private static final float C1 = 108f / 841f;

	private static final float C2 = 4f / 29f;

	private static final float C3 = 6f / 29f;

	private static final float C4 = 100f / 255f;

	private static final float C5 = 128f;

	public LabColorSpace(float[] whitepoint, float[] blackpoint, float[] range) {

		this.value = ColorSpaces.Lab;
		setCIEValues(whitepoint, blackpoint, range, null, null);
	}

	/**
	 * convert Index to RGB
	 */
	@Override
	public byte[] convertIndexToRGB(byte[] index) {

		this.isConverted = true;

		int size = index.length;
		float cl, ca, cb;

		for (int i = 0; i < size; i = i + 3) { // convert all values to rgb

			cl = (index[i] & 255) * C4;

			ca = (index[i + 1] & 255) - C5;

			cb = (index[i + 2] & 255) - C5;

			convertToRGB(cl, ca, cb);

			index[i] = (byte) this.r;
			index[i + 1] = (byte) this.g;
			index[i + 2] = (byte) this.b;

		}

		return index;
	}

	/**
	 * 

* Convert DCT encoded image bytestream to sRGB *

*

* It uses the internal Java classes and the Adobe icm to convert CMYK and YCbCr-Alpha - the data is still DCT encoded. *

*

* The Sun class JPEGDecodeParam.java is worth examining because it contains lots of interesting comments *

*

* I tried just using the new IOImage.read() but on type 3 images, all my clipping code stopped working so I am still using 1.3 *

*/ @Override public BufferedImage JPEGToRGBImage(byte[] data, int w, int h, float[] decodeArray, int pX, int pY, boolean arrayInverted, PdfObject XObject) { BufferedImage image; // ByteArrayInputStream in = null; try { Raster ras = this.images.readRasterFromJPeg(data); ras = cleanupRaster(ras, pX, pY, 3); final int width = ras.getWidth(); final int height = ras.getHeight(); final int imgSize = width * height; byte[] iData = ((DataBufferByte) ras.getDataBuffer()).getData(); for (int i = 0; i < imgSize * 3; i = i + 3) { // convert all values to rgb float cl = (iData[i] & 255) * C4; float ca = (iData[i + 1] & 255) - C5; float cb = (iData[i + 2] & 255) - C5; convertToRGB(cl, ca, cb); iData[i] = (byte) this.r; iData[i + 1] = (byte) this.g; iData[i + 2] = (byte) this.b; } image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); DataBuffer db = new DataBufferByte(iData, iData.length); int[] bands = { 0, 1, 2 }; Raster raster = Raster.createInterleavedRaster(db, width, height, width * 3, 3, bands, null); image.setData(raster); } catch (Exception ee) { image = null; if (LogWriter.isOutput()) LogWriter.writeLog("Couldn't read JPEG, not even raster: " + ee); } return image; } /** * convert LAB stream to RGB and return as an image */ @Override public BufferedImage dataToRGB(byte[] data, int width, int height) { BufferedImage image; final int imgSize = width * height; try { for (int i = 0; i < imgSize * 3; i = i + 3) { // convert all values to rgb float cl = (data[i] & 255) * C4; float ca = (data[i + 1] & 255) - C5; float cb = (data[i + 2] & 255) - C5; convertToRGB(cl, ca, cb); data[i] = (byte) this.r; data[i + 1] = (byte) this.g; data[i + 2] = (byte) this.b; } image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Raster raster = ColorSpaceConvertor.createInterleavedRaster(data, width, height); image.setData(raster); } catch (Exception ee) { image = null; if (LogWriter.isOutput()) LogWriter.writeLog("Couldn't read JPEG, not even raster: " + ee); } return image; } /** convert numbers to rgb values */ private void convertToRGB(float l, float a, float bstar) { // make sure in range if (l < 0) l = 0; else if (l > 100) l = 100; if (a < this.R[0]) a = this.R[0]; else if (a > this.R[1]) a = this.R[1]; if (bstar < this.R[2]) bstar = this.R[2]; else if (bstar > this.R[3]) bstar = this.R[3]; /** don't bother if already calculated */ if ((this.lastL == l) && (this.lastA == a) && (this.lastBstar == bstar)) {} else { // set indices int indexL = (int) l; int indexA = (int) (a - this.R[0]); int indexB = (int) (bstar - this.R[2]); Integer key = (indexL << 16) + (indexA << 8) + indexB; Object value = this.cache.get(key); /** used cache value or recalulate */ if (value != null) { int raw = (Integer) value; this.r = ((raw >> 16) & 255); this.g = ((raw >> 8) & 255); this.b = ((raw) & 255); } else { double val1 = (l + 16d) / 116d; double[] vals = new double[3]; vals[0] = val1 + (a / 500d); vals[1] = val1; vals[2] = val1 - (bstar / 200d); float[] out = new float[3]; for (int j = 0; j < 3; j++) { if (vals[j] >= C3) out[j] = (float) (this.W[j] * vals[j] * vals[j] * vals[j]); else out[j] = (float) (this.W[j] * C1 * (vals[j] - C2)); // avoid negative numbers // seem to give very odd results if (out[j] < 0) out[j] = 0; } // convert to rgb out = this.cs.toRGB(out); // put values into array this.r = (int) (out[0] * 255); this.g = (int) (out[1] * 255); this.b = (int) (out[2] * 255); // check in range if (this.r < 0) this.r = 0; if (this.g < 0) this.g = 0; if (this.b < 0) this.b = 0; if (this.r > 255) this.r = 255; if (this.g > 255) this.g = 255; if (this.b > 255) this.b = 255; int raw = (this.r << 16) + (this.g << 8) + this.b; // store values in cache this.cache.put(key, raw); } this.lastL = l; this.lastA = a; this.lastBstar = bstar; } } /** * set color (in terms of rgb) */ @Override final public void setColor(String[] number_values, int items) { float[] colValues = new float[items]; for (int ii = 0; ii < items; ii++) colValues[ii] = Float.parseFloat(number_values[ii]); setColor(colValues, items); } /** set color */ @Override final public void setColor(float[] operand, int length) { // get raw values float l = operand[0]; float a = operand[1]; float Bstar = operand[2]; convertToRGB(l, a, Bstar); this.currentColor = new PdfColor(this.r, this.g, this.b); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy