/**
  * Decompress the JPEG source image associated with this decompressor instance and output a
  * decompressed image to the given destination buffer.
  *
  * @param dstBuf buffer that will receive the decompressed image. This buffer should normally be
  *     <code>stride * scaledHeight</code> pixels in size, where <code>scaledHeight</code> can be
  *     determined by calling <code>
  * scalingFactor.{@link TJScalingFactor#getScaled getScaled}(jpegHeight)
  * </code> with one of the scaling factors returned from {@link TJ#getScalingFactors} or by
  *     calling {@link #getScaledHeight}. However, the buffer may also be larger than the
  *     dimensions of the JPEG image, in which case the <code>x</code>, <code>y</code>, and <code>
  *     stride</code> parameters can be used to specify the region into which the JPEG image should
  *     be decompressed.
  * @param x x offset (in pixels) of the region into which the JPEG image should be decompressed,
  *     relative to the start of <code>dstBuf</code>.
  * @param y y offset (in pixels) of the region into which the JPEG image should be decompressed,
  *     relative to the start of <code>dstBuf</code>.
  * @param desiredWidth desired width (in pixels) of the decompressed image (or image region.) If
  *     the desired image dimensions are different than the dimensions of the JPEG image being
  *     decompressed, then TurboJPEG will use scaling in the JPEG decompressor to generate the
  *     largest possible image that will fit within the desired dimensions. Setting this to 0 is
  *     the same as setting it to the width of the JPEG image (in other words, the width will not
  *     be considered when determining the scaled image size.)
  * @param stride pixels per line of the destination image. Normally, this should be set to <code>
  *     scaledWidth</code>, but you can use this to, for instance, decompress the JPEG image into a
  *     region of a larger image. NOTE: <code>scaledWidth</code> can be determined by calling
  *     <code>
  * scalingFactor.{@link TJScalingFactor#getScaled getScaled}(jpegWidth)
  * </code> or by calling {@link #getScaledWidth}. Setting this parameter to 0 is the equivalent of
  *     setting it to <code>scaledWidth</code>.
  * @param desiredHeight desired height (in pixels) of the decompressed image (or image region.) If
  *     the desired image dimensions are different than the dimensions of the JPEG image being
  *     decompressed, then TurboJPEG will use scaling in the JPEG decompressor to generate the
  *     largest possible image that will fit within the desired dimensions. Setting this to 0 is
  *     the same as setting it to the height of the JPEG image (in other words, the height will not
  *     be considered when determining the scaled image size.)
  * @param pixelFormat pixel format of the decompressed image (one of {@link TJ TJ.PF_*})
  * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*}
  */
 public void decompress(
     int[] dstBuf,
     int x,
     int y,
     int desiredWidth,
     int stride,
     int desiredHeight,
     int pixelFormat,
     int flags)
     throws Exception {
   if (jpegBuf == null) throw new Exception(NO_ASSOC_ERROR);
   if (dstBuf == null
       || x < 0
       || y < 0
       || desiredWidth < 0
       || stride < 0
       || desiredHeight < 0
       || pixelFormat < 0
       || pixelFormat >= TJ.NUMPF
       || flags < 0) throw new Exception("Invalid argument in decompress()");
   decompress(
       jpegBuf,
       jpegBufSize,
       dstBuf,
       x,
       y,
       desiredWidth,
       stride,
       desiredHeight,
       pixelFormat,
       flags);
 }
 /**
  * Decompress the JPEG source image associated with this decompressor instance and return a <code>
  * BufferedImage</code> instance containing the decompressed image.
  *
  * @param desiredWidth see {@link #decompress(byte[], int, int, int, int, int, int, int)} for
  *     description
  * @param desiredHeight see {@link #decompress(byte[], int, int, int, int, int, int, int)} for
  *     description
  * @param bufferedImageType the image type of the newly-created <code>BufferedImage</code>
  *     instance (for instance, <code>BufferedImage.TYPE_INT_RGB</code>)
  * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*}
  * @return a <code>BufferedImage</code> instance containing the decompressed image
  */
 public BufferedImage decompress(
     int desiredWidth, int desiredHeight, int bufferedImageType, int flags) throws Exception {
   if (desiredWidth < 0 || desiredHeight < 0 || flags < 0)
     throw new Exception("Invalid argument in decompress()");
   int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
   int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
   BufferedImage img = new BufferedImage(scaledWidth, scaledHeight, bufferedImageType);
   decompress(img, flags);
   return img;
 }
 /**
  * Decompress the JPEG source image associated with this decompressor instance and return a buffer
  * containing the decompressed image.
  *
  * @param desiredWidth see {@link #decompress(byte[], int, int, int, int, int, int, int)} for
  *     description
  * @param pitch see {@link #decompress(byte[], int, int, int, int, int, int, int)} for description
  * @param desiredHeight see {@link #decompress(byte[], int, int, int, int, int, int, int)} for
  *     description
  * @param pixelFormat pixel format of the decompressed image (one of {@link TJ TJ.PF_*})
  * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*}
  * @return a buffer containing the decompressed image
  */
 public byte[] decompress(
     int desiredWidth, int pitch, int desiredHeight, int pixelFormat, int flags) throws Exception {
   if (desiredWidth < 0
       || pitch < 0
       || desiredHeight < 0
       || pixelFormat < 0
       || pixelFormat >= TJ.NUMPF
       || flags < 0) throw new Exception("Invalid argument in decompress()");
   int pixelSize = TJ.getPixelSize(pixelFormat);
   int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
   int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
   if (pitch == 0) pitch = scaledWidth * pixelSize;
   byte[] buf = new byte[pitch * scaledHeight];
   decompress(buf, desiredWidth, pitch, desiredHeight, pixelFormat, flags);
   return buf;
 }
Пример #4
0
  public static void main(String[] argv) {

    BufferedImage img = null;
    byte[] bmpBuf = null;
    TJTransform xform = new TJTransform();
    int flags = 0;

    try {

      sf = TJ.getScalingFactors();

      if (argv.length < 2) {
        usage();
      }

      TJScalingFactor scaleFactor = new TJScalingFactor(1, 1);
      String inFormat = "jpg", outFormat = "jpg";
      int outSubsamp = -1, outQual = 95;
      boolean display = false;

      if (argv.length > 1) {
        for (int i = 1; i < argv.length; i++) {
          if (argv[i].length() < 2) continue;
          if (argv[i].length() > 2 && argv[i].substring(0, 3).equalsIgnoreCase("-sc")) {
            int match = 0;
            if (i < argv.length - 1) {
              String[] scaleArg = argv[++i].split("/");
              if (scaleArg.length == 2) {
                TJScalingFactor tempsf =
                    new TJScalingFactor(
                        Integer.parseInt(scaleArg[0]), Integer.parseInt(scaleArg[1]));
                for (int j = 0; j < sf.length; j++) {
                  if (tempsf.equals(sf[j])) {
                    scaleFactor = sf[j];
                    match = 1;
                    break;
                  }
                }
              }
            }
            if (match != 1) usage();
          }
          if (argv[i].equalsIgnoreCase("-h") || argv[i].equalsIgnoreCase("-?")) usage();
          if (argv[i].length() > 2 && argv[i].substring(0, 3).equalsIgnoreCase("-sa")) {
            if (i < argv.length - 1) {
              i++;
              if (argv[i].substring(0, 1).equalsIgnoreCase("g")) outSubsamp = TJ.SAMP_GRAY;
              else if (argv[i].equals("444")) outSubsamp = TJ.SAMP_444;
              else if (argv[i].equals("422")) outSubsamp = TJ.SAMP_422;
              else if (argv[i].equals("420")) outSubsamp = TJ.SAMP_420;
              else usage();
            } else usage();
          }
          if (argv[i].substring(0, 2).equalsIgnoreCase("-q")) {
            if (i < argv.length - 1) {
              int qual = Integer.parseInt(argv[++i]);
              if (qual >= 1 && qual <= 100) outQual = qual;
              else usage();
            } else usage();
          }
          if (argv[i].substring(0, 2).equalsIgnoreCase("-g")) xform.options |= TJTransform.OPT_GRAY;
          if (argv[i].equalsIgnoreCase("-hflip")) xform.op = TJTransform.OP_HFLIP;
          if (argv[i].equalsIgnoreCase("-vflip")) xform.op = TJTransform.OP_VFLIP;
          if (argv[i].equalsIgnoreCase("-transpose")) xform.op = TJTransform.OP_TRANSPOSE;
          if (argv[i].equalsIgnoreCase("-transverse")) xform.op = TJTransform.OP_TRANSVERSE;
          if (argv[i].equalsIgnoreCase("-rot90")) xform.op = TJTransform.OP_ROT90;
          if (argv[i].equalsIgnoreCase("-rot180")) xform.op = TJTransform.OP_ROT180;
          if (argv[i].equalsIgnoreCase("-rot270")) xform.op = TJTransform.OP_ROT270;
          if (argv[i].equalsIgnoreCase("-custom")) xform.cf = new TJExample();
          else if (argv[i].length() > 2 && argv[i].substring(0, 2).equalsIgnoreCase("-c")) {
            if (i >= argv.length - 1) usage();
            String[] cropArg = argv[++i].split(",");
            if (cropArg.length != 3) usage();
            String[] dimArg = cropArg[2].split("[xX]");
            if (dimArg.length != 2) usage();
            int tempx = Integer.parseInt(cropArg[0]);
            int tempy = Integer.parseInt(cropArg[1]);
            int tempw = Integer.parseInt(dimArg[0]);
            int temph = Integer.parseInt(dimArg[1]);
            if (tempx < 0 || tempy < 0 || tempw < 0 || temph < 0) usage();
            xform.x = tempx;
            xform.y = tempy;
            xform.width = tempw;
            xform.height = temph;
            xform.options |= TJTransform.OPT_CROP;
          }
          if (argv[i].substring(0, 2).equalsIgnoreCase("-d")) display = true;
          if (argv[i].equalsIgnoreCase("-fastupsample")) {
            System.out.println("Using fast upsampling code");
            flags |= TJ.FLAG_FASTUPSAMPLE;
          }
          if (argv[i].equalsIgnoreCase("-fastdct")) {
            System.out.println("Using fastest DCT/IDCT algorithm");
            flags |= TJ.FLAG_FASTDCT;
          }
          if (argv[i].equalsIgnoreCase("-accuratedct")) {
            System.out.println("Using most accurate DCT/IDCT algorithm");
            flags |= TJ.FLAG_ACCURATEDCT;
          }
        }
      }
      String[] inFileTokens = argv[0].split("\\.");
      if (inFileTokens.length > 1) inFormat = inFileTokens[inFileTokens.length - 1];
      String[] outFileTokens;
      if (display) outFormat = "bmp";
      else {
        outFileTokens = argv[1].split("\\.");
        if (outFileTokens.length > 1) outFormat = outFileTokens[outFileTokens.length - 1];
      }

      File file = new File(argv[0]);
      int width, height;

      if (inFormat.equalsIgnoreCase("jpg")) {
        FileInputStream fis = new FileInputStream(file);
        int inputSize = fis.available();
        if (inputSize < 1) {
          System.out.println("Input file contains no data");
          System.exit(1);
        }
        byte[] inputBuf = new byte[inputSize];
        fis.read(inputBuf);
        fis.close();

        TJDecompressor tjd;
        if (xform.op != TJTransform.OP_NONE || xform.options != 0 || xform.cf != null) {
          TJTransformer tjt = new TJTransformer(inputBuf);
          TJTransform[] t = new TJTransform[1];
          t[0] = xform;
          t[0].options |= TJTransform.OPT_TRIM;
          TJDecompressor[] tjdx = tjt.transform(t, 0);
          tjd = tjdx[0];
        } else tjd = new TJDecompressor(inputBuf);

        width = tjd.getWidth();
        height = tjd.getHeight();
        int inSubsamp = tjd.getSubsamp();
        System.out.println(
            "Source Image: "
                + width
                + " x "
                + height
                + " pixels, "
                + sampName[inSubsamp]
                + " subsampling");
        if (outSubsamp < 0) outSubsamp = inSubsamp;

        if (outFormat.equalsIgnoreCase("jpg")
            && (xform.op != TJTransform.OP_NONE || xform.options != 0)
            && scaleFactor.isOne()) {
          file = new File(argv[1]);
          FileOutputStream fos = new FileOutputStream(file);
          fos.write(tjd.getJPEGBuf(), 0, tjd.getJPEGSize());
          fos.close();
          System.exit(0);
        }

        width = scaleFactor.getScaled(width);
        height = scaleFactor.getScaled(height);

        if (!outFormat.equalsIgnoreCase("jpg"))
          img = tjd.decompress(width, height, BufferedImage.TYPE_INT_RGB, flags);
        else bmpBuf = tjd.decompress(width, 0, height, TJ.PF_BGRX, flags);
        tjd.close();
      } else {
        img = ImageIO.read(file);
        if (img == null) throw new Exception("Input image type not supported.");
        width = img.getWidth();
        height = img.getHeight();
        if (outSubsamp < 0) {
          if (img.getType() == BufferedImage.TYPE_BYTE_GRAY) outSubsamp = TJ.SAMP_GRAY;
          else outSubsamp = TJ.SAMP_444;
        }
      }
      System.gc();
      if (!display)
        System.out.print("Dest. Image (" + outFormat + "):  " + width + " x " + height + " pixels");

      if (display) {
        ImageIcon icon = new ImageIcon(img);
        JLabel label = new JLabel(icon, JLabel.CENTER);
        JOptionPane.showMessageDialog(null, label, "Output Image", JOptionPane.PLAIN_MESSAGE);
      } else if (outFormat.equalsIgnoreCase("jpg")) {
        System.out.println(", " + sampName[outSubsamp] + " subsampling, quality = " + outQual);
        TJCompressor tjc = new TJCompressor();
        int jpegSize;
        byte[] jpegBuf;

        tjc.setSubsamp(outSubsamp);
        tjc.setJPEGQuality(outQual);
        if (img != null) tjc.setSourceImage(img, 0, 0, 0, 0);
        else {
          tjc.setSourceImage(bmpBuf, 0, 0, width, 0, height, TJ.PF_BGRX);
        }
        jpegBuf = tjc.compress(flags);
        jpegSize = tjc.getCompressedSize();
        tjc.close();

        file = new File(argv[1]);
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(jpegBuf, 0, jpegSize);
        fos.close();
      } else {
        System.out.print("\n");
        file = new File(argv[1]);
        ImageIO.write(img, outFormat, file);
      }

    } catch (Exception e) {
      e.printStackTrace();
      System.exit(-1);
    }
  }
Пример #5
0
  private static void decompTest(
      TJDecompressor tjd,
      byte[] jpegBuf,
      int jpegSize,
      int w,
      int h,
      int pf,
      String baseName,
      int subsamp,
      int flags,
      TJScalingFactor sf)
      throws Exception {
    String pfStr, tempstr;
    double t;
    int scaledWidth = sf.getScaled(w);
    int scaledHeight = sf.getScaled(h);
    int temp1, temp2, imgType = pf;
    BufferedImage img = null;
    byte[] dstBuf = null;

    if (yuv == YUVENCODE) return;

    if (bi) {
      pf = biTypePF(imgType);
      pfStr = biTypeStr(imgType);
    } else pfStr = pixFormatStr[pf];

    System.out.print("JPEG -> ");
    if (yuv == YUVDECODE) System.out.print("YUV " + subName[subsamp] + " ... ");
    else {
      System.out.print(pfStr + " ");
      if (bi) System.out.print("(" + pixFormatStr[pf] + ") ");
      if ((flags & TJ.FLAG_BOTTOMUP) != 0) System.out.print("Bottom-Up ");
      else System.out.print("Top-Down  ");
      if (!sf.isOne()) System.out.print(sf.getNum() + "/" + sf.getDenom() + " ... ");
      else System.out.print("... ");
    }

    t = getTime();
    tjd.setJPEGImage(jpegBuf, jpegSize);
    if (tjd.getWidth() != w || tjd.getHeight() != h || tjd.getSubsamp() != subsamp)
      throw new Exception("Incorrect JPEG header");

    temp1 = scaledWidth;
    temp2 = scaledHeight;
    temp1 = tjd.getScaledWidth(temp1, temp2);
    temp2 = tjd.getScaledHeight(temp1, temp2);
    if (temp1 != scaledWidth || temp2 != scaledHeight) throw new Exception("Scaled size mismatch");

    if (yuv == YUVDECODE) dstBuf = tjd.decompressToYUV(flags);
    else {
      if (bi) img = tjd.decompress(scaledWidth, scaledHeight, imgType, flags);
      else dstBuf = tjd.decompress(scaledWidth, 0, scaledHeight, pf, flags);
    }
    t = getTime() - t;

    if (bi) {
      tempstr =
          baseName
              + "_dec_"
              + pfStr
              + "_"
              + (((flags & TJ.FLAG_BOTTOMUP) != 0) ? "BU" : "TD")
              + "_"
              + subName[subsamp]
              + "_"
              + (double) sf.getNum() / (double) sf.getDenom()
              + "x"
              + ".png";
      File file = new File(tempstr);
      ImageIO.write(img, "png", file);
    }

    if (yuv == YUVDECODE) {
      if (checkBufYUV(dstBuf, dstBuf.length, w, h, subsamp) == 1) System.out.print("Passed.");
      else {
        System.out.print("FAILED!");
        exitStatus = -1;
      }
    } else {
      if ((bi && checkImg(img, pf, subsamp, sf, flags) == 1)
          || (!bi
              && checkBuf(
                      dstBuf,
                      scaledWidth,
                      scaledWidth * TJ.getPixelSize(pf),
                      scaledHeight,
                      pf,
                      subsamp,
                      sf,
                      flags)
                  == 1)) System.out.print("Passed.");
      else {
        System.out.print("FAILED!");
        exitStatus = -1;
      }
    }
    System.out.format("  %.6f ms\n", t * 1000.);
  }
 /**
  * Decompress the JPEG source image associated with this decompressor instance and output a
  * decompressed image to the given <code>BufferedImage</code> instance.
  *
  * @param dstImage a <code>BufferedImage</code> instance that will receive the decompressed image
  * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*}
  */
 public void decompress(BufferedImage dstImage, int flags) throws Exception {
   if (dstImage == null || flags < 0) throw new Exception("Invalid argument in decompress()");
   int desiredWidth = dstImage.getWidth();
   int desiredHeight = dstImage.getHeight();
   int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
   int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
   if (scaledWidth != desiredWidth || scaledHeight != desiredHeight)
     throw new Exception(
         "BufferedImage dimensions do not match a scaled image size that TurboJPEG is capable of generating.");
   int pixelFormat;
   boolean intPixels = false;
   if (byteOrder == null) byteOrder = ByteOrder.nativeOrder();
   switch (dstImage.getType()) {
     case BufferedImage.TYPE_3BYTE_BGR:
       pixelFormat = TJ.PF_BGR;
       break;
     case BufferedImage.TYPE_4BYTE_ABGR:
     case BufferedImage.TYPE_4BYTE_ABGR_PRE:
       pixelFormat = TJ.PF_XBGR;
       break;
     case BufferedImage.TYPE_BYTE_GRAY:
       pixelFormat = TJ.PF_GRAY;
       break;
     case BufferedImage.TYPE_INT_BGR:
       if (byteOrder == ByteOrder.BIG_ENDIAN) pixelFormat = TJ.PF_XBGR;
       else pixelFormat = TJ.PF_RGBX;
       intPixels = true;
       break;
     case BufferedImage.TYPE_INT_RGB:
       if (byteOrder == ByteOrder.BIG_ENDIAN) pixelFormat = TJ.PF_XRGB;
       else pixelFormat = TJ.PF_BGRX;
       intPixels = true;
       break;
     case BufferedImage.TYPE_INT_ARGB:
     case BufferedImage.TYPE_INT_ARGB_PRE:
       if (byteOrder == ByteOrder.BIG_ENDIAN) pixelFormat = TJ.PF_ARGB;
       else pixelFormat = TJ.PF_BGRA;
       intPixels = true;
       break;
     default:
       throw new Exception("Unsupported BufferedImage format");
   }
   WritableRaster wr = dstImage.getRaster();
   if (intPixels) {
     SinglePixelPackedSampleModel sm = (SinglePixelPackedSampleModel) dstImage.getSampleModel();
     int stride = sm.getScanlineStride();
     DataBufferInt db = (DataBufferInt) wr.getDataBuffer();
     int[] buf = db.getData();
     if (jpegBuf == null) throw new Exception(NO_ASSOC_ERROR);
     decompress(jpegBuf, jpegBufSize, buf, scaledWidth, stride, scaledHeight, pixelFormat, flags);
   } else {
     ComponentSampleModel sm = (ComponentSampleModel) dstImage.getSampleModel();
     int pixelSize = sm.getPixelStride();
     if (pixelSize != TJ.getPixelSize(pixelFormat))
       throw new Exception("Inconsistency between pixel format and pixel size in BufferedImage");
     int pitch = sm.getScanlineStride();
     DataBufferByte db = (DataBufferByte) wr.getDataBuffer();
     byte[] buf = db.getData();
     decompress(buf, scaledWidth, pitch, scaledHeight, pixelFormat, flags);
   }
 }
 /** @deprecated Use {@link #decompress(byte[], int, int, int, int, int, int, int)} instead. */
 public void decompress(
     byte[] dstBuf, int desiredWidth, int pitch, int desiredHeight, int pixelFormat, int flags)
     throws Exception {
   decompress(dstBuf, 0, 0, desiredWidth, pitch, desiredHeight, pixelFormat, flags);
 }