code: package org.sunflow.image.readers;
  
  import java.io.BufferedInputStream;
  import java.io.FileInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  
  import org.sunflow.image.Bitmap;
  import org.sunflow.image.BitmapReader;
  import org.sunflow.image.formats.BitmapXYZ;
  
  /**
   * Reads images in Indigo's native XYZ format.
   * http://www2.indigorenderer.com/joomla/forum/viewtopic.php?p=11430
   */
  public class IGIBitmapReader implements BitmapReader {
      public Bitmap load(String filename, boolean isLinear) throws IOException, BitmapFormatException {
          InputStream stream = new BufferedInputStream(new FileInputStream(filename));
          // read header
          int magic = read32i(stream);
          int version = read32i(stream);
          stream.skip(8); // skip number of samples (double value)
          int width = read32i(stream);
          int height = read32i(stream);
          int superSample = read32i(stream); // super sample factor
          int compression = read32i(stream);
          int dataSize = read32i(stream);
          int colorSpace = read32i(stream);
          stream.skip(5000); // skip the rest of the header (unused for now)
          // error checking
          if (magic != 66613373)
              throw new BitmapFormatException("wrong magic: " + magic);
          if (version != 1)
              throw new BitmapFormatException("unsupported version: " + version);
          if (compression != 0)
              throw new BitmapFormatException("unsupported compression: " + compression);
          if (colorSpace != 0)
              throw new BitmapFormatException("unsupported color space: " + colorSpace);
          if (dataSize != (width * height * 12))
              throw new BitmapFormatException("invalid data block size: " + dataSize);
          if (width <= 0 || height <= 0)
              throw new BitmapFormatException("invalid image size: " + width + "x" + height);
          if (superSample <= 0)
              throw new BitmapFormatException("invalid super sample factor: " + superSample);
          if ((width % superSample) != 0 || (height % superSample) != 0)
              throw new BitmapFormatException("invalid image size: " + width + "x" + height);
          float[] xyz = new float[width * height * 3];
          for (int y = 0, i = 3 * (height - 1) * width; y < height; y++, i -= 6 * width) {
              for (int x = 0; x < width; x++, i += 3) {
                  xyz[i + 0] = read32f(stream);
                  xyz[i + 1] = read32f(stream);
                  xyz[i + 2] = read32f(stream);
              }
          }
          stream.close();
          if (superSample > 1) {
              // rescale image (basic box filtering)
              float[] rescaled = new float[xyz.length / (superSample * superSample)];
              float inv = 1.0f / (superSample * superSample);
              for (int y = 0, i = 0; y < height; y += superSample) {
                  for (int x = 0; x < width; x += superSample, i += 3) {
                      float X = 0;
                      float Y = 0;
                      float Z = 0;
                      for (int sy = 0; sy < superSample; sy++) {
                          for (int sx = 0; sx < superSample; sx++) {
                              int offset = 3 * ((x + sx + (y + sy) * width));
                              X += xyz[offset + 0];
                              Y += xyz[offset + 1];
                              Z += xyz[offset + 2];
                          }
                      }
                      rescaled[i + 0] = X * inv;
                      rescaled[i + 1] = Y * inv;
                      rescaled[i + 2] = Z * inv;
                  }
              }
              return new BitmapXYZ(width / superSample, height / superSample, rescaled);
          } else
              return new BitmapXYZ(width, height, xyz);
      }
  
      private static final int read32i(InputStream stream) throws IOException {
          int i = stream.read();
          i |= stream.read() << 8;
          i |= stream.read() << 16;
          i |= stream.read() << 24;
          return i;
      }
  
      private static final float read32f(InputStream stream) throws IOException {
          return Float.intBitsToFloat(read32i(stream));
      }
  }