コード例 #1
0
ファイル: JPEGCodec.java プロジェクト: RayPlante/scifio
  /**
   * The CodecOptions parameter should have the following fields set: {@link CodecOptions#width
   * width} {@link CodecOptions#height height} {@link CodecOptions#channels channels} {@link
   * CodecOptions#bitsPerSample bitsPerSample} {@link CodecOptions#interleaved interleaved} {@link
   * CodecOptions#littleEndian littleEndian} {@link CodecOptions#signed signed}
   *
   * @see Codec#compress(byte[], CodecOptions)
   */
  @Override
  public byte[] compress(final byte[] data, CodecOptions options) throws FormatException {
    if (data == null || data.length == 0) return data;
    if (options == null) options = CodecOptions.getDefaultOptions();

    if (options.bitsPerSample > 8) {
      throw new FormatException("> 8 bit data cannot be compressed with JPEG.");
    }

    final ByteArrayOutputStream out = new ByteArrayOutputStream();
    final BufferedImage img =
        AWTImageTools.makeImage(
            data,
            options.width,
            options.height,
            options.channels,
            options.interleaved,
            options.bitsPerSample / 8,
            false,
            options.littleEndian,
            options.signed);

    try {
      ImageIO.write(img, "jpeg", out);
    } catch (final IOException e) {
      throw new FormatException("Could not write JPEG data", e);
    }
    return out.toByteArray();
  }
コード例 #2
0
ファイル: JPEGCodec.java プロジェクト: RayPlante/scifio
  /**
   * The CodecOptions parameter should have the following fields set: {@link
   * CodecOptions#interleaved interleaved} {@link CodecOptions#littleEndian littleEndian}
   *
   * @see Codec#decompress(RandomAccessInputStream, CodecOptions)
   */
  @Override
  public byte[] decompress(final RandomAccessInputStream in, CodecOptions options)
      throws FormatException, IOException {
    BufferedImage b;
    final long fp = in.getFilePointer();
    try {
      try {
        while (in.read() != (byte) 0xff || in.read() != (byte) 0xd8) {
          /* Read to data. */
        }
        in.seek(in.getFilePointer() - 2);
      } catch (final EOFException e) {
        in.seek(fp);
      }

      b = ImageIO.read(new BufferedInputStream(new DataInputStream(in), 8192));
    } catch (final IOException exc) {
      // probably a lossless JPEG; delegate to LosslessJPEGCodec
      in.seek(fp);
      return new LosslessJPEGCodec().decompress(in, options);
    }

    if (options == null) options = CodecOptions.getDefaultOptions();

    final byte[][] buf = AWTImageTools.getPixelBytes(b, options.littleEndian);

    // correct for YCbCr encoding, if necessary
    if (options.ycbcr && buf.length == 3) {
      final int nBytes = buf[0].length / (b.getWidth() * b.getHeight());
      final int mask = (int) (Math.pow(2, nBytes * 8) - 1);
      for (int i = 0; i < buf[0].length; i += nBytes) {
        final int y = DataTools.bytesToInt(buf[0], i, nBytes, options.littleEndian);
        int cb = DataTools.bytesToInt(buf[1], i, nBytes, options.littleEndian);
        int cr = DataTools.bytesToInt(buf[2], i, nBytes, options.littleEndian);

        cb = Math.max(0, cb - 128);
        cr = Math.max(0, cr - 128);

        final int red = (int) (y + 1.402 * cr) & mask;
        final int green = (int) (y - 0.34414 * cb - 0.71414 * cr) & mask;
        final int blue = (int) (y + 1.772 * cb) & mask;

        DataTools.unpackBytes(red, buf[0], i, nBytes, options.littleEndian);
        DataTools.unpackBytes(green, buf[1], i, nBytes, options.littleEndian);
        DataTools.unpackBytes(blue, buf[2], i, nBytes, options.littleEndian);
      }
    }

    byte[] rtn = new byte[buf.length * buf[0].length];
    if (buf.length == 1) rtn = buf[0];
    else {
      if (options.interleaved) {
        int next = 0;
        for (int i = 0; i < buf[0].length; i++) {
          for (int j = 0; j < buf.length; j++) {
            rtn[next++] = buf[j][i];
          }
        }
      } else {
        for (int i = 0; i < buf.length; i++) {
          System.arraycopy(buf[i], 0, rtn, i * buf[0].length, buf[i].length);
        }
      }
    }
    return rtn;
  }