git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1642893 13f79535-47bb-0310-9956-ffa450edef68tags/fop-2_0
@@ -22,10 +22,15 @@ package org.apache.fop.afp; | |||
import java.io.OutputStream; | |||
import org.apache.fop.afp.goca.GraphicsData; | |||
import org.apache.fop.afp.ioca.BandImage; | |||
import org.apache.fop.afp.ioca.ImageContent; | |||
import org.apache.fop.afp.ioca.ImageRasterData; | |||
import org.apache.fop.afp.ioca.ImageSegment; | |||
import org.apache.fop.afp.ioca.ImageSizeParameter; | |||
import org.apache.fop.afp.ioca.Tile; | |||
import org.apache.fop.afp.ioca.TilePosition; | |||
import org.apache.fop.afp.ioca.TileSize; | |||
import org.apache.fop.afp.ioca.TileTOC; | |||
import org.apache.fop.afp.modca.ActiveEnvironmentGroup; | |||
import org.apache.fop.afp.modca.ContainerDataDescriptor; | |||
import org.apache.fop.afp.modca.Document; | |||
@@ -628,4 +633,23 @@ public class Factory { | |||
return imageSizeParameter; | |||
} | |||
public TileTOC createTileTOC() { | |||
return new TileTOC(); | |||
} | |||
public TileSize createTileSize(int dataWidth, int dataHeight, int dataWidthRes, int dataHeightRes) { | |||
return new TileSize(dataWidth, dataHeight, dataWidthRes, dataHeightRes); | |||
} | |||
public TilePosition createTilePosition() { | |||
return new TilePosition(); | |||
} | |||
public Tile createTile() { | |||
return new Tile(); | |||
} | |||
public BandImage createBandImage() { | |||
return new BandImage(); | |||
} | |||
} |
@@ -0,0 +1,36 @@ | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||
* contributor license agreements. See the NOTICE file distributed with | |||
* this work for additional information regarding copyright ownership. | |||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||
* (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
/* $Id$ */ | |||
package org.apache.fop.afp.ioca; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import org.apache.fop.afp.modca.AbstractAFPObject; | |||
public class BandImage extends AbstractAFPObject { | |||
@Override | |||
public void writeToStream(OutputStream os) throws IOException { | |||
final byte[] startData = new byte[] {(byte) 0x98, // ID | |||
0x05, // Length | |||
0x04, 0x08, 0x08, 0x08, 0x08 }; | |||
os.write(startData); | |||
} | |||
} |
@@ -74,6 +74,10 @@ public class ImageContent extends AbstractStructuredObject { | |||
/** the image data */ | |||
private byte[] data; | |||
private TileTOC tileTOC; | |||
private Tile tile; // change to tiles | |||
/** | |||
* Main Constructor | |||
*/ | |||
@@ -171,7 +175,11 @@ public class ImageContent extends AbstractStructuredObject { | |||
* @param imageData the image data | |||
*/ | |||
public void setImageData(byte[] imageData) { | |||
this.data = imageData; | |||
if (tile != null) { | |||
tile.setImageData(imageData); | |||
} else { | |||
this.data = imageData; | |||
} | |||
} | |||
private static final int MAX_DATA_LEN = 65535; | |||
@@ -183,30 +191,47 @@ public class ImageContent extends AbstractStructuredObject { | |||
imageSizeParameter.writeToStream(os); | |||
} | |||
if (tileTOC != null) { | |||
tileTOC.writeToStream(os); | |||
} | |||
// TODO convert to triplet/parameter class | |||
os.write(getImageEncodingParameter()); | |||
if (tile == null) { | |||
os.write(getImageEncodingParameter()); | |||
os.write(getImageIDESizeParameter()); | |||
os.write(getImageIDESizeParameter()); | |||
} else { | |||
tile.setImageEncodingParameter(this.encoding); | |||
tile.setImageIDESizeParameter(this.ideSize); | |||
} | |||
if (getIDEStructureParameter() != null) { | |||
getIDEStructureParameter().writeToStream(os); | |||
if (tile == null) { | |||
if (getIDEStructureParameter() != null) { | |||
getIDEStructureParameter().writeToStream(os); | |||
} | |||
} else { | |||
if (getIDEStructureParameter() != null) { | |||
tile.setIDEStructureParameter(getIDEStructureParameter()); | |||
} | |||
} | |||
boolean useFS10 = (this.ideSize == 1); | |||
if (!useFS10) { | |||
if (!useFS10 && tileTOC == null) { | |||
os.write(getExternalAlgorithmParameter()); | |||
} | |||
final byte[] dataHeader = new byte[] { | |||
(byte)0xFE, // ID | |||
(byte)0x92, // ID | |||
0x00, // length | |||
0x00 // length | |||
}; | |||
final int lengthOffset = 2; | |||
if (tile != null) { | |||
tile.writeToStream(os); | |||
} | |||
// Image Data | |||
if (data != null) { | |||
final byte[] dataHeader = new byte[] {(byte) 0xFE, // ID | |||
(byte) 0x92, // ID | |||
0x00, // length | |||
0x00 // length | |||
}; | |||
final int lengthOffset = 2; | |||
writeChunksToStream(data, dataHeader, lengthOffset, MAX_DATA_LEN, os); | |||
} | |||
} | |||
@@ -291,4 +316,11 @@ public class ImageContent extends AbstractStructuredObject { | |||
} | |||
} | |||
public void setTileTOC(TileTOC toc) { | |||
this.tileTOC = toc; | |||
} | |||
public void addTile(Tile tile) { | |||
this.tile = tile; | |||
} | |||
} |
@@ -175,4 +175,14 @@ public class ImageSegment extends AbstractNamedAFPObject { | |||
}; | |||
os.write(data); | |||
} | |||
public void setTileTOC() { | |||
TileTOC toc = factory.createTileTOC(); | |||
getImageContent().setTileTOC(toc); | |||
} | |||
public void addTile(Tile tile) { | |||
getImageContent().addTile(tile); | |||
} | |||
} |
@@ -0,0 +1,176 @@ | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||
* contributor license agreements. See the NOTICE file distributed with | |||
* this work for additional information regarding copyright ownership. | |||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||
* (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
/* $Id$ */ | |||
package org.apache.fop.afp.ioca; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import org.apache.fop.afp.modca.AbstractStructuredObject; | |||
import org.apache.fop.afp.util.BinaryUtils; | |||
public class Tile extends AbstractStructuredObject { | |||
private static final int MAX_DATA_LEN = 8191; | |||
private TilePosition tilePosition = null; | |||
private TileSize tileSize = null; | |||
private BandImage bandImage; | |||
private byte[] data; | |||
private IDEStructureParameter ideStructureParameter; | |||
private byte encoding = (byte) 0x03; | |||
private byte ideSize = 1; | |||
// private byte compression = (byte) 0xC0; // Baseline DCT in case of JPEG compression | |||
@Override | |||
public void writeContent(OutputStream os) throws IOException { | |||
tilePosition.writeToStream(os); | |||
tileSize.writeToStream(os); | |||
os.write(getImageEncodingParameter()); | |||
os.write(getImageIDESizeParameter()); | |||
if (bandImage != null) { | |||
bandImage.writeToStream(os); | |||
} | |||
if (ideStructureParameter != null) { | |||
ideStructureParameter.writeToStream(os); | |||
} | |||
if (data != null) { | |||
byte[] c = new byte[data.length / 4]; | |||
byte[] m = new byte[data.length / 4]; | |||
byte[] y = new byte[data.length / 4]; | |||
byte[] k = new byte[data.length / 4]; | |||
for (int j = 0; j < data.length / 4; j++) { | |||
c[j] = data[4 * j]; | |||
m[j] = data[4 * j + 1]; | |||
y[j] = data[4 * j + 2]; | |||
k[j] = data[4 * j + 3]; | |||
} | |||
final byte[] dataHeader = new byte[] {(byte) 0xFE, // ID | |||
(byte) 0x9C, // ID | |||
0x00, // length | |||
0x00, // length | |||
0x00, // bandnum | |||
0x00, // reserved | |||
0x00 // reserved | |||
}; | |||
final int lengthOffset = 2; | |||
dataHeader[4] = (byte) 0x01; | |||
writeChunksToStream(c, dataHeader, lengthOffset, MAX_DATA_LEN, os); | |||
dataHeader[4] = (byte) 0x02; | |||
writeChunksToStream(m, dataHeader, lengthOffset, MAX_DATA_LEN, os); | |||
dataHeader[4] = (byte) 0x03; | |||
writeChunksToStream(y, dataHeader, lengthOffset, MAX_DATA_LEN, os); | |||
dataHeader[4] = (byte) 0x04; | |||
writeChunksToStream(k, dataHeader, lengthOffset, MAX_DATA_LEN, os); | |||
} | |||
} | |||
@Override | |||
protected void writeStart(OutputStream os) throws IOException { | |||
final byte[] startData = new byte[] {(byte) 0x8C, // ID | |||
0x00 // Length | |||
}; | |||
os.write(startData); | |||
} | |||
@Override | |||
protected void writeEnd(OutputStream os) throws IOException { | |||
final byte[] endData = new byte[] {(byte) 0x8D, // ID | |||
0x00, // Length | |||
}; | |||
os.write(endData); | |||
} | |||
public void setPosition(TilePosition tilePosition) { | |||
this.tilePosition = tilePosition; | |||
} | |||
public void setSize(TileSize tileSize) { | |||
this.tileSize = tileSize; | |||
} | |||
public void setImageData(byte[] imageData) { | |||
this.data = imageData.clone(); | |||
} | |||
protected static void writeChunksToStream(byte[] data, byte[] dataHeader, int lengthOffset, | |||
int maxChunkLength, OutputStream os) throws IOException { | |||
int dataLength = data.length; | |||
maxChunkLength -= 3; | |||
int numFullChunks = dataLength / maxChunkLength; | |||
int lastChunkLength = dataLength % maxChunkLength; | |||
byte[] len = {(byte) 0x1f, (byte) 0xff}; | |||
int off = 0; | |||
if (numFullChunks > 0) { | |||
// write out full data chunks | |||
dataHeader[lengthOffset] = len[0]; // Length byte 1 | |||
dataHeader[lengthOffset + 1] = len[1]; // Length byte 2 | |||
for (int i = 0; i < numFullChunks; i++, off += maxChunkLength) { | |||
os.write(dataHeader); | |||
os.write(data, off, maxChunkLength); | |||
} | |||
} | |||
if (lastChunkLength > 0) { | |||
// write last data chunk | |||
len = BinaryUtils.convert(3 + lastChunkLength, 2); | |||
dataHeader[lengthOffset] = len[0]; // Length byte 1 | |||
dataHeader[lengthOffset + 1] = len[1]; // Length byte 2 | |||
os.write(dataHeader); | |||
os.write(data, off, lastChunkLength); | |||
} | |||
} | |||
public void setImageEncodingParameter(byte encoding) { | |||
this.encoding = encoding; | |||
} | |||
public void setImageIDESizeParameter(byte ideSize) { | |||
this.ideSize = ideSize; | |||
} | |||
public void setIDEStructureParameter(IDEStructureParameter ideStructureParameter) { | |||
this.ideStructureParameter = ideStructureParameter; | |||
} | |||
private byte[] getImageEncodingParameter() { | |||
final byte[] encodingData = new byte[] {(byte) 0x95, // ID | |||
0x02, // Length | |||
encoding, (byte) (encoding == ImageContent.COMPID_JPEG ? 0xFE : 0x01), // RECID | |||
}; | |||
return encodingData; | |||
} | |||
private byte[] getImageIDESizeParameter() { | |||
if (ideSize != 1) { | |||
final byte[] ideSizeData = new byte[] {(byte) 0x96, // ID | |||
0x01, // Length | |||
ideSize}; | |||
return ideSizeData; | |||
} else { | |||
return new byte[0]; | |||
} | |||
} | |||
public void setBandImage(BandImage bandImage) { | |||
this.bandImage = bandImage; | |||
} | |||
} |
@@ -0,0 +1,37 @@ | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||
* contributor license agreements. See the NOTICE file distributed with | |||
* this work for additional information regarding copyright ownership. | |||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||
* (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
/* $Id$ */ | |||
package org.apache.fop.afp.ioca; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import org.apache.fop.afp.modca.AbstractAFPObject; | |||
public class TilePosition extends AbstractAFPObject { | |||
@Override | |||
public void writeToStream(OutputStream os) throws IOException { | |||
final byte[] startData = new byte[] {(byte) 0xB5, // ID | |||
0x08, // Length | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | |||
os.write(startData); | |||
} | |||
} |
@@ -0,0 +1,73 @@ | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||
* contributor license agreements. See the NOTICE file distributed with | |||
* this work for additional information regarding copyright ownership. | |||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||
* (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
/* $Id$ */ | |||
package org.apache.fop.afp.ioca; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import org.apache.fop.afp.modca.AbstractAFPObject; | |||
import org.apache.fop.afp.util.BinaryUtils; | |||
public class TileSize extends AbstractAFPObject { | |||
private int hSize = 0; | |||
private int vSize = 0; | |||
// private int hRes = 0; // hRes and vRes not used yet -probably need them in the future | |||
// private int vRes = 0; | |||
public TileSize(int hsize, int vsize, int hresol, int vresol) { | |||
this.hSize = hsize; | |||
this.vSize = vsize; | |||
// this.hRes = hresol; | |||
// this.vRes = vresol; | |||
} | |||
@Override | |||
public void writeToStream(OutputStream os) throws IOException { | |||
byte[] data = new byte[] { | |||
(byte)0xB6, // ID = Image Size Parameter | |||
0x09, // Length | |||
0x00, // THSIZE | |||
0x00, // | |||
0x00, // | |||
0x00, // | |||
0x00, // TVSIZE | |||
0x00, // | |||
0x00, // | |||
0x00, // | |||
0x01 // RELRES, can also be 0x02 | |||
}; | |||
byte[] w = BinaryUtils.convert(hSize, 4); | |||
data[2] = w[0]; | |||
data[3] = w[1]; | |||
data[4] = w[2]; | |||
data[5] = w[3]; | |||
byte[] h = BinaryUtils.convert(vSize, 4); | |||
data[6] = h[0]; | |||
data[7] = h[1]; | |||
data[8] = h[2]; | |||
data[9] = h[3]; | |||
os.write(data); | |||
} | |||
} |
@@ -0,0 +1,42 @@ | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||
* contributor license agreements. See the NOTICE file distributed with | |||
* this work for additional information regarding copyright ownership. | |||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||
* (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
/* $Id$ */ | |||
package org.apache.fop.afp.ioca; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import org.apache.fop.afp.modca.AbstractAFPObject; | |||
public class TileTOC extends AbstractAFPObject { | |||
@Override | |||
public void writeToStream(OutputStream os) throws IOException { | |||
byte[] data = new byte[] { | |||
(byte)0xFE, // Code | |||
(byte)0xBB, // Code | |||
(byte)0x00, // length | |||
(byte)0x02, // length | |||
(byte)0x00, | |||
(byte)0x00 | |||
}; | |||
os.write(data); | |||
} | |||
} |
@@ -19,17 +19,20 @@ | |||
package org.apache.fop.afp.modca; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import org.apache.commons.io.output.ByteArrayOutputStream; | |||
import org.apache.xmlgraphics.util.MimeConstants; | |||
import org.apache.fop.afp.AFPDataObjectInfo; | |||
import org.apache.fop.afp.AFPImageObjectInfo; | |||
import org.apache.fop.afp.Factory; | |||
import org.apache.fop.afp.ioca.BandImage; | |||
import org.apache.fop.afp.ioca.ImageSegment; | |||
import org.apache.fop.afp.ioca.Tile; | |||
import org.apache.fop.afp.ioca.TilePosition; | |||
import org.apache.fop.afp.ioca.TileSize; | |||
/** | |||
* An IOCA Image Data Object | |||
@@ -76,8 +79,21 @@ public class ImageObject extends AbstractDataObject { | |||
ImageDataDescriptor imageDataDescriptor | |||
= factory.createImageDataDescriptor(dataWidth, dataHeight, dataWidthRes, dataHeightRes); | |||
if (MimeConstants.MIME_AFP_IOCA_FS45.equals(imageObjectInfo.getMimeType())) { | |||
boolean setImageSize = true; | |||
if (MimeConstants.MIME_AFP_IOCA_FS45.equals(imageObjectInfo.getMimeType()) ) { | |||
imageDataDescriptor.setFunctionSet(ImageDataDescriptor.FUNCTION_SET_FS45); | |||
if (imageObjectInfo.getBitsPerPixel() == 32 ) { | |||
setImageSize = false; | |||
Tile tile = factory.createTile(); | |||
TilePosition tilePosition = factory.createTilePosition(); | |||
TileSize tileSize = factory.createTileSize(dataWidth, dataHeight, dataWidthRes, dataHeightRes); | |||
BandImage bandImage = factory.createBandImage(); | |||
tile.setPosition(tilePosition); | |||
tile.setSize(tileSize); | |||
tile.setBandImage(bandImage); | |||
getImageSegment().setTileTOC(); | |||
getImageSegment().addTile(tile); | |||
} | |||
} else if (imageObjectInfo.getBitsPerPixel() == 1) { | |||
imageDataDescriptor.setFunctionSet(ImageDataDescriptor.FUNCTION_SET_FS10); | |||
} | |||
@@ -85,7 +101,10 @@ public class ImageObject extends AbstractDataObject { | |||
getObjectEnvironmentGroup().setMapImageObject( | |||
new MapImageObject(dataObjectInfo.getMappingOption())); | |||
getImageSegment().setImageSize(dataWidth, dataHeight, dataWidthRes, dataHeightRes); | |||
if (setImageSize) { | |||
// not used for FS45 | |||
getImageSegment().setImageSize(dataWidth, dataHeight, dataWidthRes, dataHeightRes); | |||
} | |||
} | |||
/** | |||
@@ -175,4 +194,5 @@ public class ImageObject extends AbstractDataObject { | |||
copySF(data, Type.END, Category.IMAGE); | |||
os.write(data); | |||
} | |||
} |