curveAdjustmentToACV

Photoshop Script Snippets - Note: Full Scripts go in the Photoshop Scripts Forum

Moderators: Tom, Kukurykus

Mike Hale

curveAdjustmentToACV

Post by Mike Hale »

Here is a sample script that will save an acv file from an existing curves adjustment layer. The script expects the adjustment layer to be the active layer and I only tested with RGB 8bit images on Windows

Code: Select all

File.prototype.writeByte = function(b) {
  this.write(String.fromCharCode(b));
};
File.prototype.writeShort = function(ET,s) {
  var self = this;
if(ET == "BE"){
  self.writeByte(s & 0xFF);
  self.writeByte((s >> 8) & 0xFF);
}else{
  self.writeByte((s >> 8) & 0xFF);
  self.writeByte(s & 0xFF);
}
  return self;
};
convertBCD = function( num ){
   if(num == 13){
      return [1,1,0,1];// special case
   }
   var res = new Array;
   if(num > 8 ){
      res.unshift(1);
      num = num - 8;
   }else{
      res.unshift(0);
   }
   if(num > 4 ){
      res.unshift(1);
      num = num - 4;
   }else{
      res.unshift(0);
   }
   if(num > 2 ){
      res.unshift(1);
      num = num - 2;
   }else{
      res.unshift(0);
   }
   if(num == 1 ){
      res.unshift(1);
   }else{
      res.unshift(0);
   }
   return res;
};
getCurve = function( numberOfPoints ){
   this.getPoints = function(){
      this.tempArray = new Array;
      this.tempArray.push( rawDesc.charCodeAt( pointer ) );
      pointer = pointer + 2;// set pointer to next point
      this.tempArray.push( rawDesc.charCodeAt( pointer ) );
      return this.tempArray;
   }
   
   this.pointsArray = new Array;
   for( var i = 0; i < numberOfPoints; i++ ){
      pointer = pointer + 2;// next point
      this.pointsArray.push( this.getPoints() );
   }
   pointer = pointer + 2;// next curve
   return this.pointsArray;
};

var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID( 'Lyr ' ), charIDToTypeID( 'Ordn' ), charIDToTypeID( 'Trgt' ) ); 
var rawDesc = executeActionGet( ref ).getList( stringIDToTypeID( 'adjustment' ) ).getObjectValue( 0 ).getData( stringIDToTypeID( 'legacyContentData' ) );

var pointer = 2;// used to read rawData similar to reading a file
var flag = rawDesc.charCodeAt( pointer );// char at offset 2 always == 1 so use to validate data
if( flag != 1 ) forceError;// unknown problem with rawData
   pointer = 6;// update pointer to BCD byte
   var bcd = rawDesc.charCodeAt( pointer );
   if( bcd < 0 || bcd > 15 ) forceError;// check for valid value
   if( bcd == 0 ) forceError;// an empty adjustment - no curves to process
   var bcdArray = convertBCD( bcd );
   var numberOfCurves = bcdArray.toString().match(/(1)/g).length;
   var curvesArray = new Array;
   pointer = 8;// set pointer to start of curve data
   for(var i = 0; i < numberOfCurves; i++ ){
      var numberOfPoints = rawDesc.charCodeAt( pointer );
      curvesArray.push( getCurve( numberOfPoints ) );
   }
// now need to map rawData curves in curvesArray to known channel curves
// for example if bcd == 7 then there is a RGB, RED, and GREEN curve
// if bcd ==  8 then there is only a BLUE curve. etc
var acvArray = new Array;
if( bcdArray[0] == 1 ) {
   acvArray.push( curvesArray.shift() );
} else {
   acvArray.push( [ [0,0],[255,255] ] );
}
if( bcdArray[1] == 1 ) {
   acvArray.push( curvesArray.shift() );
} else {
   acvArray.push( [ [0,0],[255,255] ] );
}
if( bcdArray[2] == 1 ) {
   acvArray.push( curvesArray.shift() );
} else {
   acvArray.push( [ [0,0],[255,255] ] );
}
if( bcdArray[3] == 1 ) {
   acvArray.push( curvesArray.shift() );
} else {
   acvArray.push( [ [0,0],[255,255] ] );
}
acvArray.push( [ [0,0],[255,255] ] );
var myACV = new File('/c/temp/myCurve.acv');
myACV.open('w');
myACV.writeShort( 'LE','4' );// acv header
myACV.writeShort( 'LE','5' );// acv header
for( var i = 0; i< 5; i++ ) {
   var numberOfPoints = acvArray[i].length;
   myACV.writeShort( 'LE', numberOfPoints.toString() );
   //myACV.writeByte( 0 );
   for( var p = 0; p < numberOfPoints; p++ ){
      myACV.writeShort( 'LE', acvArray[i][p][0].toString() );
      myACV.writeShort( 'LE', acvArray[i][p][1].toString() );
   }
}
myACV.close();
'm'