
org.jpedal.parser.image.MaskDataDecoder Maven / Gradle / Ivy
/*
* ===========================================
* Java Pdf Extraction Decoding Access Library
* ===========================================
*
* Project Info: http://www.idrsolutions.com
* Help section for developers at http://www.idrsolutions.com/support/
*
* (C) Copyright 1997-2015 IDRsolutions and Contributors.
*
* This file is part of JPedal/JPDF2HTML5
*
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
*
* ---------------
* MaskDataDecoder.java
* ---------------
*/
package org.jpedal.parser.image;
import com.idrsolutions.pdf.color.shading.BitReader;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import org.jpedal.color.ColorSpaces;
import org.jpedal.color.GenericColorSpace;
import org.jpedal.color.JPEGDecoder;
import org.jpedal.io.ColorSpaceConvertor;
import org.jpedal.objects.raw.PdfDictionary;
import org.jpedal.objects.raw.PdfObject;
import org.jpedal.parser.image.data.ImageData;
/**
*
* @author markee
*/
class MaskDataDecoder {
/**
* apply the SMask to image data directly as a component on argb
*
* @param imageData
* @param decodeColorData
* @param newSMask
* @return
*/
static byte[] applyMask(final ImageData imageData,final GenericColorSpace decodeColorData, final PdfObject newMask, final PdfObject XObject, byte[] maskDataSream) {
final int[] maskArray=newMask.getIntArray(PdfDictionary.Mask);
byte[] objectData=imageData.getObjectData();
/*
* Image data
*/
int w=imageData.getWidth();
int h=imageData.getHeight();
int d=imageData.getDepth();
objectData = convertData(decodeColorData, objectData, w, h, imageData, d, 1, null);
XObject.setIntNumber(PdfDictionary.BitsPerComponent, 8);
if(maskArray!=null){
objectData=applyMaskArray(w, h, objectData,maskArray);
}else{
objectData=applyMaskStream(maskDataSream,imageData,decodeColorData, newMask, XObject);
}
//include Decode if present
final float[] maskDecodeArray=newMask.getFloatArray(PdfDictionary.Decode);
if(maskDecodeArray!=null) {
ImageCommands.applyDecodeArray(objectData, maskDecodeArray.length / 2, maskDecodeArray, ColorSpaces.DeviceRGB);
}
return objectData;
}
static BufferedImage applyMaskArray(ImageData imageData, int[] maskArray){
int bitDepth = imageData.getDepth();
// int negate = 8-bitDepth;
int nComp = maskArray.length/2;
int dim = imageData.getWidth()*imageData.getHeight();
BufferedImage img = new BufferedImage(imageData.getWidth(), imageData.getHeight(), BufferedImage.TYPE_INT_ARGB);
int output[] = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
byte [] data = imageData.getObjectData();
int r,g,b,t,c,m,y,k;
boolean isMask;
switch(bitDepth){
case 1:
case 2:
case 4:
BitReader reader = new BitReader(data, true);
for (int i = 0; i < dim; i++) {
if(nComp == 1){
t = reader.getPositive(bitDepth);
isMask = t >= maskArray[0] && t<=maskArray[1];
if(!isMask){
t ^= 0xff;
output[i] = (255 << 24) | (t << 16) | (t << 8) | t;
}
}else{ //assume number of components is 3 at the moment we can fix in future;
r = reader.getPositive(bitDepth);
g = reader.getPositive(bitDepth);
b = reader.getPositive(bitDepth);
isMask = r >= maskArray[0] && r<=maskArray[1]
&& g >= maskArray[2] && g<=maskArray[3]
&& b >= maskArray[4] && b<=maskArray[5];
if(!isMask){
r ^= 0xff;
g ^= 0xff;
b ^= 0xff;
output[i] = (255 << 24) | (r << 16) | (g << 8) | b;
}
}
}
break;
case 8:
int p = 0;
if(nComp ==1){
for (int i = 0; i < dim; i++) {
t = data[p++]&0xff;
isMask = t >= maskArray[0] && t<=maskArray[1];
if(!isMask){
output[i] = (255 << 24) | (t << 16) | (t << 8) | t;
}
}
}else if(nComp==3){
for (int i = 0; i < dim; i++) {
r = data[p++]&0xff;
g = data[p++]&0xff;
b = data[p++]&0xff;
isMask = r >= maskArray[0] && r<=maskArray[1]
&& g >= maskArray[2] && g<=maskArray[3]
&& b >= maskArray[4] && b<=maskArray[5];
if(!isMask){
output[i] = (255 << 24) | (r << 16) | (g << 8) | b;
}
}
}else if(nComp==4){
//
}
break;
}
return img;
}
static byte[] applySMask(byte[] maskData, final ImageData imageData,final GenericColorSpace decodeColorData, final PdfObject newSMask, final PdfObject XObject) {
byte[] objectData=imageData.getObjectData();
/*
* Image data
*/
int w=imageData.getWidth();
int h=imageData.getHeight();
int d=imageData.getDepth();
/*
* Smask data (ASSUME single component at moment)
*/
final int maskW=newSMask.getInt(PdfDictionary.Width);
final int maskH=newSMask.getInt(PdfDictionary.Height);
final int maskD=newSMask.getInt(PdfDictionary.BitsPerComponent);
objectData = convertData(decodeColorData, objectData, w, h, imageData, d, maskD, maskData);
//needs to be 'normalised to 8 bit'
if(maskD!=8){
maskData=ColorSpaceConvertor.normaliseTo8Bit(maskD, maskW, maskH, maskData);
}
//add mask as a element so we now have argb
if(w==maskW && h==maskH){
//System.out.println("Same size");
objectData=buildUnscaledByteArray(w, h, objectData, maskData);
}else if(w15){
is4Bit=false;
break;
}
}
if(is4Bit){
for (int ii=0;ii1f){
diff /= 255f;
}
}
try{
for(int i=0;i0){
combinedData[i+comp]=(byte) (objectData[rgbPtr]*diff);
}else{
combinedData[i+comp]=objectData[rgbPtr];
}
}
rgbPtr++;
}
//opacity
combinedData[i+3]=(byte)255;
}
}catch(Exception e){
e.printStackTrace();
}
return combinedData;
}
private static byte[] buildUnscaledByteArray(final int w, final int h, final byte[] objectData, final byte[] maskData) {
int pixels=w*h*4;
int rgbPtr=0, aPtr=0;
byte[] combinedData=new byte[w*h*4];
final int rawDataSize=objectData.length;
final int maskSize=maskData.length;
try{
for(int i=0;i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy