//v0.1 - 2017.03.29 //- initial version //v0.2 - 2017.05.09 //- add REMOVEUTF8BOM feature //- XLog updated to v0.45 //todo: //- FROM parameter for TODNG to allow direct input of files to convert? /////////////////////////////////////////////////////////////////////////////// var template = "" + "TODNG/S,"+ //convert any-raw to dng-raw "DELETE/S,"+ //delete source raw files if dng successfully created "NOPROGRESS/S,"+ //no progess dialog "HERE/S,"+ //create dng in same directory of raw-file (default is destination-tab if DUAL) "TO/O," + //create dng in specific target directory, not destination tab "REMOVEUTF8BOM/S," + "DESELECT/O[,fail,none,all]," + //shared misc "NOFAIL/S,NODESELECT/S,"+ "XLOG/O[off,xit,error,warning,info,,trace,dump,all],"+ "PT/R"; //passthrough arguments /////////////////////////////////////////////////////////////////////////////// function OnInit(data) { //uid added via script wizard (do not change after publishing this script) var uid = "641E7A7B-36E6-4718-8C73-7E2A8750F585"; //thread url added via script wizard (required for updating) var url = "https://resource.dopus.com/t/command-convertex-dng-converter-encodings-etc/25847"; /////////////////////////////////////////////////////////////////////////////// data.name = "Command.Generic: ConvertEx"; data.desc = "Extended convert functionality."; data.copyright = "tbone"; data.version = "0.2"; if (DOpus.Version.AtLeast("12.0.8")) data.url = (typeof url == 'undefined' ? '' : url); data.default_enable = true; var cmd = data.AddCommand(); cmd.name = "ConvertEx"; cmd.method = "Command_ConvertEx"; cmd.label = data.name = "ConvertEx"; cmd.desc = data.desc; cmd.template = template; /////////////////////////////////////////////////////////////////////////// function ConfigHelper(data){ //v1.2 var t=this; t.d=data; t.c=data.config; t.cd=DOpus.Create.Map(); t.add=function(name, val, des){ t.l={n:name,ln:name. toLowerCase()}; return t.val(val).des(des);} t.des=function(des){ if (!des) return t; if (t.cd.empty) t.d.config_desc=t.cd; t.cd(t.l.n)=des; return t;} t.val=function(val){ var l=t.l; if (l.v!==l.x&&typeof l.v=="object") l.v.push_back(val);else l.v=t.c[l.n]=val;return t;} t.trn=function(){return t.des(t("script.config."+t.l.ln));}} /////////////////////////////////////////////////////////////////////////// var cfg = new ConfigHelper(data); cfg.add('Exe.DNGConverter', "%ProgramFiles(x86)%\\Adobe\\Adobe DNG Converter.exe"). des('Path to "Adobe DNG Converter.exe".'); cfg.add('Exe.DNGConverter.Switches', ""). des('Additional commandline switches for "Adobe DNG Converter.exe". Switches -d and -c cannot be used.'); cfg.add('XLog', DOpus.Create.Vector()). val(5).val("Off").val("Exception").val("Error").val("Warning").val("Info").val("Normal").val("Trace").val("Dump").val("All"). des('Console output level. The higher, the more output will be visible in the console window. '); } /////////////////////////////////////////////////////////////////////////////// var COMMAND_FAILURE = true; var COMMAND_USERABORT = true; var COMMAND_BADPARAMS = true; var COMMAND_SUCCESS = false; /////////////////////////////////////////////////////////////////////////////// function Command_ConvertEx(data) { /////////////////////////////////////////////////////////////////////////////// var args = ArgsMagic(data, null, template), result = null; //DumpObject(args); //return; if (args["XLOG"].exists){ XLog = args["XLOG"].value; } Log("CmdLine: " + data.cmdline,"D"); if (args["NODESELECT"].exists) data.func.command.deselect = false; if (args["NOFAIL"].exists) COMMAND_FAILURE = COMMAND_SUCCESS; if (0); else if (args["TODNG"].exists) return ConvertEx_TODNG(data.func.command, data.func.sourcetab, data.func.desttab, args); else if (args["REMOVEUTF8BOM"].exists) return ConvertEx_REMOVEUTF8BOM(data.func.command, data.func.sourcetab, data.func.desttab, args); if (result===null){ Log("Bad/incomplete params.","X"); return COMMAND_BADPARAMS; } return result; } /////////////////////////////////////////////////////////////////////////////// function ConvertEx_REMOVEUTF8BOM(cmd, sourcetab, desttab, args) { /////////////////////////////////////////////////////////////////////////////// Log("ConvertEx_REMOVEUTF8BOM():", "T", 1); var tab = sourcetab, selFiles = tab.selected_files; var vDeSelOK = DOpus.Create.Vector(), vDeSelFAIL = DOpus.Create.Vector() for (var eSel = new Enumerator(selFiles); !eSel.atEnd(); eSel.moveNext()) { var bomRemoved = RemoveUTF8BOM(eSel.item(), tab); if (bomRemoved){ Log("Removing BOM ["+eSel.item().realpath+"] succeeded.", "d"); vDeSelOK.push_back(eSel.item()); } else { Log("Removing BOM ["+eSel.item().realpath+"] FAILED.", "i"); vDeSelFAIL.push_back(eSel.item()); } } Log("Done.", "t", -1); if (args["DESELECT"].value!='none') { cmd.ClearFiles(); if (args["DESELECT"].value == 'all'){ cmd.AddFiles(vDeSelOK); cmd.AddFiles(vDeSelFAIL); } if (args["DESELECT"].value == 'success') cmd.AddFiles(vDeSelOK); if (args["DESELECT"].value == 'fail') cmd.AddFiles(vDeSelFAIL); cmd.RunCommand("Select DESELECT FROMSCRIPT"); } if (vDeSelFAIL.size) return COMMAND_FAILURE; return COMMAND_SUCCESS; } /////////////////////////////////////////////////////////////////////////////// function RemoveUTF8BOM( doItem, tab) { /////////////////////////////////////////////////////////////////////////////// var bBOM = DOpus.Create.Blob(0xEF,0xBB,0xBF); var bFile = DOpus.Create.Blob(); tab = tab || null; var f = doItem.Open("r", tab); if (f.error != 0) return false; if (f.Read(bFile, 3) != 3 || bBOM.Compare(bFile) != 0) return false; bFile.Free(); f.Read(bFile); if (f.error != 0) return false; f.Close(); f = doItem.Open("wt", tab); if (f.error != 0) return false; f.Write(bFile); f.Close(); bFile.Free(); return true; } /////////////////////////////////////////////////////////////////////////////// function ConvertEx_TODNG(cmd, sourcetab, desttab, args) { /////////////////////////////////////////////////////////////////////////////// Log("ConvertEx_TODNG():", "T", 1); /////////////////////////////////////////////////////////////////////////// function GetSrcPath(sourcetab, haveSameSrcPath, args) { /////////////////////////////////////////////////////////////////////////// var srcPath = ''+sourcetab.path; if (!haveSameSrcPath) srcPath = false; if (srcPath !== false && args["HERE"].exists) srcPath = ''+sourcetab.path; if (srcPath !== false && !DOpus.FSUtil.Exists(srcPath)) { Log("Source folder not found.", "e"); Log("-", "t", -1); srcPath = null; } return srcPath; } /////////////////////////////////////////////////////////////////////////// function GetDstPath(sourcetab, desttab, args) { /////////////////////////////////////////////////////////////////////////// var dstPath = (''+sourcetab.path).toLowerCase(); if (desttab) { dstPath = (''+desttab.path).toLowerCase(); } if (args["HERE"].exists) { dstPath = (''+sourcetab.path).toLowerCase(); } if (args["TO"].exists) { dstPath = (''+args["TO"].value).toLowerCase(); } if (!DOpus.FSUtil.Exists(dstPath)) { Log("Destination folder not found.", "e"); Log("-", "t", -1); dstPath = null; } return dstPath; } /////////////////////////////////////////////////////////////////////////// function AreSingleSrcPathItems(doItems){ //determine whether the collection contains files from one folder only. //in flat view, files will have different paths, need special handling. /////////////////////////////////////////////////////////////////////////// var samePath = true; var prevItemPath = ''; var itemPath = ''; if (doItems.count == 1) return false; for(var i=0;i>D:\output.txt // echo CD /D {sourcepath$} >>D:\output.txt //http://wwwimages.adobe.com/content/dam/Adobe/en/products/photoshop/pdfs/dng_commandline.pdf //-c Output compressed DNG files (default). //-u Output uncompressed DNG files. //-l Output linear DNG files. //-e Embed original raw file inside DNG files. //-p0 Set JPEG preview size to none. // -> tb: will not allow exiftool to set a new preview thumbnail in the DNG //-p1 Set JPEG preview size to medium size (default). //-p2 Set JPEG preview size to full size. //-fl Embed fast load data. //-lossy Specify lossy compression. Defaults to preserve pixel count. // Specify a long-side pixels or megapixels limit with optional //-side or -count options defined below. Valid for Camera Raw // compatibility 6.6 or later. //-side Specify a long-side pixels value from 32 to 65000 pixels. //-count Specify a megapixels limit of 1024 (1MP) or greater. //-cr2.4 Set Camera Raw compatibility to 2.4 and later //-cr4.1 Set Camera Raw compatibility to 4.1 and later //-cr4.6 Set Camera Raw compatibility to 4.6 and later //-cr5.4 Set Camera Raw compatibility to 5.4 and later //-cr6.6 Set Camera Raw compatibility to 6.6 and later //-cr7.1 Set Camera Raw compatibility to 7.1 and later (default) //-dng1.1 Set DNG backward version to 1.1 //-dng1.3 Set DNG backward version to 1.3 //-dng1.4 Set DNG backward version to 1.4 (default) //-x Extract original embedded raw file(s) from source file argument(s). // Overrides options above. //-d Output converted or extracted files to the specified directory. // Default to the parent directory of the input file. In the case of // multiple input files, it defaults to the parent directory of each file. //-o Specify the name of the output DNG file. // Default is the name of the input file with the extension // changed to “.dng”. // When converting multiple files with a single command, // output files will use this as a base name and will be numbered // sequentially. Ignored when using -x option. // -> tb: option -o needs to be put before -c (the file(s) to convert) // -> tb: if output file exists, converter will add suffix "*_x.dng" // -> tb: seems to make sense for patterns like . only /* echo 1 {sourcepath$} >D:\output.txt CD /D {sourcepath$} echo 2 {sourcepath$} >>D:\output.txt "C:\Program Files (x86)\Adobe\Adobe DNG Converter.exe" -d {sourcepath$} -c {allfile$} echo "C:\Program Files (x86)\Adobe\Adobe DNG Converter.exe" -c {allfile$} >>D:\output.txt echo CD /D {sourcepath$} >>D:\output.txt pause */ } /////////////////////////////////////////////////////////////////////////////// String.prototype.lTrim = function(chr){chr=chr||"\\s";return new String(this.replace(new RegExp("^"+chr+"*"),''));} String.prototype.rTrim = function(chr){chr=chr||"\\s";return new String(this.replace(new RegExp(chr+"*$"),''));} String.prototype.trim = function(chr){return this.lTrim(chr).rTrim(chr);} String.prototype.left = function(chrs){return this.substring(0,chrs);} String.prototype.right = function(chrs){return this.substring(this.length-chrs);} String.prototype.contains = function (s,nocs){return (nocs?this.toUpperCase():this).indexOf(nocs?s.toUpperCase():s)>=0;}; String.prototype.startsWith = function (s,nocs){return (nocs?this.toUpperCase():this).indexOf(nocs?s.toUpperCase():s)==0;}; String.prototype.endsWith = function (s,nocs){return (nocs?this.toUpperCase():this).slice(-s.length)==(nocs?s.toUpperCase():s);}; /////////////////////////////////////////////////////////////////////////////// function ArgsMagic(data, jsonData, template){ this.version = 0.42; /////////////////////////////////////////////////////////////////////////// function Arg(name, type, exists, value, subOpsTemplate){ this.name = name; this.exists = exists; this.type = type; this.value = value; this.options = []; if (!this.exists) return; switch (type){ case "switch":; case "numeric":; case "multiple": return;} if (this.type=="optional" && this.value===true) this.value=""; var op,ops=this.value!=""?new String(this.value).split(","):null, match; if (ops && ops.length) for(op in ops) { var opName = ops[op].replace('"',''); var opValue = true, parts = opName.split("="); opName = parts[0].trim("<").trim(">"); if (parts.length>1) opValue = parts.slice(1).join(""); this.options[opName] = opValue; } if (!(!this.value && subOpsTemplate)) return; if (!(match = subOpsTemplate.match(/\<(.+?)\>/))) return; this.options[match[1]] = true; this.value = match[1]; } /////////////////////////////////////////////////////////////////////////// var types = {s:"switch",k:"keyword",o:"optional",n:"numeric",m:"multiple",r:"raw"}; var names = template.replace(/\/(.)\,/g,"/$1;").replace(/\]\,/g,"];").split(";"), args = []; for(arg in names) { var parts = names[arg].split("/"); var name=parts[0].toUpperCase(), subOpsTemplate=null; var parts2 = parts[1].split("["); var type=parts2[0].toLowerCase(); if (parts2.length>1) subOpsTemplate = parts2[1].substring(0,parts2[1].length-1); var exists=(data&&data.func.args.got_arg[name])||(jsonData&&(jsonData[name]!=undefined))||false; var value = (data && data.func.args[name]) || (jsonData && jsonData[name]) || undefined; args.push( args[name] = new Arg(name, types[type], exists, value, subOpsTemplate )); } /////////////////////////////////////////////////////////////////////////// args.Get = function( argName, configName, noneValue){ var arg = this[argName = argName.toUpperCase()]; if (!arg) throw new Error(0, "Unknown parameter ["+argName+"]"); if (arg.exists) return arg.value; //DOpus.Output("argName: " + argName); //DOpus.Output("configName: " + configName); if (!configName) return noneValue; if (typeof Script.config[configName] == "string") return new String(""+Script.config[configName]); return Script.config[configName]; } return args; } /////////////////////////////////////////////////////////////////////////////// function Log(text, lvl, ind){ //XLog v0.45 (allow early usage, but warn (Script-object cannot be typeof'ed)) var u,lvs={o:0,x:1,e:2,w:3,i:4,n:5,t:6,d:7,a:8},i=["","X","E","W","I","","","",""],d=DOpus; if (typeof XLog==(u="undefined")){var v=d.Vars; if (v.Exists("XLog") && typeof XLogForce==u) {XLog=v.Get("XLog"); }} if (typeof XLog==u){try{var c=Script.Config;if(typeof c.XLog!=u){XLog=c.XLog;}}catch(e){d.Output("XLog: Early call, log-level=all.",1);XLog=8;}} if (typeof XLog==u){XLog="normal";} if(XLog.paused===undefined){ if(XLog===true) var L=5; else if(!isNaN(parseInt(XLog,10))) var L=XLog*1; else var L=lvs[(""+XLog).toLowerCase().substring(0,1)]; XLog={paused:false,I:0,L:L};} lvl=(lvl==undefined?5:lvs[lvl.substring(0,1).toLowerCase()]); if (!(lvl && XLog.L && !XLog.paused && (lvl<=XLog.L))){ return;} var pad = (XLog.I==0?"":new Array(XLog.I+1).join(" ")); if (i[lvl])pad = i[lvl]+(!pad?" ":pad.substring(1)); if (text!="-"){if (d.Version.AtLeast("11.13.1")) d.Output(pad+text,((lvl==1||lvl==2)?1:0)); else d.Output(pad+text);} ind=(ind!==undefined?ind:0);XLog.I+=ind;if(XLog.I<0)throw new Error("XLog indent went sub-zero."); } /////////////////////////////////////////////////////////////////////////////// function DumpObject(o, name, upperCaseProps, self, level){ this.version = 0.4; name = name || "unnamed"; if (self == undefined) DOpus.Output("DumpObject(): ["+name+"]"); var maxLen = 0; upperCaseProps = upperCaseProps || false; self = self || false; level = level || " "; for(prop in o) if (prop.length > maxLen) maxLen = prop.length; for(prop in o) { var pad = ""; while (pad.length+prop.length