pixelmed
JPEGLosslessImageReaderSpi.java
Go to the documentation of this file.
1 /* Copyright (c) 2015, David A. Clunie DBA Pixelmed Publishing. All rights reserved. */
2 package com.pixelmed.imageio;
3 
4 // follow the pattern described in "http://docs.oracle.com/javase/1.5.0/docs/guide/imageio/spec/extending.fm3.html"
5 
8 
9 import java.io.IOException;
10 import java.util.Locale;
11 import javax.imageio.ImageReader;
12 import javax.imageio.spi.ImageReaderSpi;
13 import javax.imageio.stream.ImageInputStream;
14 
15 public class JPEGLosslessImageReaderSpi extends ImageReaderSpi {
16 
17  private static final String identString = "@(#) $Header: /userland/cvs/codec/com/pixelmed/imageio/JPEGLosslessImageReaderSpi.java,v 1.5 2016/01/16 15:07:52 dclunie Exp $";
18 
19  static final String vendorName = "PixelMed Publishing, LLC.";
20  static final String version = "0.01";
21  static final String readerClassName = "com.pixelmed.imageio.JPEGLosslessImageReader";
22  static final String description = "PixelMed JPEG Lossless Image Reader";
23 
24  public static final Class<?>[] inputTypes = { ImageInputStream.class }; // current JavaDoc says STANDARD_INPUT_TYPE is deprecated
25 
26  static final String[] names = { "jpeg-lossless" }; // this is what Sun JIIO JAI codecs use to recognize JPEG lossless
27  static final String[] suffixes = { "ljpeg", "jpl" }; // not "jls", which is JPEG-LS; "ljpeg" was used by USF Mammo
28  static final String[] MIMETypes = null; // current JavaDoc says null or empty array OK
29 
30  static final String nativeImageMetadataFormatName = "com.pixelmed.imageio.JPEGLosslessMetadata_0.1";
31  static final String nativeImageMetadataFormatClassName = "com.pixelmed.imageio.JPEGLosslessMetadata";
32 
34  super(
35  vendorName,
36  version,
37  names,
38  suffixes,
39  MIMETypes,
40  readerClassName,
41  inputTypes,
42  null/*writerSpiNames*/,
43  false/*supportsStandardStreamMetadataFormat*/,
44  null/*nativeStreamMetadataFormatName*/,
45  null/*nativeStreamMetadataFormatClassName*/,
46  null/*extraStreamMetadataFormatNames*/,
47  null/*extraStreamMetadataFormatClassNames*/,
48  false/*supportsStandardImageMetadataFormat*/,
49  nativeImageMetadataFormatName,
50  nativeImageMetadataFormatClassName,
51  null/*extraImageMetadataFormatNames*/,
52  null/*extraImageMetadataFormatClassNames*/);
53  }
54 
55  public boolean canDecodeInput(Object input) throws IOException {
56  // Need SOI Start of Image
57  // May be intervening table/misc segments
58  // Need SOF3 Huffman Lossless Sequential length variable 0x0b
59  boolean canDecode = false;
60  try {
61  if (input instanceof ImageInputStream) {
62  ImageInputStream stream = (ImageInputStream)input;
63  byte[] b = new byte[4];
64  stream.mark();
65  stream.readFully(b,0,2);
66  if (b[0] == (byte)0xff && b[1] == (byte)0xd8) { // have SOI
67  int markerprefix = stream.read();
68  while (markerprefix == 0xff) { // keep reading until we have an SOF or until not a marker segment
69  int marker = stream.read();
70  marker|=0xff00; // convention is to express them with the leading ff, so that is what we look up
71 //System.err.println("JPEGLosslessImageReaderSpi.canDecodeInput(): have marker "+Utilities.toPaddedHexString(marker,4)+" "+Markers.getAbbreviation(marker));
72  // should not have to worry about stuffed bytes in ECS or padding because we never get that far in the stream
73  if (Markers.isSOF(marker)) {
74 //System.err.println("JPEGLosslessImageReaderSpi.canDecodeInput(): have some type of SOF marker");
75  if (marker == Markers.SOF3) {
76 //System.err.println("JPEGLosslessImageReaderSpi.canDecodeInput(): have SOF3");
77  canDecode = true;
78  }
79  break; // stop reading after any SOF
80  }
81  else if (marker == Markers.SOS) {
82  break; // stop reading at SOS since too late to get SOF3
83  }
84  else if (Markers.isVariableLengthJPEGSegment(marker)) {
85  stream.readFully(b,0,2);
86  int length=((b[0]&0xff)<<8) + (b[1]&0xff); // big endian
87  if (length > 2) {
88 //System.err.println("JPEGLosslessImageReaderSpi.canDecodeInput(): skipping variable length marker segment length="+length);
89  stream.skipBytes(length-2);
90  }
91  else {
92 //System.err.println("JPEGLosslessImageReaderSpi.canDecodeInput(): variable length marker segment with invalid length="+length);
93  break;
94  }
95  }
96  else if (Markers.isNoLengthJPEGSegment(marker)) {
97  }
98  else {
99  int length=Markers.isFixedLengthJPEGSegment(marker);
100  if (length == 0) {
101 //System.err.println("JPEGLosslessImageReaderSpi.canDecodeInput(): stopping on unrecognized marker segment");
102  break;
103  }
104  else {
105 //System.err.println("JPEGLosslessImageReaderSpi.canDecodeInput(): skipping fixed length marker segment length="+length);
106  stream.skipBytes(length-2);
107  }
108  }
109  markerprefix=stream.read();
110  }
111  }
112  // else no SOI so not JPEG
113  stream.reset();
114 System.err.println("JPEGLosslessImageReaderSpi.canDecodeInput() = "+canDecode);
115  }
116  }
117  catch (IOException e) {
118  }
119  return canDecode;
120  }
121 
122  public String getDescription(Locale locale) {
123  return description;
124  }
125 
126  public ImageReader createReaderInstance(Object extension) {
127  return new JPEGLosslessImageReader(this);
128  }
129 
130 }
com.pixelmed.codec.jpeg.Markers.isSOF
static final boolean isSOF(int marker)
Definition: Markers.java:187
com.pixelmed.codec.jpeg.Markers.SOF3
static final int SOF3
Definition: Markers.java:63
com.pixelmed.codec.jpeg
Definition: EntropyCodedSegment copy.java:3
com.pixelmed.codec.jpeg.Markers.SOS
static final int SOS
Definition: Markers.java:78
com.pixelmed
com.pixelmed.imageio.JPEGLosslessImageReaderSpi.JPEGLosslessImageReaderSpi
JPEGLosslessImageReaderSpi()
Definition: JPEGLosslessImageReaderSpi.java:33
com.pixelmed.codec.jpeg.Markers.isVariableLengthJPEGSegment
static final boolean isVariableLengthJPEGSegment(int marker)
Definition: Markers.java:183
com.pixelmed.imageio.JPEGLosslessImageReaderSpi.createReaderInstance
ImageReader createReaderInstance(Object extension)
Definition: JPEGLosslessImageReaderSpi.java:126
com.pixelmed.codec.jpeg.Markers
Definition: Markers.java:13
com.pixelmed.codec.jpeg.Markers.isNoLengthJPEGSegment
static final boolean isNoLengthJPEGSegment(int marker)
Definition: Markers.java:142
com.pixelmed.codec.jpeg.Utilities
Definition: Utilities.java:13
com.pixelmed.codec
com.pixelmed.imageio.JPEGLosslessImageReaderSpi.inputTypes
static final Class<?>[] inputTypes
Definition: JPEGLosslessImageReaderSpi.java:24
com.pixelmed.codec.jpeg.Markers.isFixedLengthJPEGSegment
static final int isFixedLengthJPEGSegment(int marker)
Definition: Markers.java:131
com.pixelmed.imageio.JPEGLosslessImageReaderSpi.getDescription
String getDescription(Locale locale)
Definition: JPEGLosslessImageReaderSpi.java:122
com.pixelmed.imageio.JPEGLosslessImageReader
Definition: JPEGLosslessImageReader.java:43
com
com.pixelmed.imageio.JPEGLosslessImageReaderSpi
Definition: JPEGLosslessImageReaderSpi.java:15
com.pixelmed.imageio.JPEGLosslessImageReaderSpi.canDecodeInput
boolean canDecodeInput(Object input)
Definition: JPEGLosslessImageReaderSpi.java:55