Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

EMFReader.java 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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.image.analyser;
  19. // Java
  20. import java.io.InputStream;
  21. import java.io.IOException;
  22. // FOP
  23. import org.apache.fop.image.FopImage;
  24. import org.apache.fop.apps.FOUserAgent;
  25. /**
  26. * ImageReader object for EMF image type.
  27. *
  28. * @author Peter Herweg
  29. */
  30. public class EMFReader implements ImageReader {
  31. /** Length of the EMF header */
  32. protected static final int EMF_SIG_LENGTH = 88;
  33. /** offset to signature */
  34. private static final int SIGNATURE_OFFSET = 40;
  35. /** offset to width */
  36. private static final int WIDTH_OFFSET = 32;
  37. /** offset to height */
  38. private static final int HEIGHT_OFFSET = 36;
  39. /** offset to horizontal resolution in pixel */
  40. private static final int HRES_PIXEL_OFFSET = 72;
  41. /** offset to vertical resolution in pixel */
  42. private static final int VRES_PIXEL_OFFSET = 76;
  43. /** offset to horizontal resolution in mm */
  44. private static final int HRES_MM_OFFSET = 80;
  45. /** offset to vertical resolution in mm */
  46. private static final int VRES_MM_OFFSET = 84;
  47. /** {@inheritDoc} */
  48. public FopImage.ImageInfo verifySignature(String uri, InputStream bis,
  49. FOUserAgent ua) throws IOException {
  50. byte[] header = getDefaultHeader(bis);
  51. boolean supported
  52. = ( (header[SIGNATURE_OFFSET + 0] == (byte) 0x20)
  53. && (header[SIGNATURE_OFFSET + 1] == (byte) 0x45)
  54. && (header[SIGNATURE_OFFSET + 2] == (byte) 0x4D)
  55. && (header[SIGNATURE_OFFSET + 3] == (byte) 0x46) );
  56. if (supported) {
  57. FopImage.ImageInfo info = getDimension(header);
  58. info.originalURI = uri;
  59. info.mimeType = getMimeType();
  60. info.inputStream = bis;
  61. return info;
  62. } else {
  63. return null;
  64. }
  65. }
  66. /**
  67. * Returns the MIME type supported by this implementation.
  68. *
  69. * @return The MIME type
  70. */
  71. public String getMimeType() {
  72. return "image/emf";
  73. }
  74. private FopImage.ImageInfo getDimension(byte[] header) {
  75. FopImage.ImageInfo info = new FopImage.ImageInfo();
  76. long value = 0;
  77. int byte1;
  78. int byte2;
  79. int byte3;
  80. int byte4;
  81. // little endian notation
  82. //resolution
  83. byte1 = header[HRES_MM_OFFSET] & 0xff;
  84. byte2 = header[HRES_MM_OFFSET + 1] & 0xff;
  85. byte3 = header[HRES_MM_OFFSET + 2] & 0xff;
  86. byte4 = header[HRES_MM_OFFSET + 3] & 0xff;
  87. long hresMM = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1);
  88. byte1 = header[VRES_MM_OFFSET] & 0xff;
  89. byte2 = header[VRES_MM_OFFSET + 1] & 0xff;
  90. byte3 = header[VRES_MM_OFFSET + 2] & 0xff;
  91. byte4 = header[VRES_MM_OFFSET + 3] & 0xff;
  92. long vresMM = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1);
  93. byte1 = header[HRES_PIXEL_OFFSET] & 0xff;
  94. byte2 = header[HRES_PIXEL_OFFSET + 1] & 0xff;
  95. byte3 = header[HRES_PIXEL_OFFSET + 2] & 0xff;
  96. byte4 = header[HRES_PIXEL_OFFSET + 3] & 0xff;
  97. long hresPixel = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1);
  98. byte1 = header[VRES_PIXEL_OFFSET] & 0xff;
  99. byte2 = header[VRES_PIXEL_OFFSET + 1] & 0xff;
  100. byte3 = header[VRES_PIXEL_OFFSET + 2] & 0xff;
  101. byte4 = header[VRES_PIXEL_OFFSET + 3] & 0xff;
  102. long vresPixel = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1);
  103. info.dpiHorizontal = hresPixel / (hresMM / 25.4f);
  104. info.dpiVertical = vresPixel / (vresMM / 25.4f);
  105. //width
  106. byte1 = header[WIDTH_OFFSET] & 0xff;
  107. byte2 = header[WIDTH_OFFSET + 1] & 0xff;
  108. byte3 = header[WIDTH_OFFSET + 2] & 0xff;
  109. byte4 = header[WIDTH_OFFSET + 3] & 0xff;
  110. value = (long) ((byte4 << 24) | (byte3 << 16)
  111. | (byte2 << 8) | byte1);
  112. value = Math.round(value / 100f / 25.4f * info.dpiHorizontal);
  113. info.width = (int) (value & 0xffffffff);
  114. //height
  115. byte1 = header[HEIGHT_OFFSET] & 0xff;
  116. byte2 = header[HEIGHT_OFFSET + 1] & 0xff;
  117. byte3 = header[HEIGHT_OFFSET + 2] & 0xff;
  118. byte4 = header[HEIGHT_OFFSET + 3] & 0xff;
  119. value = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1);
  120. value = Math.round(value / 100f / 25.4f * info.dpiVertical);
  121. info.height = (int) (value & 0xffffffff);
  122. return info;
  123. }
  124. private byte[] getDefaultHeader(InputStream imageStream)
  125. throws IOException {
  126. byte[] header = new byte[EMF_SIG_LENGTH];
  127. try {
  128. imageStream.mark(EMF_SIG_LENGTH + 1);
  129. imageStream.read(header);
  130. imageStream.reset();
  131. } catch (IOException ex) {
  132. try {
  133. imageStream.reset();
  134. } catch (IOException exbis) {
  135. // throw the original exception, not this one
  136. }
  137. throw ex;
  138. }
  139. return header;
  140. }
  141. }