You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Tile.java 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.afp.ioca;
  19. import java.io.IOException;
  20. import java.io.OutputStream;
  21. import org.apache.fop.afp.modca.AbstractStructuredObject;
  22. import org.apache.fop.afp.util.BinaryUtils;
  23. public class Tile extends AbstractStructuredObject {
  24. private static final int MAX_DATA_LEN = 8191;
  25. private TilePosition tilePosition = null;
  26. private TileSize tileSize = null;
  27. private BandImage bandImage;
  28. private byte[] data;
  29. private IDEStructureParameter ideStructureParameter;
  30. private byte encoding = (byte) 0x03;
  31. private byte ideSize = 1;
  32. // private byte compression = (byte) 0xC0; // Baseline DCT in case of JPEG compression
  33. @Override
  34. public void writeContent(OutputStream os) throws IOException {
  35. tilePosition.writeToStream(os);
  36. tileSize.writeToStream(os);
  37. os.write(getImageEncodingParameter());
  38. os.write(getImageIDESizeParameter());
  39. if (bandImage != null) {
  40. bandImage.writeToStream(os);
  41. }
  42. if (ideStructureParameter != null) {
  43. ideStructureParameter.writeToStream(os);
  44. }
  45. if (data != null) {
  46. byte[] c = new byte[data.length / 4];
  47. byte[] m = new byte[data.length / 4];
  48. byte[] y = new byte[data.length / 4];
  49. byte[] k = new byte[data.length / 4];
  50. for (int j = 0; j < data.length / 4; j++) {
  51. c[j] = data[4 * j];
  52. m[j] = data[4 * j + 1];
  53. y[j] = data[4 * j + 2];
  54. k[j] = data[4 * j + 3];
  55. }
  56. final byte[] dataHeader = new byte[] {(byte) 0xFE, // ID
  57. (byte) 0x9C, // ID
  58. 0x00, // length
  59. 0x00, // length
  60. 0x00, // bandnum
  61. 0x00, // reserved
  62. 0x00 // reserved
  63. };
  64. final int lengthOffset = 2;
  65. dataHeader[4] = (byte) 0x01;
  66. writeChunksToStream(c, dataHeader, lengthOffset, MAX_DATA_LEN, os);
  67. dataHeader[4] = (byte) 0x02;
  68. writeChunksToStream(m, dataHeader, lengthOffset, MAX_DATA_LEN, os);
  69. dataHeader[4] = (byte) 0x03;
  70. writeChunksToStream(y, dataHeader, lengthOffset, MAX_DATA_LEN, os);
  71. dataHeader[4] = (byte) 0x04;
  72. writeChunksToStream(k, dataHeader, lengthOffset, MAX_DATA_LEN, os);
  73. }
  74. }
  75. @Override
  76. protected void writeStart(OutputStream os) throws IOException {
  77. final byte[] startData = new byte[] {(byte) 0x8C, // ID
  78. 0x00 // Length
  79. };
  80. os.write(startData);
  81. }
  82. @Override
  83. protected void writeEnd(OutputStream os) throws IOException {
  84. final byte[] endData = new byte[] {(byte) 0x8D, // ID
  85. 0x00, // Length
  86. };
  87. os.write(endData);
  88. }
  89. public void setPosition(TilePosition tilePosition) {
  90. this.tilePosition = tilePosition;
  91. }
  92. public void setSize(TileSize tileSize) {
  93. this.tileSize = tileSize;
  94. }
  95. public void setImageData(byte[] imageData) {
  96. this.data = imageData.clone();
  97. }
  98. protected static void writeChunksToStream(byte[] data, byte[] dataHeader, int lengthOffset,
  99. int maxChunkLength, OutputStream os) throws IOException {
  100. int dataLength = data.length;
  101. maxChunkLength -= 3;
  102. int numFullChunks = dataLength / maxChunkLength;
  103. int lastChunkLength = dataLength % maxChunkLength;
  104. byte[] len = {(byte) 0x1f, (byte) 0xff};
  105. int off = 0;
  106. if (numFullChunks > 0) {
  107. // write out full data chunks
  108. dataHeader[lengthOffset] = len[0]; // Length byte 1
  109. dataHeader[lengthOffset + 1] = len[1]; // Length byte 2
  110. for (int i = 0; i < numFullChunks; i++, off += maxChunkLength) {
  111. os.write(dataHeader);
  112. os.write(data, off, maxChunkLength);
  113. }
  114. }
  115. if (lastChunkLength > 0) {
  116. // write last data chunk
  117. len = BinaryUtils.convert(3 + lastChunkLength, 2);
  118. dataHeader[lengthOffset] = len[0]; // Length byte 1
  119. dataHeader[lengthOffset + 1] = len[1]; // Length byte 2
  120. os.write(dataHeader);
  121. os.write(data, off, lastChunkLength);
  122. }
  123. }
  124. public void setImageEncodingParameter(byte encoding) {
  125. this.encoding = encoding;
  126. }
  127. public void setImageIDESizeParameter(byte ideSize) {
  128. this.ideSize = ideSize;
  129. }
  130. public void setIDEStructureParameter(IDEStructureParameter ideStructureParameter) {
  131. this.ideStructureParameter = ideStructureParameter;
  132. }
  133. private byte[] getImageEncodingParameter() {
  134. final byte[] encodingData = new byte[] {(byte) 0x95, // ID
  135. 0x02, // Length
  136. encoding, (byte) (encoding == ImageContent.COMPID_JPEG ? 0xFE : 0x01), // RECID
  137. };
  138. return encodingData;
  139. }
  140. private byte[] getImageIDESizeParameter() {
  141. if (ideSize != 1) {
  142. final byte[] ideSizeData = new byte[] {(byte) 0x96, // ID
  143. 0x01, // Length
  144. ideSize};
  145. return ideSizeData;
  146. } else {
  147. return new byte[0];
  148. }
  149. }
  150. public void setBandImage(BandImage bandImage) {
  151. this.bandImage = bandImage;
  152. }
  153. }