Menu

Convert Operation Hangs on Specific Image

Help
2017-09-21
2017-09-21
  • Eric Manzitti

    Eric Manzitti - 2017-09-21

    Hello. I have an instance where a specific image file is causing the convert.exe to hang. However when I run the same command through either the command line in Windows, or through a runtime execution inside java, the operation complets successfully.

    The below code should indicate, I hope, that I am performing the same operation (in a local environment) between the im4java interface and the command line.

    Super weird. I've tried an assortment of different commands in im4java, nothing seems to matter. Even just tried to 'resave' it.

    Speaking of resaving. Whenever I modify the image in anyway, even a simple resaving, it then clears up whatever is wrong with the image and the im4java interface deals with it just fine.

    Can anyone reproduce the hanging below? We first found this to be happening in our prod environment on a linux box.

    Anyone happen to know or have an idea how I could try to detect the problem aspect(s) of this image before I send it to image magik through im4java? That way we dont have hanging threads out there?

                boolean runImageTest = true; 
                String domainName = "google.com";
                String command = "C:\\Program Files\\ImageMagick-7.0.5-Q16\\convert.exe C:\\WorkStuff\\badOriginal.jpeg -quality 40 C:\\WorkStuff\\fixedOriginal1.jpg";
                StringBuffer output = new StringBuffer();
                Process p;
                try {
                    p = Runtime.getRuntime().exec(command);
                    p.waitFor();
                    BufferedReader reader =
                                    new BufferedReader(new InputStreamReader(p.getInputStream()));
    
                                String line = "";
                    while ((line = reader.readLine())!= null) {
                        output.append(line + "\n");
                    }
    
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println(output.toString());
    
                if (runImageTest) {
                    System.out.println("We're going to do some custom arguments");
                    String myCommand = "quality";
                    String incomingFile = "C:\\WorkStuff\\badOriginal.jpg";
                    String outgoingFile = "C:\\WorkStuff\\fixedOriginal11.jpg";
                    String mimeType = "image/jpg";
                    double qualityValue = 05;
                    String stylePath = "C:\\WorkStuff\\HMS.test.scales.csv";
                    String enginePath = "C:\\Program Files\\ImageMagick-7.0.5-Q16";
                    String style = "WIDTH";
    
                    InputStream inputStream = null;
                    CreatedFilesList imageReturnObject = null;
                    OutputStream outputStream = null;
                    try {
                        inputStream = new FileInputStream(incomingFile);
                        outputStream = new FileOutputStream(outgoingFile);
                        IMOperation imOperation = new IMOperation();
                        //imOperation.list("debug");
                        imOperation.addImage(FilenameUtils.getExtension(incomingFile) + ":-");              
                        imOperation.quality(qualityValue);              
                        imOperation.addImage(FilenameUtils.getExtension(outgoingFile) + ":-");
    
                        Pipe pipeIn = new Pipe(inputStream, null);
                        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                        Pipe pipeOut = new Pipe(null, byteArrayOutputStream);
                        ConvertCmd convertCmd = new ConvertCmd();
                        convertCmd.setInputProvider(pipeIn);
                        convertCmd.setOutputConsumer(pipeOut);
                        convertCmd.setSearchPath(enginePath);
                        System.out.println("We are about to start the operation");
                        convertCmd.run(imOperation);
                        outputStream.write(byteArrayOutputStream.toByteArray());
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        outputStream.close();
                        inputStream.close();
                    }
                    System.out.println("Holy Moly we made it through"); 
                }
    
     
  • Eric Manzitti

    Eric Manzitti - 2017-09-21

    Oh sorry, here is the image file in question.

    And a link to it:

    https://drive.google.com/open?id=0B-9pALoPVAUeMmU1RWdpdVJvdkE

    EDIT :: THE ATTACHMENT WILL NOT WORK FOR THE EXAMPLE. It downloads much smaller than the original file, and falls into the "resaved" category and thus works inside im4java.

    I downloaded the image from the link above however and that did cause the hanging still

     

    Last edit: Eric Manzitti 2017-09-21
  • Eric Manzitti

    Eric Manzitti - 2017-09-21

    So I am continuing to dig deeper, decided to use the Info Object to investigate the bad image, and a good image (copy of bad)'s differences.

    String incomingFileBad = "C:\\WorkStuff\\badOriginal444.jpeg";
    String incomingFileGood = "C:\\WorkStuff\\badRandomProp.jpeg";
    String mimeType = "image/jpg";
    String enginePath = "C:\\Program Files\\ImageMagick-7.0.5-Q16";
    Info imageInfoBad = null;
    Info imageInfoGood = null;
    try {
        imageInfoBad = new Info (incomingFileBad);
        imageInfoGood = new Info (incomingFileGood);            
    } catch (InfoException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    if (imageInfoBad != null) {
        List<String> listOfDiffs = new ArrayList<String>();
        boolean found = false;
        Enumeration<String> badNames = imageInfoBad.getPropertyNames();
        int badNamesCounter = 0, goodNamesCounter =0;
        while (badNames.hasMoreElements()){
            String badFileProperty = badNames.nextElement();
            goodNamesCounter =0;
            badNamesCounter++;
            Enumeration<String> goodNames = imageInfoGood.getPropertyNames();
            while (goodNames.hasMoreElements()){                            
                String goodFileProperty = goodNames.nextElement();
                goodNamesCounter++;
                if (goodFileProperty.equals(badFileProperty)) {
                    found = true;                               
                }
                }
        if (!found) {
                listOfDiffs.add(badFileProperty);                           
        }
        found = false;                      
    }
    
    System.out.println("There were " + badNamesCounter + " bad image properties");
    System.out.println("There were " + goodNamesCounter + " good image properties");
    System.out.println(listOfDiffs.size() + " differences in good/bad properties");
    if (listOfDiffs.size() > 0) {
        for(String entry : listOfDiffs) {
            System.out.println("Differing Property: " + entry);
        }
    } else {
        System.out.println("No differing properties...");
    }
    }                               
    

    That produces the following output:

     We're going to get the image info.  For two images.
    Pause
    
    There were 151 bad image properties
    There were 155 good image properties
    There were 1 differences in good/bad properties
    
    Differing Property: Properties:exif:Artist:exif:Copyright:exif:Flash
    

    Now the difference betweent he two images is one is the bad image and one is that same image simply resaved (meaning It'll work)

    So digging deeper here, it looks like perhaps that property causing image magik to get mad...

     

    Last edit: Eric Manzitti 2017-09-21
  • Bernhard Bablok

    Bernhard Bablok - 2017-09-22

    Hi Eric,

    this is indeed strange. My first try would be to add an error-consumer. This might be the cause of the hang if the internal buffer for the stderr is not cleared. The output might also give some additional insights. This does not deal with the root-cause of course.

    Bernhard

     
  • Eric Manzitti

    Eric Manzitti - 2017-09-22

    Hi Bernard,

    Thanks for the quick reply.

    So we kept digging deeper and a coworker found that if she did the following, it worked.

                    ConvertCmd cmd = new ConvertCmd();
                    String enginePath = "C:\\Program Files\\ImageMagick-7.0.5-Q16";
                    // create the operation, add images and operators/options
                    IMOperation op = new IMOperation();
                    op.addImage("C:\\WorkStuff\\badOriginal.jpeg");
                    op.resize(800,600);
                    op.addImage("C:\\WorkStuff\\fixedHappy2.jpg");
                    // execute the operation
                    cmd.setSearchPath(enginePath);
                    cmd.run(op);
    

    Moving one step at a time towards the broken code. We found it was the pipeIn that caused the problem.

    Bernie (lol, hehe) ~ I think I'll go ahead and perhaps try to dig into that errorConsumer. I can't let that become production code, but if it'll help the open source, I'll dig into it and try to get you some more info.

    As currently our solution is to modify the code to not use the pipe input. We don't seem to have a use case for why the Pipe object was used and so long as it tests fine without using the pipe, we're going that route.

    <3 im4java and thanks for the reply.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.