def probeVideo(self, filename=None):
        """
        Probes a video file.
        Caveat: Supports only 1 video channel and 1 audio chanel
        @param: file Video file to probe
        @return Dictionary. Key "video" contains dictionary of VideoStream objects and key "audio" contains a dictionary of AudioStream objects
        """
        loggerJobCreationRuntime.info("================================================================================")
        loggerJobCreationRuntime.info("Processing :" + str(filename))
        # Prepare CL
        ffprobeCLBuilder = FFPROBECLGenerator()
        ffprobeCLBuilder.addInputFile(util.escapePathForOSIndependentShell(filename))
        ffprobeCLBuilder.addShowStreams()
        cl = ffprobeCLBuilder.tocl()
        loggerJobCreationRuntime.info("ffprobe cl:" + str(cl))

        # Run CL
        # clRunner = CLRunner(stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        clRunner = CLRunner(shell=True)
        clRunner.run(cl)
        ffprobeRawOutput = clRunner.stdout()
        loggerJobCreationRuntime.info("ffprobe raw output:" + str(ffprobeRawOutput))
        # Parse CL output
        ffprobeParser = FFprobeParser()
        streams = ffprobeParser.parseShowStreamsOuput(ffprobeRawOutput)

        # Second pass: Build media instances
        countStreams = len(streams)
        mediaStreams = list()
        if countStreams > 0:
            for i in range(0, countStreams, 1):
                stream = streams[i]
                mediaStream = None
                if stream["codec_type"] in "video":
                    mediaStream = ApertureConverterPlugin.createVideoStream(d=stream)
                    mediaStreams.append(mediaStream)
                elif stream["codec_type"] in "audio":
                    mediaStream = ApertureConverterPlugin.createAudioStream(d=stream)
                    mediaStreams.append(mediaStream)

        streamsMediaObjects = dict(video=dict(), audio=dict())
        for i in range(0, len(mediaStreams)):
            mediaStream = mediaStreams[i]
            streams = None
            if mediaStream.getType() in "video":
                streams = (streamsMediaObjects["video"])
            elif mediaStream.getType() in "audio":
                streams = (streamsMediaObjects["audio"])
            streams[mediaStream.getStreamIndex()] = mediaStream
        loggerJobCreationRuntime.info("ffprobe converted output:" + str(streamsMediaObjects))
        return streamsMediaObjects
    def createVideoJob(self, sourceMediaFile=None):
        """
        Creates a job to convert a video file to my own storage requirements
        @param sourceMediaFile Source MediaFile object
        @return Job instance to convert the video
        """
        sourceVideoMediaStreams = sourceMediaFile.getVideoStreams()
        sourceAudioMediaStreams = sourceMediaFile.getAudioStreams()
        masterJob = None
        hanbrakeSourceMediaFile = copy.deepcopy(sourceMediaFile)
        hanbrakeDestinationMediaFile = MediaFile()
        ffmpegSourceMediaFile = MediaFile()
        ffmpegDestinationMediaFile = MediaFile()
        destinationHandbrakeVideoStreams = list()
        destinationHandbrakeAudioStreams = list()
        destinationHandbrakeVideoStream = None
        destinationHandbrakeAudioStream = None

        destinationFFMPEGVideoStreams = list()
        destinationFFMPEGAudioStreams = list()
        destinationFFMPEGVideoStream = None
        destinationFFMPEGAudioStream = None

        # Source video attributes
        sVWidth = None
        sVHeight = None
        sVCodecName = None
        sVCodecTag = None
        sVFramerateMin = None
        # Source audio attributes
        sACodecName = None
        sACodecTag = None
        sABitPerSample = None

        # Handbrake Destination video attributes
        dVHandbrakeCodecName = None
        dVHandbrakeStreamIndex = None
        dVHandbrakeWidth = None
        dVHandbrakeHeight = None
        dVHandbrakeQuality = None
        # Handbrake  Destination audio attributes
        dAHandbrakeStreamIndex = None
        dAHandbrakeSampleRate = None
        dAHandbrakeCodecName = None

        # FFMPEG Destination video attributes
        dVFFMPEGCodecName = None
        # FFMPEG  Destination audio attributes
        dAFFMPEGCodecName = None

        countSourceVideoStreams = len(sourceVideoMediaStreams)
        if countSourceVideoStreams == 1:
            vmsKey = sourceVideoMediaStreams.keys()[0]
            vms = sourceVideoMediaStreams[vmsKey]

            sVWidth = vms.getWidth()
            sVHeight = vms.getHeight()
            sVCodecName = vms.getCodecName()
            sVCodecTag = vms.getCodecTag()
            sVFramerateMin = vms.getFramerateMin()
            sACodecName = None
            sACodecTag = None
            sABitPerSample = None
            dVHandbrakeWidth = sVWidth
            dVHandbrakeHeight = sVHeight

            loggerCameraSourceType = "Not identified"
            skippedJobCreation = True
            skippedReason = ""

            countSourceAudioStreams = len(sourceAudioMediaStreams)
            if countSourceVideoStreams == 1:
                amsKey = sourceAudioMediaStreams.keys()[0]
                ams = sourceAudioMediaStreams[amsKey]
                sACodecName = ams.getCodecName()
                sACodecTag = ams.getCodecTag()
                sABitPerSample = ams.getBitPerSample()
                dAHandbrakeStreamIndex = "1"
                dAHandbrakeSampleRate = ams.getSampleRate()
            else:
                logger.warn("NOTE:" +
                            sourceMediaFile.getFileName() +
                            ": " +
                            str(countSourceVideoStreams) +
                            " audio stream found.")

            # Select appropriate destination media file convertion settings
            # Nikon D3100
            if(sVWidth >= 1280 and sVHeight >= 720 and
                sVCodecName == "h264" and sVCodecTag == "0x31637661" and
                sACodecName == "pcm_s16le" and sACodecTag == "0x74776f73" and
                sABitPerSample == "16"):
                evfH264 = HandbrakeCLGenerator.ENCODER_VIDEO_FORMAT_H264
                dVHandbrakeCodecName = evfH264
                dVHandbrakeStreamIndex = "0"
                dVHandbrakeQuality = "25"
                dVHandbrakeWidth = 1280
                dVHandbrakeHeight = 720
                eafFAAC = HandbrakeCLGenerator.ENCODER_AUDIO_FORMAT_FAAC
                dAHandbrakeCodecName = eafFAAC
                cfMP4 = HandbrakeCLGenerator.CONTAINER_FORMAT_MP4
                hanbrakeDestinationMediaFile.setContainerType(cfMP4)

                dVFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_VIDEO_FORMAT_COPY
                dAFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_AUDIO_FORMAT_COPY

                loggerCameraSourceType = "Nikon D3100"
                skippedJobCreation = False

            # GoPro Silver 3+ 
            elif(sVCodecName == "h264" and sVCodecTag == "0x31637661" and
                sACodecName == "aac" and sACodecTag == "0x6134706d"):
                evfH264 = HandbrakeCLGenerator.ENCODER_VIDEO_FORMAT_H264
                dVHandbrakeCodecName = evfH264
                dVHandbrakeStreamIndex = "0"
                dVHandbrakeQuality = "23"

		eafFAAC = HandbrakeCLGenerator.ENCODER_AUDIO_FORMAT_FAAC
                dAHandbrakeCodecName = eafFAAC

                cfMP4 = HandbrakeCLGenerator.CONTAINER_FORMAT_MP4
                hanbrakeDestinationMediaFile.setContainerType(cfMP4)

                dVFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_VIDEO_FORMAT_COPY
                dAFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_AUDIO_FORMAT_COPY

                loggerCameraSourceType = "GoPro 3+ Silver"
                skippedJobCreation = False

 
            # Canon Nexus 700
            elif(sVWidth == 320 and sVHeight == 240 and
                sVCodecName == "mjpeg" and sVCodecTag == "0x47504a4d" and
                sACodecName == "pcm_u8" and sACodecTag == "0x0001" and
                sABitPerSample == "8"):
                evfH264 = HandbrakeCLGenerator.ENCODER_VIDEO_FORMAT_H264
                dVHandbrakeCodecName = evfH264
                dVHandbrakeStreamIndex = "0"
                dVHandbrakeQuality = "25"
                cfMP4 = HandbrakeCLGenerator.CONTAINER_FORMAT_MP4
                hanbrakeDestinationMediaFile.setContainerType(cfMP4)

                dVFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_VIDEO_FORMAT_COPY
                dAFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_AUDIO_FORMAT_COPY

                loggerCameraSourceType = "Canon Nexus 700"
                skippedJobCreation = False

            # iPhone 3GS (NOT MBP 2007 iSight)
            elif(((sVWidth == 640 and sVHeight == 480) or (sVWidth == 480 and sVHeight == 360)) and
                 sVCodecName == "h264" and sVCodecTag == "0x31637661" and
                 sACodecName == "aac" and sACodecTag == "0x6134706d" and
                 sABitPerSample == "0"):
                evfH264 = HandbrakeCLGenerator.ENCODER_VIDEO_FORMAT_H264
                dVHandbrakeCodecName = evfH264
                dVHandbrakeStreamIndex = "0"
                dVHandbrakeQuality = "30"
                eafFAAC = HandbrakeCLGenerator.ENCODER_AUDIO_FORMAT_FAAC
                dAHandbrakeCodecName = eafFAAC
                # quality=25 best quality=35 worst
                cfMP4 = HandbrakeCLGenerator.CONTAINER_FORMAT_MP4
                hanbrakeDestinationMediaFile.setContainerType(cfMP4)

                dVFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_VIDEO_FORMAT_COPY
                dAFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_AUDIO_FORMAT_COPY

                loggerCameraSourceType = "iPhone 3GS"
                skippedJobCreation = False

            # MBP 2010 iSight
            elif(sVWidth == 320 and sVHeight == 240 and
                 sVCodecName == "mjpeg" and sVCodecTag == "" and
                 sACodecName == "pcm_u8" and sACodecTag == "" and
                 sABitPerSample == "8"):
                evfH264 = HandbrakeCLGenerator.ENCODER_VIDEO_FORMAT_H264
                dVHandbrakeCodecName = evfH264
                dVHandbrakeStreamIndex = "0"
                dVHandbrakeQuality = "25"
                eafFAAC = HandbrakeCLGenerator.ENCODER_AUDIO_FORMAT_FAAC
                dAHandbrakeCodecName = eafFAAC
                cfMP4 = HandbrakeCLGenerator.CONTAINER_FORMAT_MP4
                hanbrakeDestinationMediaFile.setContainerType(cfMP4)

                dVFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_VIDEO_FORMAT_COPY
                dAFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_AUDIO_FORMAT_COPY

                loggerCameraSourceType = "Macbook Pro iSight 2010"
                skippedJobCreation = False

            # Unknown
            elif(sVWidth == 640 and sVHeight == 480 and
                 sVCodecName == "mjpeg" and sVCodecTag == "" and
                 sACodecName == "pcm_mulaw" and sACodecTag == "" and
                 sABitPerSample == "8"):
                evfH264 = HandbrakeCLGenerator.ENCODER_VIDEO_FORMAT_H264
                dVHandbrakeCodecName = evfH264
                dVHandbrakeStreamIndex = "0"
                dVHandbrakeQuality = "25"
                eafFAAC = HandbrakeCLGenerator.ENCODER_AUDIO_FORMAT_FAAC
                dAHandbrakeCodecName = eafFAAC
                cfMP4 = HandbrakeCLGenerator.CONTAINER_FORMAT_MP4
                hanbrakeDestinationMediaFile.setContainerType(cfMP4)

                dVFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_VIDEO_FORMAT_COPY
                dAFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_AUDIO_FORMAT_COPY

                loggerCameraSourceType = "Unknown0"
                skippedJobCreation = False

            # Panasonic DMC FX-36
            elif(sVWidth == 640 and sVHeight == 480 and
                 sVCodecName == "mjpeg" and sVCodecTag == "0x6765706a" and
                 sACodecName == "pcm_u8" and sACodecTag == "0x20776172" and
                 sABitPerSample == "8"):
                evfH264 = HandbrakeCLGenerator.ENCODER_VIDEO_FORMAT_H264
                dVHandbrakeCodecName = evfH264
                dVHandbrakeStreamIndex = "0"
                dVHandbrakeQuality = "27"
                eafFAAC = HandbrakeCLGenerator.ENCODER_AUDIO_FORMAT_FAAC
                dAHandbrakeCodecName = eafFAAC
                # quality=25 best quality=35 worst
                cfMP4 = HandbrakeCLGenerator.CONTAINER_FORMAT_MP4
                hanbrakeDestinationMediaFile.setContainerType(cfMP4)

                dVFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_VIDEO_FORMAT_COPY
                dAFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_AUDIO_FORMAT_COPY

                loggerCameraSourceType = "Panasonic DMC FX-36"
                skippedJobCreation = False
            # Unknown 1
            elif(sVCodecName == None and sVCodecTag == None and
                 sACodecName == "aac" and sACodecTag == "0x6134706d" and
                 sABitPerSample == "0"):
                # No need to re-encode
                skippedJobCreation = True
                skippedReason = "No need to re-encode"
            else:
                skippedJobCreation = True
                skippedReason = ("No suitable converter configuration found. "
                                + "Missing a convertion case ? "
                                + "New video file ?" )

            if not skippedJobCreation:
                try:
                    masterJob = OnSuccessOnlyConverterJob()
                    # Convert with HandBrake as Job #1
                    hanbrakeSourceMediaFile.setFileName(util.escapePathForOSIndependentShell(hanbrakeSourceMediaFile.getFileName()))
                    destinationHandbrakeVideoStream = VideoStream(codecName=dVHandbrakeCodecName,
                                                                  streamIndex=dVHandbrakeStreamIndex,
                                                                  framerateMin=sVFramerateMin,
                                                                  width=dVHandbrakeWidth,
                                                                  height=dVHandbrakeHeight,
                                                                  quality=dVHandbrakeQuality)
                    destinationHandbrakeAudioStream = AudioStream(streamIndex=dAHandbrakeStreamIndex,
                                                                  sampleRate=dAHandbrakeSampleRate,
                                                                  codecName=dAHandbrakeCodecName)
                    destinationHandbrakeVideoStreams.append(destinationHandbrakeVideoStream)
                    destinationHandbrakeAudioStreams.append(destinationHandbrakeAudioStream)
                    hanbrakeDestinationMediaFile.setVideoStreams(destinationHandbrakeVideoStreams)
                    hanbrakeDestinationMediaFile.setAudioStreams(destinationHandbrakeAudioStreams)
                    handbrakeDestinationFileName = sourceMediaFile.getFileName() + ".tmp." + str(hanbrakeDestinationMediaFile.getContainerType())
                    hanbrakeDestinationMediaFile.setFileName(util.escapePathForOSIndependentShell(handbrakeDestinationFileName))
                    handbrakeCLIBuilder = HandbrakeCLGenerator.createFrom(sourceMediaFile=hanbrakeSourceMediaFile, destinationMediaFile=hanbrakeDestinationMediaFile)
                    handbrakeCLIBuilder.addLooseAnamorphic()
                    handbrakeCLIBuilder.addVerbosity()
                    handbrakeCLIRunner = CLRunner(shell=True)

                    masterJob.addJob(ConverterJob(clibuilder=handbrakeCLIBuilder, clirunner=handbrakeCLIRunner))
                    loggerJobCreationRuntime.info("Handbrake cl:" + str(handbrakeCLIBuilder.tocl()))

                    # Convert with FFMpeg as Job #2
                    destinationFFMPEGVideoStream = VideoStream(codecName=dVFFMPEGCodecName)
                    destinationFFMPEGAudioStream = AudioStream(codecName=dAFFMPEGCodecName)

                    ffmpegSourceMediaFile.setFileName(hanbrakeDestinationMediaFile.getFileName())
                    ffmpegDestinationMediaFile.setFileName(util.escapePathForOSIndependentShell(sourceMediaFile.getFileName()))
                    destinationFFMPEGVideoStreams.append(destinationFFMPEGVideoStream)
                    destinationFFMPEGAudioStreams.append(destinationFFMPEGAudioStream)
                    ffmpegDestinationMediaFile.setVideoStreams(destinationFFMPEGVideoStreams)
                    ffmpegDestinationMediaFile.setAudioStreams(destinationFFMPEGAudioStreams)
                    ffmpegCLIBuilder = FFMPEGCLGenerator.createFrom(sourceMediaFile=ffmpegSourceMediaFile, destinationMediaFile=ffmpegDestinationMediaFile)
                    ffmpegCLIBuilder.addOverwriteOutputFileWithoutAsking()
                    ffmpegCLIRunner = CLRunner(shell=True)
                    loggerJobCreationRuntime.info("ffmpeg cl:" + str(ffmpegCLIBuilder.tocl()))

                    masterJob.addJob(ConverterJob(clibuilder=ffmpegCLIBuilder, clirunner=ffmpegCLIRunner))
                    # Delete temporary file as Job #3
                    masterJob.addJob(DeleteFileJob(filename=handbrakeDestinationFileName))
                    loggerJobCreationRuntime.info("Will delete file:" + str(handbrakeDestinationFileName))
                    loggerJobCreationSuccess.info("JOB_CREATION_SUCCESS:" + sourceMediaFile.getFileName() + ": Type:" + loggerCameraSourceType)
                except BaseException:
                    loggerJobCreationFailed.exception("JOB_CREATION_FAILED:" + sourceMediaFile.getFileName() + ": Type:" + loggerCameraSourceType + "Exception :")
            else:
                loggerJobCreationSkipped.info("JOB_CREATION_SKIPPED:" +
                                              sourceMediaFile.getFileName() +
                                              ": Type:" + loggerCameraSourceType +
                                              " Reason: " + skippedReason)
        else:
            loggerJobCreationFailed.error("JOB_CREATION_FAILED:" + sourceMediaFile.getFileName() + ": Reason: 1 video stream expected. " + str(countSourceVideoStreams) + " found.")

        if not masterJob:
            masterJob = Job()  # Created only if proper convert job not created
        return masterJob
    def createImageJob(self, sourceMediaFile=None):
        """
        Creates a job to convert image file to my own storage requirements
        @param sourceMediaFile Source MediaFile object
        @return Job instance to convert the image
        """
        sourceImageStreams = sourceMediaFile.getImageStreams()
        masterJob = None
        backupDestinationMediaFile = MediaFile()
        convertDestinationMediaFile = MediaFile()
        destinationBakupImageStreams = list()
        destinationConvertImageStreams = list()

        # Source video attributes
        sIWidth = None
        sIHeight = None
        sIDPIX = None
        sIDPIY = None
        sIQuality = None

        # Handbrake Destination video attributes
        dIWidth = None
        dIHeight = None
        dIDPIX = None
        dIDPIY = None
        dIQuality = None

        countSourceImageStreams = len(sourceImageStreams)
        if countSourceImageStreams == 1:
            imsKey = sourceImageStreams.keys()[0]
            ims = sourceImageStreams[imsKey]

            sIWidth = ims.getWidth()
            sIHeight = ims.getHeight()
            sIDPIX = ims.getDensityX()[0]
            sIDPIY = ims.getDensityY()[0]
            sIQuality = ims.getQuality()
            loggerCameraSourceType = "Not identified"
            skippedJobCreation = True
            skippedReason = ""

            sIQuotientHeightWidth = float(float(sIHeight)/float(sIWidth))

            # Select appropriate destination media file convertion settings
            # Unknown1
            if(sIDPIX == 300 and sIDPIY == 300 and
               sIWidth >= 3508 and sIHeight >= 2480):
                if sIQuotientHeightWidth >= 1.0:
                    sIHeight=3508
                else:
                    dIWidth=2480
                dIQuality=95
                loggerCameraSourceType = "Unknown1"
                skippedJobCreation = False
            # GoPro 3+ Silver - 10MP Wide Mode
            elif(sIDPIX == 72 and sIDPIY == 72 and
               sIWidth == 3680 and sIHeight == 2760):
                dIQuality=92
                loggerCameraSourceType = "GoPro 3+ Silver - 10MP Wide Mode"
                skippedJobCreation = False
            # Unknown2
            elif((sIWidth <= 2480 and sIHeight <= 3508) or
                (sIDPIX <=300 and sIDPIY <=300)):
                # No need to re-encode
                skippedJobCreation = True
                skippedReason = "No need to re-encode"
            else:
                skippedJobCreation = True
                skippedReason = "No suitable converter configuration found. Missing a convertion case ? New image file ?"

            if not skippedJobCreation:
                try:
                    masterJob = OnSuccessOnlyConverterJob()
                    # Backup file as Job #1
                    sourceBackupFileName = sourceMediaFile.getFileName()
                    destinationBackupFileName = str(sourceBackupFileName) + ".backup"
                    destinationBackupMediaFile = MediaFile()
                    destinationBackupMediaFile.setFileName(destinationBackupFileName)
                    copyFileJob = CopyFileJob(sourceFileName=sourceMediaFile.getFileName(), destinationFileName=destinationBackupMediaFile.getFileName())
                    masterJob.addJob(copyFileJob)
                    loggerJobCreationRuntime.info("Will backup file: " + str(sourceBackupFileName) + " to " + str(destinationBackupFileName))

                    # Convert with ImageMagick's mogrity tool as Job #2
                    convertSourceMediaFile = MediaFile()
                    convertSourceMediaFile.setFileName(util.escapePathForOSIndependentShell(destinationBackupFileName))
                    convertDestinationFileName = sourceMediaFile.getFileName()
                    convertDestinationMediaFile.setFileName(util.escapePathForOSIndependentShell(convertDestinationFileName))
                    destinationConvertImageStream = ImageStream(filename=convertDestinationFileName, width=dIWidth, height=sIHeight, quality=dIQuality, densityX=dIDPIX, densityY=dIDPIY)
                    destinationConvertImageStreams.append(destinationConvertImageStream)
                    convertDestinationMediaFile.setImageStreams(destinationConvertImageStreams)
                    convertCLIBuilder = ConvertCLGenerator.createResizeJobFrom(sourceMediaFile=convertSourceMediaFile, destinationMediaFile=convertDestinationMediaFile)
                    convertCLIRunner = CLRunner(shell=True)

                    masterJob.addJob(ConverterJob(clibuilder=convertCLIBuilder, clirunner=convertCLIRunner))
                    loggerJobCreationRuntime.info("convert cl:" + str(convertCLIBuilder.tocl()))

                    # Delete backup file as Job #3
                    masterJob.addJob(DeleteFileJob(filename=destinationBackupMediaFile.getFileName()))
                    loggerJobCreationRuntime.info("Will delete file:" + str(destinationBackupMediaFile.getFileName()))
                    loggerJobCreationSuccess.info("JOB_CREATION_SUCCESS:" + sourceMediaFile.getFileName() + ": Type:" + loggerCameraSourceType)
                except BaseException:
                    loggerJobCreationFailed.exception("JOB_CREATION_FAILED:" + sourceMediaFile.getFileName() + ": Type:" + loggerCameraSourceType + "Exception :")
            else:
                loggerJobCreationSkipped.info("JOB_CREATION_SKIPPED:" +
                                              sourceMediaFile.getFileName() +
                                              ": Type:" + loggerCameraSourceType
                                              + " Reason: " +skippedReason)			
        else:
            loggerJobCreationFailed.error("JOB_CREATION_FAILED:" + sourceMediaFile.getFileName() + ": Reason: 1 video stream expected. " + str(countSourceVideoStreams) + " found.")

        if not masterJob:
            masterJob = Job()  # Created only if proper convert job not created 
        return masterJob
    def probeImage(self, filename=None):
            """
            Probes an image file
            @param: file Image file to probe
            @return Dictionary. Key "image" contains dictionary of ImageStream objects
            """
            loggerJobCreationRuntime.info("================================================================================")
            loggerJobCreationRuntime.info("Processing :" + str(filename))

            # Get Image width
            identifyCLBuilder0 = IdentifyCLGenerator()
            identifyCLBuilder0.addInputFile(util.escapePathForOSIndependentShell(filename))
            identifyCLBuilder0.addFormatOption()
            identifyCLBuilder0.addFormatWidthOption()
            cl0 = identifyCLBuilder0.tocl()
            loggerJobCreationRuntime.info("identify cl:" + str(cl0))

            clRunner0 = CLRunner(shell=True)
            clRunner0.run(cl0)
            identifyCLRawOutput0 = clRunner0.stdout()

            identifyParser0 = IdentifyParser()
            width = identifyParser0.parseFormatWidthOption(identifyCLRawOutput0)

            # Get Image height
            identifyCLBuilder1 = IdentifyCLGenerator()
            identifyCLBuilder1.addInputFile(util.escapePathForOSIndependentShell(filename))
            identifyCLBuilder1.addFormatOption()
            identifyCLBuilder1.addFormatHeightOption()
            cl1=identifyCLBuilder1.tocl()
            loggerJobCreationRuntime.info("identify cl:" + str(cl1))

            clRunner1=CLRunner(shell=True)
            clRunner1.run(cl1)
            identifyCLRawOutput1=clRunner1.stdout()

            identifyParser1 = IdentifyParser()
            height = identifyParser1.parseFormatHeightOption(identifyCLRawOutput1)

            # Get Image DPI X
            identifyCLBuilder2 = IdentifyCLGenerator()
            identifyCLBuilder2.addInputFile(util.escapePathForOSIndependentShell(filename))
            identifyCLBuilder2.addFormatOption()
            identifyCLBuilder2.addFormatHorizontalDPIOption()
            cl2=identifyCLBuilder2.tocl()
            loggerJobCreationRuntime.info("identify cl:" + str(cl2))

            clRunner2=CLRunner(shell=True)
            clRunner2.run(cl2)
            identifyCLRawOutput2=clRunner2.stdout()

            identifyParser2 = IdentifyParser()
            dpiX = identifyParser2.parseFormatHorizontalDPIOption(identifyCLRawOutput2)

            # Get Image DPI Y
            identifyCLBuilder3 = IdentifyCLGenerator()
            identifyCLBuilder3.addInputFile(util.escapePathForOSIndependentShell(filename))
            identifyCLBuilder3.addFormatOption()
            identifyCLBuilder3.addFormatVerticalDPIOption()
            cl3=identifyCLBuilder3.tocl()
            loggerJobCreationRuntime.info("identify cl:" + str(cl3))

            clRunner3=CLRunner(shell=True)
            clRunner3.run(cl3)
            identifyCLRawOutput3=clRunner3.stdout()

            identifyParser3 = IdentifyParser()
            dpiY = identifyParser3.parseFormatVerticalDPIOption(identifyCLRawOutput3)

            # Get Image Quality
            identifyCLBuilder4 = IdentifyCLGenerator()
            identifyCLBuilder4.addInputFile(util.escapePathForOSIndependentShell(filename))
            identifyCLBuilder4.addFormatOption()
            identifyCLBuilder4.addFormatQualityOption()
            cl4=identifyCLBuilder4.tocl()
            loggerJobCreationRuntime.info("identify cl:" + str(cl4))

            clRunner4=CLRunner(shell=True)
            clRunner4.run(cl4)
            identifyCLRawOutput4=clRunner4.stdout()

            identifyParser4 = IdentifyParser()
            quality = identifyParser4.parseFormatQualityOption(identifyCLRawOutput4)
            imageStream = ImageStream(filename=filename,
                                      width=width,
                                      height=height,
                                      quality=quality,
                                      densityX=dpiX,
                                      densityY=dpiY)
            imageStreams = dict()
            imageStreams["0"] = imageStream
            streamsMediaObjects = dict(image=imageStreams)
            return streamsMediaObjects