Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
ImageReader.java
1 package ij.io;
2 import java.io.*;
3 import java.net.*;
4 import ij.*; //??
5 
8 public class ImageReader {
9 
10  private FileInfo fi;
11  private int width, height;
12  private long skipCount;
13  private int bytesPerPixel, bufferSize, byteCount, nPixels;
14  private boolean showProgressBar=true;
15  private int eofErrorCount;
16 
21  public ImageReader (FileInfo fi) {
22  this.fi = fi;
23  width = fi.width;
24  height = fi.height;
25  skipCount = fi.longOffset>0?fi.longOffset:fi.offset;
26  }
27 
28  void eofError() {
29  eofErrorCount++;
30  }
31 
32  byte[] read8bitImage(InputStream in) throws IOException {
33  byte[] pixels;
34  int totalRead = 0;
35  pixels = new byte[nPixels];
36  int count, actuallyRead;
37 
38  while (totalRead<byteCount) {
39  if (totalRead+bufferSize>byteCount)
40  count = byteCount-totalRead;
41  else
42  count = bufferSize;
43  actuallyRead = in.read(pixels, totalRead, count);
44  if (actuallyRead==-1) {eofError(); break;}
45  totalRead += actuallyRead;
46  showProgress((double)totalRead/byteCount);
47  }
48  return pixels;
49  }
50 
51  private void showProgress(double progress) {
52  if (showProgressBar)
53  IJ.showProgress(progress);
54  }
55 
57  short[] read16bitImage(InputStream in) throws IOException {
58  int pixelsRead;
59  byte[] buffer = new byte[bufferSize];
60  short[] pixels = new short[nPixels];
61  int totalRead = 0;
62  int base = 0;
63  int count, value;
64  int bufferCount;
65 
66  while (totalRead<byteCount) {
67  if ((totalRead+bufferSize)>byteCount)
68  bufferSize = byteCount-totalRead;
69  bufferCount = 0;
70  while (bufferCount<bufferSize) { // fill the buffer
71  count = in.read(buffer, bufferCount, bufferSize-bufferCount);
72  if (count==-1) {
73  eofError();
74  if (fi.fileType==FileInfo.GRAY16_SIGNED)
75  for (int i=base; i<pixels.length; i++)
76  pixels[i] = (short)32768;
77  return pixels;
78  }
79  bufferCount += count;
80  }
81  totalRead += bufferSize;
82  showProgress((double)totalRead/byteCount);
83  pixelsRead = bufferSize/bytesPerPixel;
84  if (fi.intelByteOrder) {
85  if (fi.fileType==FileInfo.GRAY16_SIGNED)
86  for (int i=base,j=0; i<(base+pixelsRead); i++,j+=2)
87  pixels[i] = (short)((((buffer[j+1]&0xff)<<8) | (buffer[j]&0xff))+32768);
88  else
89  for (int i=base,j=0; i<(base+pixelsRead); i++,j+=2)
90  pixels[i] = (short)(((buffer[j+1]&0xff)<<8) | (buffer[j]&0xff));
91  } else {
92  if (fi.fileType==FileInfo.GRAY16_SIGNED)
93  for (int i=base,j=0; i<(base+pixelsRead); i++,j+=2)
94  pixels[i] = (short)((((buffer[j]&0xff)<<8) | (buffer[j+1]&0xff))+32768);
95  else
96  for (int i=base,j=0; i<(base+pixelsRead); i++,j+=2)
97  pixels[i] = (short)(((buffer[j]&0xff)<<8) | (buffer[j+1]&0xff));
98  }
99  base += pixelsRead;
100  }
101  return pixels;
102  }
103 
104  float[] read32bitImage(InputStream in) throws IOException {
105  int pixelsRead;
106  byte[] buffer = new byte[bufferSize];
107  float[] pixels = new float[nPixels];
108  int totalRead = 0;
109  int base = 0;
110  int count, value;
111  int bufferCount;
112  int tmp;
113 
114  while (totalRead<byteCount) {
115  if ((totalRead+bufferSize)>byteCount)
116  bufferSize = byteCount-totalRead;
117  bufferCount = 0;
118  while (bufferCount<bufferSize) { // fill the buffer
119  count = in.read(buffer, bufferCount, bufferSize-bufferCount);
120  if (count==-1) {eofError(); return pixels;}
121  bufferCount += count;
122  }
123  totalRead += bufferSize;
124  showProgress((double)totalRead/byteCount);
125  pixelsRead = bufferSize/bytesPerPixel;
126  int j = 0;
127  if (fi.intelByteOrder)
128  for (int i=base; i < (base+pixelsRead); i++) {
129  tmp = (int)(((buffer[j+3]&0xff)<<24) | ((buffer[j+2]&0xff)<<16) | ((buffer[j+1]&0xff)<<8) | (buffer[j]&0xff));
130  if (fi.fileType==FileInfo.GRAY32_FLOAT)
131  pixels[i] = Float.intBitsToFloat(tmp);
132  else if (fi.fileType==FileInfo.GRAY32_UNSIGNED)
133  pixels[i] = (float)(tmp&0xffffffffL);
134  else
135  pixels[i] = tmp;
136  j += 4;
137  }
138  else
139  for (int i=base; i < (base+pixelsRead); i++) {
140  tmp = (int)(((buffer[j]&0xff)<<24) | ((buffer[j+1]&0xff)<<16) | ((buffer[j+2]&0xff)<<8) | (buffer[j+3]&0xff));
141  if (fi.fileType==FileInfo.GRAY32_FLOAT)
142  pixels[i] = Float.intBitsToFloat(tmp);
143  else if (fi.fileType==FileInfo.GRAY32_UNSIGNED)
144  pixels[i] = (float)(tmp&0xffffffffL);
145  else
146  pixels[i] = tmp;
147  j += 4;
148  }
149  base += pixelsRead;
150  }
151  return pixels;
152  }
153 
154  int[] readChunkyRGB(InputStream in) throws IOException {
155  int pixelsRead;
156  bufferSize = 24*width;
157  byte[] buffer = new byte[bufferSize];
158  int[] pixels = new int[nPixels];
159  int totalRead = 0;
160  int base = 0;
161  int count, value;
162  int bufferCount;
163  int r, g, b;
164 
165  while (totalRead<byteCount) {
166  if ((totalRead+bufferSize)>byteCount)
167  bufferSize = byteCount-totalRead;
168  bufferCount = 0;
169  while (bufferCount<bufferSize) { // fill the buffer
170  count = in.read(buffer, bufferCount, bufferSize-bufferCount);
171  if (count==-1) {eofError(); return pixels;}
172  bufferCount += count;
173  }
174  totalRead += bufferSize;
175  showProgress((double)totalRead/byteCount);
176  pixelsRead = bufferSize/bytesPerPixel;
177  boolean bgr = fi.fileType==FileInfo.BGR;
178  int j = 0;
179  for (int i=base; i<(base+pixelsRead); i++) {
180  if (bytesPerPixel==4)
181  j++; // ignore alfa byte
182  r = buffer[j++]&0xff;
183  g = buffer[j++]&0xff;
184  b = buffer[j++]&0xff;
185  if (bgr)
186  pixels[i] = 0xff000000 | (b<<16) | (g<<8) | r;
187  else
188  pixels[i] = 0xff000000 | (r<<16) | (g<<8) | b;
189  }
190  base += pixelsRead;
191  }
192  return pixels;
193  }
194 
195  int[] readPlanarRGB(InputStream in) throws IOException {
196  int planeSize = nPixels; // 1/3 image size
197  byte[] buffer = new byte[planeSize];
198  int[] pixels = new int[nPixels];
199  int r, g, b;
200 
201  int bytesRead;
202  int totalRead = 0;
203  showProgress(0.12);
204  bytesRead = in.read(buffer, 0, planeSize);
205  if (bytesRead==-1) {eofError(); return pixels;}
206  totalRead += bytesRead;
207  for (int i=0; i < planeSize; i++) {
208  r = buffer[i]&0xff;
209  pixels[i] = 0xff000000 | (r<<16);
210  }
211 
212  showProgress(0.37);
213  bytesRead = in.read(buffer, 0, planeSize);
214  if (bytesRead==-1) {eofError(); return pixels;}
215  totalRead += bytesRead;
216  for (int i=0; i < planeSize; i++) {
217  g = buffer[i]&0xff;
218  pixels[i] |= g<<8;
219  }
220 
221  showProgress(0.62);
222  bytesRead = in.read(buffer, 0, planeSize);
223  if (bytesRead==-1) {eofError(); return pixels;}
224  totalRead += bytesRead;
225  for (int i=0; i < planeSize; i++) {
226  b = buffer[i]&0xff;
227  pixels[i] |= b;
228  }
229 
230  showProgress(0.87);
231  return pixels;
232  }
233 
234  Object readRGB48(InputStream in) throws IOException {
235  int pixelsRead;
236  bufferSize = 24*width;
237  byte[] buffer = new byte[bufferSize];
238  short[] red = new short[nPixels];
239  short[] green = new short[nPixels];
240  short[] blue = new short[nPixels];
241  int totalRead = 0;
242  int base = 0;
243  int count, value;
244  int bufferCount;
245 
246  Object[] stack = new Object[3];
247  stack[0] = red;
248  stack[1] = green;
249  stack[2] = blue;
250  while (totalRead<byteCount) {
251  if ((totalRead+bufferSize)>byteCount)
252  bufferSize = byteCount-totalRead;
253  bufferCount = 0;
254  while (bufferCount<bufferSize) { // fill the buffer
255  count = in.read(buffer, bufferCount, bufferSize-bufferCount);
256  if (count==-1) {eofError(); return stack;}
257  bufferCount += count;
258  }
259  totalRead += bufferSize;
260  showProgress((double)totalRead/byteCount);
261  pixelsRead = bufferSize/bytesPerPixel;
262  if (fi.intelByteOrder) {
263  for (int i=base,j=0; i<(base+pixelsRead); i++) {
264  red[i] = (short)(((buffer[j+1]&0xff)<<8) | (buffer[j]&0xff)); j+=2;
265  green[i] = (short)(((buffer[j+1]&0xff)<<8) | (buffer[j]&0xff)); j+=2;
266  blue[i] = (short)(((buffer[j+1]&0xff)<<8) | (buffer[j]&0xff)); j+=2;
267  }
268  } else {
269  for (int i=base,j=0; i<(base+pixelsRead); i++) {
270  red[i] = (short)(((buffer[j]&0xff)<<8) | (buffer[j+1]&0xff)); j+=2;
271  green[i] = (short)(((buffer[j]&0xff)<<8) | (buffer[j+1]&0xff)); j+=2;
272  blue[i] = (short)(((buffer[j]&0xff)<<8) | (buffer[j+1]&0xff)); j+=2;
273  }
274  }
275  base += pixelsRead;
276  }
277  return stack;
278  }
279 
280  void skip(InputStream in) throws IOException {
281  if (skipCount>0) {
282  long bytesRead = 0;
283  int skipAttempts = 0;
284  long count;
285  while (bytesRead<skipCount) {
286  count = in.skip(skipCount-bytesRead);
287  skipAttempts++;
288  if (count==-1 || skipAttempts>5) break;
289  bytesRead += count;
290  //IJ.log("skip: "+skipCount+" "+count+" "+bytesRead+" "+skipAttempts);
291  }
292  }
293  byteCount = width*height*bytesPerPixel;
294  if (fi.fileType==FileInfo.BITMAP) {
295  int scan=width/8, pad = width%8;
296  if (pad>0) scan++;
297  byteCount = scan*height;
298  }
299  nPixels = width*height;
300  bufferSize = byteCount/25;
301  if (bufferSize<8192)
302  bufferSize = 8192;
303  else
304  bufferSize = (bufferSize/8192)*8192;
305  }
306 
312  public Object readPixels(InputStream in) {
313  try {
314  switch (fi.fileType) {
315  case FileInfo.GRAY8:
316  case FileInfo.COLOR8:
317  bytesPerPixel = 1;
318  skip(in);
319  return (Object)read8bitImage(in);
320  case FileInfo.GRAY16_SIGNED:
322  bytesPerPixel = 2;
323  skip(in);
324  return (Object)read16bitImage(in);
325  case FileInfo.GRAY32_INT:
327  case FileInfo.GRAY32_FLOAT:
328  bytesPerPixel = 4;
329  skip(in);
330  return (Object)read32bitImage(in);
331  case FileInfo.RGB:
332  case FileInfo.BGR:
333  case FileInfo.ARGB:
334  bytesPerPixel = fi.fileType==FileInfo.ARGB?4:3;
335  skip(in);
336  return (Object)readChunkyRGB(in);
337  case FileInfo.RGB_PLANAR:
338  bytesPerPixel = 3;
339  skip(in);
340  return (Object)readPlanarRGB(in);
341  case FileInfo.BITMAP:
342  bytesPerPixel = 1;
343  skip(in);
344  byte[] bitmap = read8bitImage(in);
345  expandBitmap(bitmap);
346  return (Object)bitmap;
347  case FileInfo.RGB48:
348  bytesPerPixel = 6;
349  skip(in);
350  return (Object)readRGB48(in);
351  default:
352  return null;
353  }
354  }
355  catch (IOException e) {
356  IJ.write("" + e);
357  return null;
358  }
359  }
360 
366  public Object readPixels(InputStream in, long skipCount) {
367  this.skipCount = skipCount;
368  showProgressBar = false;
369  Object pixels = readPixels(in);
370  if (eofErrorCount>0)
371  return null;
372  else
373  return pixels;
374  }
375 
380  public Object readPixels(String url) {
381  java.net.URL theURL;
382  InputStream is;
383  try {theURL = new URL(url);}
384  catch (MalformedURLException e) {IJ.write(""+e); return null;}
385  try {is = theURL.openStream();}
386  catch (IOException e) {IJ.write(""+e); return null;}
387  return readPixels(is);
388  }
389 
390  void expandBitmap(byte[] pixels) {
391  int scan=width/8;
392  int pad = width%8;
393  if (pad>0) scan++;
394  int len = scan*height;
395  byte bitmap[] = new byte [len];
396  System.arraycopy(pixels, 0, bitmap, 0, len);
397  int value1,value2, offset, index;
398  for (int y=0; y<height; y++) {
399  offset = y*scan;
400  index = y*width;
401  for (int x=0; x<scan; x++) {
402  value1 = bitmap[offset+x]&0xff;
403  for (int i=7; i>=0; i--) {
404  value2 = (value1&(1<<i))!=0?255:0;
405  if (index<pixels.length)
406  pixels[index++] = (byte)value2;
407  }
408  }
409  }
410  }
411 
412 }
413