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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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 BMP image type.
  27. *
  28. * @author Pankaj Narula
  29. * @version $Id$
  30. */
  31. public class BMPReader implements ImageReader {
  32. /** Length of the BMP header */
  33. protected static final int BMP_SIG_LENGTH = 46;
  34. /** offset to width */
  35. private static final int WIDTH_OFFSET = 18;
  36. /** offset to height */
  37. private static final int HEIGHT_OFFSET = 22;
  38. /** offset to horizontal res */
  39. private static final int HRES_OFFSET = 38;
  40. /** offset to vertical res */
  41. private static final int VRES_OFFSET = 42;
  42. /** {@inheritDoc} */
  43. public FopImage.ImageInfo verifySignature(String uri, InputStream bis,
  44. FOUserAgent ua) throws IOException {
  45. byte[] header = getDefaultHeader(bis);
  46. boolean supported = ((header[0] == (byte) 0x42)
  47. && (header[1] == (byte) 0x4d));
  48. if (supported) {
  49. FopImage.ImageInfo info = new FopImage.ImageInfo();
  50. info.dpiHorizontal = ua.getFactory().getSourceResolution();
  51. info.dpiVertical = info.dpiHorizontal;
  52. getDimension(header, info);
  53. info.originalURI = uri;
  54. info.mimeType = getMimeType();
  55. info.inputStream = bis;
  56. return info;
  57. } else {
  58. return null;
  59. }
  60. }
  61. /**
  62. * Returns the MIME type supported by this implementation.
  63. *
  64. * @return The MIME type
  65. */
  66. public String getMimeType() {
  67. return "image/bmp";
  68. }
  69. private void getDimension(byte[] header, FopImage.ImageInfo info) {
  70. // little endian notation
  71. int byte1 = header[WIDTH_OFFSET] & 0xff;
  72. int byte2 = header[WIDTH_OFFSET + 1] & 0xff;
  73. int byte3 = header[WIDTH_OFFSET + 2] & 0xff;
  74. int byte4 = header[WIDTH_OFFSET + 3] & 0xff;
  75. long l = (long) ((byte4 << 24) | (byte3 << 16)
  76. | (byte2 << 8) | byte1);
  77. info.width = (int) (l & 0xffffffff);
  78. byte1 = header[HEIGHT_OFFSET] & 0xff;
  79. byte2 = header[HEIGHT_OFFSET + 1] & 0xff;
  80. byte3 = header[HEIGHT_OFFSET + 2] & 0xff;
  81. byte4 = header[HEIGHT_OFFSET + 3] & 0xff;
  82. l = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1);
  83. info.height = (int) (l & 0xffffffff);
  84. byte1 = header[HRES_OFFSET] & 0xff;
  85. byte2 = header[HRES_OFFSET + 1] & 0xff;
  86. byte3 = header[HRES_OFFSET + 2] & 0xff;
  87. byte4 = header[HRES_OFFSET + 3] & 0xff;
  88. l = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1);
  89. if (l > 0) {
  90. info.dpiHorizontal = l / 39.37d;
  91. }
  92. byte1 = header[VRES_OFFSET] & 0xff;
  93. byte2 = header[VRES_OFFSET + 1] & 0xff;
  94. byte3 = header[VRES_OFFSET + 2] & 0xff;
  95. byte4 = header[VRES_OFFSET + 3] & 0xff;
  96. l = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1);
  97. if (l > 0) {
  98. info.dpiVertical = l / 39.37d;
  99. }
  100. }
  101. private byte[] getDefaultHeader(InputStream imageStream)
  102. throws IOException {
  103. byte[] header = new byte[BMP_SIG_LENGTH];
  104. try {
  105. imageStream.mark(BMP_SIG_LENGTH + 1);
  106. imageStream.read(header);
  107. imageStream.reset();
  108. } catch (IOException ex) {
  109. try {
  110. imageStream.reset();
  111. } catch (IOException exbis) {
  112. // throw the original exception, not this one
  113. }
  114. throw ex;
  115. }
  116. return header;
  117. }
  118. }