Пример #1
0
  public synchronized RenderedImage runDCRaw(dcrawMode mode, boolean secondaryPixels)
      throws IOException, UnknownImageTypeException, BadImageFileException {
    if (!m_decodable || (mode == dcrawMode.full && m_rawColors != 3))
      throw new UnknownImageTypeException("Unsuported Camera");

    RenderedImage result = null;

    File of = null;

    try {
      if (mode == dcrawMode.preview) {
        if (m_thumbWidth >= 1024 && m_thumbHeight >= 768) {
          mode = dcrawMode.thumb;
        }
      }

      long t1 = System.currentTimeMillis();

      of = File.createTempFile("LZRAWTMP", ".ppm");

      boolean four_colors = false;
      final String makeModel = m_make + ' ' + m_model;
      for (String s : four_color_cameras)
        if (s.equalsIgnoreCase(makeModel)) {
          four_colors = true;
          break;
        }

      if (secondaryPixels) runDCRawInfo(true);

      String cmd[];
      switch (mode) {
        case full:
          if (four_colors)
            cmd =
                new String[] {
                  DCRAW_PATH,
                  "-F",
                  of.getAbsolutePath(),
                  "-v",
                  "-f",
                  "-H",
                  "1",
                  "-t",
                  "0",
                  "-o",
                  "0",
                  "-4",
                  m_fileName
                };
          else if (m_filters == -1 || (m_make != null && m_make.equalsIgnoreCase("SIGMA")))
            cmd =
                new String[] {
                  DCRAW_PATH,
                  "-F",
                  of.getAbsolutePath(),
                  "-v",
                  "-H",
                  "1",
                  "-t",
                  "0",
                  "-o",
                  "0",
                  "-4",
                  m_fileName
                };
          else if (secondaryPixels)
            cmd =
                new String[] {
                  DCRAW_PATH,
                  "-F",
                  of.getAbsolutePath(),
                  "-v",
                  "-j",
                  "-H",
                  "1",
                  "-t",
                  "0",
                  "-s",
                  "1",
                  "-d",
                  "-4",
                  m_fileName
                };
          else
            cmd =
                new String[] {
                  DCRAW_PATH,
                  "-F",
                  of.getAbsolutePath(),
                  "-v",
                  "-j",
                  "-H",
                  "1",
                  "-t",
                  "0",
                  "-d",
                  "-4",
                  m_fileName
                };
          break;
        case preview:
          cmd =
              new String[] {
                DCRAW_PATH,
                "-F",
                of.getAbsolutePath(),
                "-v",
                "-t",
                "0",
                "-o",
                "1",
                "-w",
                "-h",
                m_fileName
              };
          break;
        case thumb:
          cmd = new String[] {DCRAW_PATH, "-F", of.getAbsolutePath(), "-v", "-e", m_fileName};
          break;
        default:
          throw new IllegalArgumentException("Unknown mode " + mode);
      }

      String ofName = null;

      synchronized (DCRaw.class) {
        Process p = null;
        InputStream dcrawStdErr;
        InputStream dcrawStdOut;
        if (ForkDaemon.INSTANCE != null) {
          ForkDaemon.INSTANCE.invoke(cmd);
          dcrawStdErr = ForkDaemon.INSTANCE.getStdErr();
          dcrawStdOut = ForkDaemon.INSTANCE.getStdOut();
        } else {
          p = Runtime.getRuntime().exec(cmd);
          dcrawStdErr = new BufferedInputStream(p.getErrorStream());
          dcrawStdOut = p.getInputStream();
        }

        String line, args;
        // output expected on stderr
        while ((line = readln(dcrawStdErr)) != null) {
          // System.out.println(line);

          if ((args = match(line, DCRAW_OUTPUT)) != null)
            ofName = args.substring(0, args.indexOf(" ..."));
        }

        // Flush stdout just in case...
        while ((line = readln(dcrawStdOut)) != null) ; // System.out.println(line);

        if (p != null) {
          dcrawStdErr.close();

          try {
            p.waitFor();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          m_error = p.exitValue();
          p.destroy();
        } else m_error = 0;
      }

      System.out.println("dcraw value: " + m_error);

      if (m_error > 0) {
        of.delete();
        throw new BadImageFileException(of);
      }

      if (!ofName.equals(of.getPath())) {
        of.delete();
        of = new File(ofName);
      }

      if (of.getName().endsWith(".jpg") || of.getName().endsWith(".tiff")) {
        if (of.getName().endsWith(".jpg")) {
          try {
            LCJPEGReader jpegReader = new LCJPEGReader(of.getPath());
            result = jpegReader.getImage();
          } catch (Exception e) {
            e.printStackTrace();
          }
        } else {
          try {
            LCTIFFReader tiffReader = new LCTIFFReader(of.getPath());
            result = tiffReader.getImage(null);
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
        long t2 = System.currentTimeMillis();

        int totalData =
            result.getWidth()
                * result.getHeight()
                * result.getColorModel().getNumColorComponents()
                * (result.getColorModel().getTransferType() == DataBuffer.TYPE_BYTE ? 1 : 2);

        System.out.println("Read " + totalData + " bytes in " + (t2 - t1) + "ms");
      } else {
        ImageData imageData;
        try {
          imageData = readPPM(of);
        } catch (Exception e) {
          e.printStackTrace();
          throw new BadImageFileException(of, e);
        }

        // do not change the initial image geometry
        // m_width = Math.min(m_width, imageData.width);
        // m_height = Math.min(m_height, imageData.height);

        long t2 = System.currentTimeMillis();

        int totalData =
            imageData.width
                * imageData.height
                * imageData.bands
                * (imageData.dataType == DataBuffer.TYPE_BYTE ? 1 : 2);

        System.out.println("Read " + totalData + " bytes in " + (t2 - t1) + "ms");

        final ColorModel cm;
        if (mode == dcrawMode.full) {
          if (imageData.bands == 1) {
            cm =
                new ComponentColorModel(
                    ColorSpace.getInstance(ColorSpace.CS_GRAY),
                    false,
                    false,
                    Transparency.OPAQUE,
                    DataBuffer.TYPE_USHORT);
          } else {
            cm = JAIContext.colorModel_linear16;
          }
        } else {
          if (imageData.bands == 3)
            cm =
                new ComponentColorModel(
                    JAIContext.sRGBColorSpace,
                    false,
                    false,
                    Transparency.OPAQUE,
                    DataBuffer.TYPE_BYTE);
          else if (imageData.bands == 4)
            cm =
                new ComponentColorModel(
                    JAIContext.CMYKColorSpace,
                    false,
                    false,
                    Transparency.OPAQUE,
                    imageData.dataType);
          else throw new UnknownImageTypeException("Weird number of bands: " + imageData.bands);
        }

        final DataBuffer buf =
            imageData.dataType == DataBuffer.TYPE_BYTE
                ? new DataBufferByte(
                    (byte[]) imageData.data, imageData.bands * imageData.width * imageData.height)
                : new DataBufferUShort(
                    (short[]) imageData.data, imageData.bands * imageData.width * imageData.height);

        final WritableRaster raster =
            Raster.createInterleavedRaster(
                buf,
                imageData.width,
                imageData.height,
                imageData.bands * imageData.width,
                imageData.bands,
                imageData.bands == 3 ? new int[] {0, 1, 2} : new int[] {0},
                null);

        result = new BufferedImage(cm, raster, false, null);
      }
    } catch (IOException e) {
      if (of != null) of.delete();
      throw e;
    } finally {
      if (of != null) of.delete();
    }
    return result;
  }
Пример #2
0
  public void decode() throws IOException {
    readTagDescriptors();

    final MessageDigest md;
    try {
      md = MessageDigest.getInstance("SHA-512");
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
      return;
    }

    final ComponentColorModel colorModel =
        new ComponentColorModel(
            ColorSpace.getInstance(ColorSpace.CS_sRGB),
            true,
            false,
            Transparency.TRANSLUCENT,
            DataBuffer.TYPE_BYTE);
    final int[] bandOffsets = {2, 1, 0, 3};
    final Map<String, String> duplicateGuard = new HashMap<String, String>();
    final byte[] bytes = data.array();
    final int[] tags = new int[8];

    final List<String> symLinkCommand = new ArrayList<String>(4);
    symLinkCommand.add("ln");
    symLinkCommand.add("-s");
    symLinkCommand.add(null);
    symLinkCommand.add(null);

    for (int fileIndex = 0; fileIndex < fileCount; fileIndex++) {
      data.position(fileDescriptorsOffset + ((4 + 8) * fileIndex));
      final int fileDataOffset = data.getInt();
      int numOfTags = 8;
      for (int i = 0; i < 8; i++) {
        int tag = data.get() & 0xff;
        if (tag == 0) {
          numOfTags = i;
          break;
        }
        tags[i] = tag;
      }

      data.position(fileDataSectionOffset + fileDataOffset);
      final int artRows = data.getShort();
      final int artColumns = data.getShort();
      // skip unknown
      data.position(data.position() + 28);

      final int[] subimageOffsets = readNumericArray(9, false);
      final int[] subimageWidths = readNumericArray(9, true);
      final int[] subimageHeights = readNumericArray(9, true);

      assert numOfTags >= 2;
      final File dir;
      final int tagStartIndexForFilename;
      if (numOfTags == 2) {
        tagStartIndexForFilename = 1;
        dir = new File(outputDir, names[tags[0]].toString());
      } else {
        tagStartIndexForFilename = 2;
        dir = new File(outputDir, names[tags[0]] + "/" + names[tags[1]]);
      }

      boolean dirCreated = false;

      final int imageCount = artRows * artColumns;
      for (int subImageIndex = 0; subImageIndex < imageCount; subImageIndex++) {
        final int w = subimageWidths[subImageIndex];
        final int h = subimageHeights[subImageIndex];
        if (w <= 0 || h <= 0) {
          continue;
        }

        final int srcPos = fileDataSectionOffset + fileDataOffset + subimageOffsets[subImageIndex];
        final int srcLength = w * h * 4;

        md.update(bytes, srcPos, srcLength);
        md.update((byte) w);
        md.update((byte) h);
        final String digest = convertToHex(md.digest());
        md.reset();

        if (!dirCreated) {
          //noinspection ResultOfMethodCallIgnored
          dir.mkdirs();
          dirCreated = true;
        }

        final byte[] bgra = new byte[srcLength];
        // cannot pass bytes directly, offset in DataBufferByte is not working
        System.arraycopy(bytes, srcPos, bgra, 0, bgra.length);
        BufferedImage image =
            new BufferedImage(
                colorModel,
                (WritableRaster)
                    Raster.createRaster(
                        new PixelInterleavedSampleModel(
                            DataBuffer.TYPE_BYTE, w, h, 4, w * 4, bandOffsets),
                        new DataBufferByte(bgra, bgra.length),
                        null),
                false,
                null);

        final StringBuilder outFilename =
            createOutpuFile(
                numOfTags, tags, tagStartIndexForFilename, imageCount > 0, subImageIndex);
        final String oldOutFilename = duplicateGuard.get(digest);
        if (oldOutFilename == null) {
          File file = new File(dir, outFilename.toString());
          duplicateGuard.put(digest, file.getPath());
          ImageIO.write(image, "png", file);
        } else {
          symLinkCommand.set(2, oldOutFilename);
          symLinkCommand.set(3, dir + "/" + outFilename);
          Process process = new ProcessBuilder(symLinkCommand).start();
          try {
            if (process.waitFor() != 0) {
              throw new IOException(
                  "Can't create symlink " + symLinkCommand.get(2) + " " + symLinkCommand.get(3));
            }
          } catch (InterruptedException e) {
            throw new IOException(e);
          }
        }
      }
    }
  }
Пример #3
0
  private void runDCRawInfo(boolean secondary) throws IOException {
    String info[] = {DCRAW_PATH, "-v", "-i", "-t", "0", m_fileName};
    String secondaryInfo[] = {DCRAW_PATH, "-v", "-i", "-s", "1", "-t", "0", m_fileName};

    synchronized (DCRaw.class) {
      Process p = null;
      InputStream dcrawStdOut;
      InputStream dcrawStdErr;
      if (ForkDaemon.INSTANCE != null) {
        ForkDaemon.INSTANCE.invoke(secondary ? secondaryInfo : info);
        dcrawStdOut = ForkDaemon.INSTANCE.getStdOut();
        dcrawStdErr = ForkDaemon.INSTANCE.getStdErr();
      } else {
        p = Runtime.getRuntime().exec(secondary ? secondaryInfo : info);
        dcrawStdOut = p.getInputStream();
        dcrawStdErr = new BufferedInputStream(p.getErrorStream());
      }

      // output expected on stdout
      String line, args;
      while ((line = readln(dcrawStdOut)) != null) {
        // System.out.println(line);

        String search;

        if (secondary) {
          if (line.startsWith(search = CAMERA_MULTIPLIERS)) {
            String multipliers[] = line.substring(search.length()).split("\\s");
            m_secondary_cam_mul[0] = Float.parseFloat(multipliers[0]);
            m_secondary_cam_mul[1] = Float.parseFloat(multipliers[1]);
            m_secondary_cam_mul[2] = Float.parseFloat(multipliers[2]);
            m_secondary_cam_mul[3] = Float.parseFloat(multipliers[3]);
          }
        } else {
          // if (line.startsWith(search = FILENAME)) {
          //     String filename = line.substring(search.length());
          // } else
          if (line.startsWith(search = TIMESTAMP)) {
            String timestamp = line.substring(search.length());
            try {
              m_captureDateTime = new SimpleDateFormat().parse(timestamp).getTime();
            } catch (ParseException e) {
              m_captureDateTime = 0;
            }
          } else if (line.startsWith(search = CAMERA)) {
            String camera = line.substring(search.length());
            m_make = camera.substring(0, camera.indexOf(' '));
            m_model = camera.substring(m_make.length() + 1);
          } else if (line.startsWith(search = ISO)) {
            String iso = line.substring(search.length());
            m_iso = Integer.decode(iso);
          } else if (line.startsWith(search = SHUTTER)) {
            String shutterSpeed = line.substring(search.length() + 2);
            float exposureTime = 0;
            try {
              exposureTime = Float.valueOf(shutterSpeed.substring(0, shutterSpeed.indexOf(" sec")));
              if (exposureTime != 0) m_shutterSpeed = 1 / exposureTime;
            } catch (NumberFormatException e) {
            }
          } else if (line.startsWith(search = APERTURE)) {
            String aperture = line.substring(search.length() + 2);
            try {
              m_aperture = Float.valueOf(aperture);
            } catch (NumberFormatException e) {
            }
          } else if (line.startsWith(search = FOCAL_LENGTH)) {
            String focalLenght = line.substring(search.length());
            try {
              m_focalLength = Float.valueOf(focalLenght.substring(0, focalLenght.indexOf(" mm")));
            } catch (NumberFormatException e) {
            }
            // } else if (line.startsWith(search = NUM_RAW_IMAGES)) {
            //     String numRawImages = line.substring(search.length());
            // } else if (line.startsWith(search = EMBEDDED_ICC_PROFILE)) {
            //     String embeddedICCProfile = line.substring(search.length());
          } else if (line.startsWith(CANNOT_DECODE)) {
            m_decodable = false;
          } else if ((args = match(line, THUMB_SIZE)) != null) {
            String sizes[] = args.split(" x ");
            m_thumbWidth = Integer.decode(sizes[0]);
            m_thumbHeight = Integer.decode(sizes[1]);
          } else if ((args = match(line, FULL_SIZE)) != null) {
            String sizes[] = args.split(" x ");
            m_fullWidth = Integer.decode(sizes[0]);
            m_fullHeight = Integer.decode(sizes[1]);
          } else if ((args = match(line, IMAGE_SIZE)) != null) {
            String sizes[] = args.split(" x ");
            m_rawWidth = Integer.decode(sizes[0]);
            m_rawHeight = Integer.decode(sizes[1]);
          } else if ((args = match(line, OUTPUT_SIZE)) != null) {
            String sizes[] = args.split(" x ");
            m_width = Integer.decode(sizes[0]);
            m_height = Integer.decode(sizes[1]);
          } else if (line.startsWith(search = RAW_COLORS)) {
            String rawColors = line.substring(search.length());
            m_rawColors = Integer.decode(rawColors);
          } else if (line.startsWith(search = FILTER_PATTERN)) {
            String pattern = line.substring(search.length());
            if (pattern.length() >= 8 && !pattern.substring(0, 4).equals(pattern.substring(4, 8)))
              m_filters = -1;
            else if (pattern.startsWith("BGGR")) m_filters = 0x16161616;
            else if (pattern.startsWith("GRBG")) m_filters = 0x61616161;
            else if (pattern.startsWith("GBRG")) m_filters = 0x49494949;
            else if (pattern.startsWith("RGGB")) m_filters = 0x94949494;
            else m_filters = -1;
          } else if (line.startsWith(search = DAYLIGHT_MULTIPLIERS)) {
            String multipliers[] = line.substring(search.length()).split("\\s");
            m_pre_mul[0] = Float.parseFloat(multipliers[0]);
            m_pre_mul[1] = Float.parseFloat(multipliers[1]);
            m_pre_mul[2] = Float.parseFloat(multipliers[2]);
            m_pre_mul[3] = m_pre_mul[1];
          } else if (line.startsWith(search = CAMERA_MULTIPLIERS)) {
            String multipliers[] = line.substring(search.length()).split("\\s");
            m_cam_mul[0] = Float.parseFloat(multipliers[0]);
            m_cam_mul[1] = Float.parseFloat(multipliers[1]);
            m_cam_mul[2] = Float.parseFloat(multipliers[2]);
            m_cam_mul[3] = Float.parseFloat(multipliers[3]);
          } else if (line.startsWith(CAMERA_RGB_PROFILE)) {
            String rgb_cam[] = line.substring(CAMERA_RGB_PROFILE.length()).split("\\s");
            m_rgb_cam = new float[9];
            for (int i = 0; i < 9; i++) {
              m_rgb_cam[i] = Float.parseFloat(rgb_cam[i]);
            }
          } else if (line.startsWith(CAMERA_XYZ_PROFILE)) {
            String xyz_cam[] = line.substring(CAMERA_XYZ_PROFILE.length()).split("\\s");
            m_xyz_cam = new float[9];
            for (int i = 0; i < 9; i++) {
              m_xyz_cam[i] = Float.parseFloat(xyz_cam[i]);
            }
          }
        }
      }

      // Flush stderr just in case...
      while ((line = readln(dcrawStdErr)) != null) ; // System.out.println(line);

      if (p != null) {
        dcrawStdOut.close();
        try {
          p.waitFor();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        m_error = p.exitValue();
        p.destroy();
      } else m_error = 0;
    }
  }