JPEGImageInputStream.java 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /* JPEGImageInputStream.java --
  2. Copyright (C) 2006 Free Software Foundation, Inc.
  3. This file is part of GNU Classpath.
  4. GNU Classpath is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. GNU Classpath is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Classpath; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  15. 02110-1301 USA.
  16. Linking this library statically or dynamically with other modules is
  17. making a combined work based on this library. Thus, the terms and
  18. conditions of the GNU General Public License cover the whole
  19. combination.
  20. As a special exception, the copyright holders of this library give you
  21. permission to link this library with independent modules to produce an
  22. executable, regardless of the license terms of these independent
  23. modules, and to copy and distribute the resulting executable under
  24. terms of your choice, provided that you also meet, for each linked
  25. independent module, the terms and conditions of the license of that
  26. module. An independent module is a module which is not derived from
  27. or based on this library. If you modify this library, you may extend
  28. this exception to your version of the library, but you are not
  29. obligated to do so. If you do not wish to do so, delete this
  30. exception statement from your version. */
  31. package gnu.javax.imageio.jpeg;
  32. import java.io.IOException;
  33. import javax.imageio.stream.ImageInputStream;
  34. import javax.imageio.stream.ImageInputStreamImpl;
  35. public class JPEGImageInputStream
  36. extends ImageInputStreamImpl
  37. {
  38. private ImageInputStream in;
  39. byte marker;
  40. public JPEGImageInputStream(ImageInputStream in)
  41. {
  42. super();
  43. this.in = in;
  44. }
  45. public int read()
  46. throws IOException
  47. {
  48. setBitOffset(0);
  49. return in.read();
  50. }
  51. public int read(byte[] data, int offset, int len)
  52. throws IOException
  53. {
  54. setBitOffset(0);
  55. return in.read(data, offset, len);
  56. }
  57. /**
  58. * Pull a byte from the stream, this checks to see if the byte is 0xff
  59. * and if the next byte isn't 0x00 (stuffed byte) it errors out. If it's
  60. * 0x00 then it simply ignores the byte.
  61. *
  62. * @return the next byte in the buffer
  63. *
  64. * @throws IOException TODO
  65. * @throws BitStreamException TODO
  66. */
  67. private byte pullByte() throws IOException, JPEGMarkerFoundException
  68. {
  69. byte mybyte = readByte();
  70. // FIXME: handle multiple 0xff in a row
  71. if(mybyte==(byte)(0xff))
  72. {
  73. byte secondbyte = readByte();
  74. if(secondbyte != (byte)(0x00))
  75. {
  76. marker = secondbyte;
  77. throw new JPEGMarkerFoundException();
  78. }
  79. }
  80. return mybyte;
  81. }
  82. /**
  83. * This returns the marker that was last encountered. This should only be
  84. * used if removeBit() throws a MarkerTagFound exception.
  85. *
  86. * @return marker as byte
  87. */
  88. public byte getMarker()
  89. {
  90. return marker;
  91. }
  92. /**
  93. * Removes a bit from the buffer. (Removes from the top of a queue). This
  94. * also checks for markers and throws MarkerTagFound exception if it does.
  95. * If MarkerTagFound is thrown you can use getMarker() method to get the
  96. * marker that caused the throw.
  97. *
  98. * @param l specifies how many bits you want to remove and add to the
  99. * integer
  100. * @return the amount of bits specified by l as an integer
  101. *
  102. * @throws IOException TODO
  103. * @throws JPEGMarkerFoundException
  104. * @throws BitStreamException TODO
  105. */
  106. public int readBit()
  107. throws IOException, JPEGMarkerFoundException
  108. {
  109. checkClosed();
  110. // Calc new bit offset here, readByte resets it.
  111. int newOffset = (bitOffset + 1) & 0x7;
  112. byte data = pullByte();
  113. if (bitOffset != 0)
  114. {
  115. seek(getStreamPosition() - 1);
  116. data = (byte) (data >> (8 - newOffset));
  117. }
  118. bitOffset = newOffset;
  119. return data & 0x1;
  120. }
  121. /**
  122. * This method skips over the the data and finds the next position
  123. * in the bit sequence with a X'FF' X'??' sequence. Multiple X'FF
  124. * bytes in sequence are considered padding and interpreted as one
  125. * X'FF byte.
  126. *
  127. * @return the next marker byte in the stream
  128. * @throws IOException if the end of the stream is reached
  129. * unexpectedly
  130. */
  131. public byte findNextMarker()
  132. throws IOException
  133. {
  134. boolean marked0xff = false;
  135. byte byteinfo = JPEGMarker.X00;
  136. setBitOffset(0);
  137. while (true)
  138. {
  139. byteinfo = readByte();
  140. if (!marked0xff)
  141. {
  142. if (byteinfo == JPEGMarker.XFF)
  143. marked0xff = true;
  144. }
  145. else
  146. {
  147. if (byteinfo == JPEGMarker.XFF)
  148. // Ignore the value 0xff when it is immediately
  149. // followed by another 0xff byte.
  150. continue;
  151. else if (byteinfo == JPEGMarker.X00)
  152. // The sequence 0xff 0x00 is used to encode the
  153. // actual value 0xff. So restart our search for a
  154. // marker.
  155. marked0xff = false;
  156. else
  157. // One or more 0xff values were follwed by a
  158. // non-0x00, non-0xff value so return this as the
  159. // marker byte.
  160. return byteinfo;
  161. }
  162. }
  163. }
  164. }