
org.jpedal.parser.image.SMaskDecoder 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-2016 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
*
* ---------------
* SMaskDecoder.java
* ---------------
*/
package org.jpedal.parser.image;
import java.nio.ByteBuffer;
import java.util.Arrays;
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 SMaskDecoder {
public static byte[] applyJPX_JBIG_Smask(final ImageData imageData, final ImageData smaskData, byte[] maskData,PdfObject imageObject, PdfObject maskObject, GenericColorSpace colorSpace, GenericColorSpace maskCS){
byte[] objectData = imageData.getObjectData();
int iw=imageData.getWidth();
int ih=imageData.getHeight();
int id=imageData.getDepth();
float[] matte = maskObject.getFloatArray(PdfDictionary.Matte);
smaskData.getFilter(maskObject);
if(smaskData.isDCT()){
maskData=JPEGDecoder.getBytesFromJPEG(maskData,maskCS,maskObject);
maskObject.setMixedArray(PdfDictionary.Filter,null);
maskObject.setDecodedStream(maskData);
}else if(smaskData.isJPX()){
maskData=JPeg2000ImageDecoder.getBytesFromJPEG2000(maskData,maskCS,maskObject);
maskObject.setMixedArray(PdfDictionary.Filter,null);
maskObject.setDecodedStream(maskData);
}else {
objectData = ColorSpaceConvertor.normaliseTo8Bit(id, iw, ih, objectData);
}
int sw=smaskData.getWidth();
int sh=smaskData.getHeight();
int sd=smaskData.getDepth();
float [] decodeArr = maskObject.getFloatArray(PdfDictionary.Decode);
if(decodeArr!=null && decodeArr[0]==1 && decodeArr[1]==0){ // data inverted refer to dec2011/example.pdf
for (int i = 0; i < maskData.length; i++) {
maskData[i]^= 0xff;
}
}
byte[] index=colorSpace.getIndexedMap();
if(index!=null){
index=colorSpace.convertIndexToRGB(index);
objectData=ColorSpaceConvertor.convertIndexToRGBByte(index, iw, ih, imageData.getCompCount(), id, objectData, false, false);
} else if (imageData.isDCT() || imageData.isJPX() || imageData.isJBIG()) {
} else if(colorSpace.getID()==ColorSpaces.DeviceGray){
objectData=colorSpace.dataToRGBByteArray(objectData,iw,ih,false);
if(matte!=null){
matte = new float[]{matte[0],matte[0],matte[0]};
}
} else if(colorSpace.getID()==ColorSpaces.CalRGB){
} else if(colorSpace.getID()==ColorSpaces.DeviceRGB){
} else {
objectData=colorSpace.dataToRGBByteArray(objectData,iw,ih,false);
}
maskData = ColorSpaceConvertor.normaliseTo8Bit(sd,sw, sh, maskData);
int imageDim = iw*ih;
int maskDim = sw*sh;
if(imageDim>maskDim){
maskData = getScaledBytes(maskData, sw, sh, iw, ih);
}else if(maskDim>imageDim){
objectData = getScaledBytes(objectData, iw, ih, sw, sh);
imageDim = maskDim;
iw = sw;
ih = sh;
}else{
//do nothing
}
int p = 0;
ByteBuffer buffer = ByteBuffer.allocate(iw*ih*4);
if (imageDim == objectData.length) {
int aa = 0;
for (int i = 0; i < imageDim; i++) {
byte r = objectData[i] ;
for (int j = 0; j < 3; j++) {
buffer.put(r);
}
buffer.put(maskData[aa++]); // write out maskData[aa++] directly and lose a ?
}
} else {
if(matte!=null){
for (int i = 0; i < maskData.length; i++) {
int a = maskData[i] & 0xff;
int r = objectData[p++] & 0xff;
int g = objectData[p++] & 0xff;
int b = objectData[p++] & 0xff;
if(a!=0){
double k = 255.0/a;
r = (int) ((r-matte[0])*k+matte[0]);
g = (int) ((g-matte[1])*k+matte[1]);
b = (int) ((b-matte[2])*k+matte[2]);
r = r < 0 ? 0 : r > 255 ? 255 : r;
g = g < 0 ? 0 : g > 255 ? 255 : g;
b = b < 0 ? 0 : b > 255 ? 255 : b;
}
byte[] bb = {(byte)r,(byte)g,(byte)b,(byte)a};
buffer.put(bb);
}
}else{
int expected = imageDim*3;
if(objectData.length> 16);
// yDiff = y - (yr << 16);
// yDiffMinus = 65536 - yDiff;
// yIndex = yr * sw;
// x = 0;
// for (int j = 0; j < dw; j++) {
// xr = (int) (x >> 16);
// xDiff = x - (xr << 16);
// xDiffMinus = 65536 - xDiff;
// index = yIndex + xr;
//
// A = data[index] & 0xff;
// B = data[index + 1] & 0xff;
// C = data[index + sw] & 0xff;
// D = data[index + sw + 1] & 0xff;
//
// gray = (int) ((A * xDiffMinus * yDiffMinus
// + B * xDiff * yDiffMinus
// + C * yDiff * xDiffMinus
// + D * xDiff * yDiff) >> 32);
//
// temp[offset++] = (byte) gray;
//
// x += xRatio;
// }
// y += yRatio;
// }
// return temp;
}
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 = MaskDataDecoder.convertSmaskData(decodeColorData, objectData, w, h, imageData, d, maskD, maskData, newSMask);
//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;ii
© 2015 - 2025 Weber Informatics LLC | Privacy Policy