Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* ===========================================
* 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-2017 IDRsolutions and Contributors.
*
* This file is part of JPedal/JPDF2HTML5
*
@LICENSE@
*
* ---------------
* BaseFilter.java
* ---------------
*/
package org.jpedal.io.filter;
import java.io.*;
import java.util.Map;
import org.jpedal.io.ObjectStore;
import org.jpedal.objects.raw.PdfObject;
import org.jpedal.utils.LogWriter;
/**
* common values
*/
public class BaseFilter {
final PdfObject decodeParms;
BufferedInputStream bis;
BufferedOutputStream streamCache;
Map cachedObjects;
BaseFilter(final PdfObject decodeParms) {
this.decodeParms = decodeParms;
}
/**
* inherited by several methods
*
* @return
*/
@SuppressWarnings("UnusedDeclaration")
public boolean hasError() {
return false;
}
void setupCachedObjectForDecoding(final String cacheName) throws IOException {
// rename file
final File tempFile2 = File.createTempFile("jpedal", ".raw", new File(ObjectStore.temp_dir));
cachedObjects.put(tempFile2.getAbsolutePath(), "x"); // store to
// delete when
// PDF closed
ObjectStore.copy(cacheName, tempFile2.getAbsolutePath());
final File rawFile = new File(cacheName);
rawFile.delete();
// where its going after decompression
streamCache = new BufferedOutputStream(new FileOutputStream(cacheName));
// where data is coming from
bis = new BufferedInputStream(new FileInputStream(tempFile2));
}
byte[] applyPredictor(final int predictor, final byte[] data, final int colors, final int bitsPerComponent, final int columns) throws Exception {
//no prediction (TIFF =1 PNG=10)
if (predictor == 1) { // || predictor==10){
return data;
} else {
final boolean isCached = data == null;
if (isCached) {
applyPredictorFunction(predictor, bis, streamCache, colors, bitsPerComponent, columns);
return null;
//calling it twice to size buffer itakes 1% on sample file as opposed to 9% to call it once with OutputStream
} else if (1 == 2) {
final BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(data));
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
applyPredictorFunction(predictor, bis, bos, colors, bitsPerComponent, columns);
return bos.toByteArray();
} else {
ByteArrayInputStream byis = new ByteArrayInputStream(data);
BufferedInputStream bis = new BufferedInputStream(byis);
//just workout size
final int count = applyPredictorFunction2(predictor, bis, null, colors, bitsPerComponent, columns);
byis.close();
bis.close();
final byte[] bos = new byte[count];
byis = new ByteArrayInputStream(data);
bis = new BufferedInputStream(byis);
//now actually get the size.
applyPredictorFunction2(predictor, bis, bos, colors, bitsPerComponent, columns);
byis.close();
bis.close();
return bos;
}
}
}
/**
* implement predictor function
*/
private static void applyPredictorFunction(final int mainPred, final BufferedInputStream bis,
final OutputStream bos, final int colors, final int bitsPerComponent, final int columns) throws Exception {
int predictor;
final int bytesAvailable = bis.available();
/*
* calculate values
*/
final int bpp = (colors * bitsPerComponent + 7) / 8; //actual Bytes for a pixel;
final int rowLength = (columns * colors * bitsPerComponent + 7) / 8 + bpp; //length of each row + predictor
//array to hold 2 lines
final byte[] thisLine = new byte[rowLength];
final byte[] lastLine = new byte[rowLength];
// extra predictor needed for optimization
int curPred;
//actual processing loop
try {
int byteCount = 0;
while (true) {
//exit after all used
if (bytesAvailable <= byteCount) {
break;
}
predictor = mainPred;
int i = 0;
int offset = bpp;
// PNG optimization.
if (predictor >= 10) {
curPred = bis.read();
if (curPred == -1) {
break;
}
curPred += 10;
} else {
curPred = predictor;
}
while (offset < rowLength) {
i = bis.read(thisLine, offset, rowLength - offset);
if (i == -1) {
break;
}
offset += i;
byteCount += i;
}
if (i == -1) {
break;
}
//apply
switch (curPred) {
case 2: //tiff (same as sub)
for (int i1 = bpp; i1 < rowLength; i1++) {
final int sub = thisLine[i1] & 0xff;
final int raw = thisLine[i1 - bpp] & 0xff;
thisLine[i1] = (byte) ((sub + raw) & 0xff);
bos.write(thisLine[i1]);
}
break;
case 10: //just pass through
for (int i1 = bpp; i1 < rowLength; i1++) {
bos.write(thisLine[i1]);
}
break;
case 11: //sub
for (int i1 = bpp; i1 < rowLength; i1++) {
final int sub = thisLine[i1] & 0xff;
final int raw = thisLine[i1 - bpp] & 0xff;
thisLine[i1] = (byte) ((sub + raw));
bos.write(thisLine[i1]);
}
break;
case 12: //up
for (int i1 = bpp; i1 < rowLength; i1++) {
final int sub = (lastLine[i1] & 0xff) + (thisLine[i1] & 0xff);
thisLine[i1] = (byte) (sub);
bos.write(thisLine[i1]);
}
break;
case 13: //avg
for (int i1 = bpp; i1 < rowLength; i1++) {
final int av = thisLine[i1] & 0xff;
final int floor = ((thisLine[i1 - bpp] & 0xff) + (lastLine[i1] & 0xff) >> 1);
thisLine[i1] = (byte) (av + floor);
bos.write(thisLine[i1]);
}
break;
case 14: //paeth (see http://www.w3.org/TR/PNG-Filters.html)
for (int i1 = bpp; i1 < rowLength; i1++) {
final int a = thisLine[i1 - bpp] & 0xff;
final int b = lastLine[i1] & 0xff;
final int c = lastLine[i1 - bpp] & 0xff;
final int p = a + b - c;
int pa = p - a, pb = p - b, pc = p - c;
//make sure positive
if (pa < 0) {
pa = -pa;
}
if (pb < 0) {
pb = -pb;
}
if (pc < 0) {
pc = -pc;
}
if (pa <= pb && pa <= pc) {
thisLine[i1] = (byte) (thisLine[i1] + a);
} else if (pb <= pc) {
thisLine[i1] = (byte) (thisLine[i1] + b);
} else {
thisLine[i1] = (byte) (thisLine[i1] + c);
}
bos.write(thisLine[i1]);
}
break;
case 15:
//implemented inside main code body
break;
}
//add to output and update line
System.arraycopy(thisLine, 0, lastLine, 0, lastLine.length);
}
bos.flush();
bos.close();
} catch (final Exception e) {
LogWriter.writeLog("Exception " + e + " accessing Predictor");
}
}
/**
* implement predictor function
*/
private static int applyPredictorFunction2(final int mainPred, final BufferedInputStream bis,
final byte[] bos, final int colors, final int bitsPerComponent, final int columns) throws Exception {
int count = 0;
int predictor;
final int bytesAvailable = bis.available();
final int bpp = (colors * bitsPerComponent + 7) / 8; //actual Bytes for a pixel;
final int rowLength = (columns * colors * bitsPerComponent + 7) / 8 + bpp; //length of each row + predictor
//array to hold 2 lines
final byte[] thisLine = new byte[rowLength];
final byte[] lastLine = new byte[rowLength];
// extra predictor needed for optimization
int curPred;
//actual processing loop
try {
int byteCount = 0;
while (true) {
//exit after all used
if (bytesAvailable <= byteCount) {
break;
}
predictor = mainPred;
int i = 0;
int offset = bpp;
// PNG optimization.
if (predictor >= 10) {
curPred = bis.read();
if (curPred == -1) {
break;
}
curPred += 10;
} else {
curPred = predictor;
}
while (offset < rowLength) {
i = bis.read(thisLine, offset, rowLength - offset);
if (i == -1) {
break;
}
offset += i;
byteCount += i;
}
if (i == -1) {
break;
}
//apply
switch (curPred) {
case 2: //tiff (same as sub)
for (int i1 = bpp; i1 < rowLength; i1++) {
final int sub = thisLine[i1] & 0xff;
final int raw = thisLine[i1 - bpp] & 0xff;
thisLine[i1] = (byte) ((sub + raw) & 0xff);
if (bos != null) {
bos[count] = thisLine[i1];
}
count++;
}
break;
case 10: //just pass through
for (int i1 = bpp; i1 < rowLength; i1++) {
if (bos != null) {
bos[count] = thisLine[i1];
}
count++;
}
break;
case 11: //sub
for (int i1 = bpp; i1 < rowLength; i1++) {
final int sub = thisLine[i1] & 0xff;
final int raw = thisLine[i1 - bpp] & 0xff;
thisLine[i1] = (byte) ((sub + raw));
if (bos != null) {
bos[count] = thisLine[i1];
}
count++;
}
break;
case 12: //up
for (int i1 = bpp; i1 < rowLength; i1++) {
final int sub = (lastLine[i1] & 0xff) + (thisLine[i1] & 0xff);
thisLine[i1] = (byte) (sub);
if (bos != null) {
bos[count] = thisLine[i1];
}
count++;
}
break;
case 13: //avg
for (int i1 = bpp; i1 < rowLength; i1++) {
final int av = thisLine[i1] & 0xff;
final int floor = ((thisLine[i1 - bpp] & 0xff) + (lastLine[i1] & 0xff) >> 1);
thisLine[i1] = (byte) (av + floor);
if (bos != null) {
bos[count] = thisLine[i1];
}
count++;
}
break;
case 14: //paeth (see http://www.w3.org/TR/PNG-Filters.html)
for (int i1 = bpp; i1 < rowLength; i1++) {
final int a = thisLine[i1 - bpp] & 0xff;
final int b = lastLine[i1] & 0xff;
final int c = lastLine[i1 - bpp] & 0xff;
final int p = a + b - c;
int pa = p - a, pb = p - b, pc = p - c;
//make sure positive
if (pa < 0) {
pa = -pa;
}
if (pb < 0) {
pb = -pb;
}
if (pc < 0) {
pc = -pc;
}
if (pa <= pb && pa <= pc) {
thisLine[i1] = (byte) (thisLine[i1] + a);
} else if (pb <= pc) {
thisLine[i1] = (byte) (thisLine[i1] + b);
} else {
thisLine[i1] = (byte) (thisLine[i1] + c);
}
if (bos != null) {
bos[count] = thisLine[i1];
}
count++;
}
break;
case 15:
//implemented inside main code body
break;
}
//add to output and update line
System.arraycopy(thisLine, 0, lastLine, 0, lastLine.length);
}
} catch (final Exception e) {
LogWriter.writeLog("Exception " + e + " accessing Predictor");
}
return count;
}
}