nmhbjh
// (c) Copyright 2007 Adobe Systems, Inc. All rights reserved.
// Written by Ed Rose
// based on the ADM Mode Change by Joe Ault from 1998
/*
@@@BUILDINFO@@@ Conditional Mode Change.jsx 1.0.0.12
*/
/* Special properties for a JavaScript to enable it to behave like an automation plug-in, the variable name must be exactly
as the following example and the variables must be defined in the top 10000 characters of the file
// BEGIN__HARVEST_EXCEPTION_ZSTRING
$$$/JavaScripts/ModeChange/Name=Conditional Mode Change...
true
8cba8cd6-cb66-11d1-bc43-0060b0a13dc4
>]
>>
/Enums <<
/sourceModeType <<
/uIBitmap ($$$/AdobePlugin/ConditionalModeChange/Bitmap=Bitmap)
/uIGrayscale ($$$/AdobePlugin/ConditionalModeChange/Grayscale=Grayscale)
/uIDuotone ($$$/AdobePlugin/ConditionalModeChange/Duotone=Duotone)
/uIIndexed ($$$/AdobePlugin/ConditionalModeChange/Indexed=Indexed)
/uIRGB ($$$/AdobePlugin/ConditionalModeChange/RGB=RGB)
/uICMYK ($$$/AdobePlugin/ConditionalModeChange/CMYK=CMYK)
/uILab ($$$/AdobePlugin/ConditionalModeChange/Lab=Lab)
/uIMultichannel ($$$/AdobePlugin/ConditionalModeChange/Multichannel=Multichannel)
>>
>>
>> ]]>
// END__HARVEST_EXCEPTION_ZSTRING
*/
// enable double clicking from the Macintosh Finder or the Windows Explorer
#target photoshop
// debug level: 0-2 (0:disable, 1:break on error, 2:break at beginning)
//$.level = 1;
//debugger; // launch debugger on next line
// on localized builds we pull the $$$/Strings from a .dat file, see documentation for more details
$.localize = true;
var gScriptResult;
// ok and cancel button
var okButtonID = 1;
var cancelButtonID = 2;
// the main routine
// the ModeChange object does most of the work
try {
GlobalVariables();
CheckVersion();
// create our default params
var changeInfo = new ChangeInfo();
var gMC = new ModeChange();
if ( DialogModes.ALL == app.playbackDisplayDialogs ) {
gMC.CreateDialog();
if (cancelButtonID == gMC.RunDialog() ) { // <- this calls MCExecute
gScriptResult = 'cancel';
}
} else {
if ( gMC.InitVariables() ) { // only proceed if document to change
if ( ! MCExecute() ) {
gScriptResult = 'cancel';
}
} else {
gScriptResult = 'cancel';
}
}
if (!rollItBack) { // rollItBack is set false when MCExecute correctly happens
SaveOffParameters(changeInfo);
}
}
// Lot's of things can go wrong
// Give a generic alert and see if they want the details
catch( e ) {
if ( DialogModes.NO != app.playbackDisplayDialogs ) {
alert( e + " : " + e.line );
}
gScriptResult = 'cancel';
}
// restore the dialog modes
app.displayDialogs = gSaveDialogMode;
gScriptResult;
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
// created via new ChangeInfo(), above
function SaveOffParameters(changeInfo) {
// save off our last run parameters
var d = ChangeInfoToDescriptor(changeInfo, strMessage);
app.putCustomOptions("85d5fff3-b16f-432c-96e6-6dbbedbbdcda", d);
app.playbackDisplayDialogs = DialogModes.ALL;
var dd = ChangeInfoToDescriptor(changeInfo, strMessage);
app.playbackParameters = dd;
}
function GlobalVariables() {
// a version for possible expansion issues
gVersion = 1;
// remember the dialog modes
gSaveDialogMode = app.displayDialogs;
app.displayDialogs = DialogModes.NO;
//
// all the strings that need to be localized
//
// title of app
strTitle = localize( "$$$/JavaScript/ModeChange/Title=Conditional Mode Change" );
// buttons
strButtonOK = localize("$$$/JavaScripts/ModeChange/OK=OK");
strButtonCancel = localize("$$$/JavaScripts/ModeChange/Cancel=Cancel");
strButtonAll = localize("$$$/JavaScripts/ModeChange/All=&All");
strButtonNone = localize("$$$/JavaScripts/ModeChange/None=&None");
// panel strings
strSrcMode = localize("$$$/JavaScripts/ModeChange/SrcMode=Source Mode");
strTargMode = localize("$$$/JavaScripts/ModeChange/TargetMode=Target Mode");
// checkbox strings
strChkBitmap = localize("$$$/JavaScripts/ModeChange/ChkBitmap=&Bitmap");
strChkGraysc = localize("$$$/JavaScripts/ModeChange/ChkGraysc=&Grayscale");
strChkDuotone = localize("$$$/JavaScripts/ModeChange/ChkDuotone=&Duotone");
strChkIxClr = localize("$$$/JavaScripts/ModeChange/ChkIxClr=&Indexed Color");
strChkRGB = localize("$$$/JavaScripts/ModeChange/ChkRGB=&RGB Color");
strChkCMYK = localize("$$$/JavaScripts/ModeChange/ChkCMYK=&CMYK Color");
strChkLab = localize("$$$/JavaScripts/ModeChange/ChkLab=&Lab Color");
strChkMChan = localize("$$$/JavaScripts/ModeChange/ChkMChan=M&ultichannel");
// popup strings
strPopBitmap = localize("$$$/JavaScripts/ModeChange/PopBitmap=Bitmap");
strPopGraysc = localize("$$$/JavaScripts/ModeChange/PopGraysc=Grayscale");
strPopDuotone = localize("$$$/JavaScripts/ModeChange/PopDuotone=Duotone");
strPopIxClr = localize("$$$/JavaScripts/ModeChange/PopIxClr=Indexed Color");
strPopRGB = localize("$$$/JavaScripts/ModeChange/PopRGB=RGB Color");
strPopCMYK = localize("$$$/JavaScripts/ModeChange/PopCMYK=CMYK Color");
strPopLab = localize("$$$/JavaScripts/ModeChange/PopLab=Lab Color");
strPopMChan = localize("$$$/JavaScripts/ModeChange/PopMChan=Multichannel");
// label
strModeLbl = localize("$$$/JavaScripts/ModeChange/ModeLbl=&Mode:");
// alert dialog strings
strTextNeedFile = localize("$$$/JavaScripts/ModeChange/NeedFile=You must have a file selected before using Conditional Mode Change");
strTextModeMatch = localize("$$$/JavaScripts/ModeChange/ModeMatch=Mode of the document does not match any selected Source Modes.");
strTextOneSrcMode = localize("$$$/JavaScripts/ModeChange/OneSrcMode=At least one Source Mode must be selected.");
strTextErrRetHist = localize("$$$/JavaScripts/ModeChange/ErrRetHist=Error retrieving history preferences.");
strTextErrSetHist = localize("$$$/JavaScripts/ModeChange/ErrSetHist=Error setting history preferences.");
strTextErrDocAttr = localize("$$$/JavaScripts/ModeChange/ErrDocAttr=Error retrieving document attributes. No conversion performed.");
strTextErrIntCnv8 = localize("$$$/JavaScripts/ModeChange/ErrIntCnv8=Error with intermediate conversion to 8-bit color.");
strTextErrCvtRGB = localize("$$$/JavaScripts/ModeChange/ErrCvtRGB=Error with conversion to RGB color mode.");
strTextErrCvtGray = localize("$$$/JavaScripts/ModeChange/ErrCvtGray=Error with conversion to Grayscale mode.");
strTextErrCvtTarg = localize("$$$/JavaScripts/ModeChange/ErrCvtTarg=Error with converting to Target Mode.");
strTextModeSame = localize("$$$/JavaScripts/ModeChange/ModeSame=Mode of the document is the same as the Target Mode. No conversion performed.");
strTextErrIntCnv16 = localize("$$$/JavaScripts/ModeChange/ErrIntCnv16=Error with intermediate conversion to 16-bit color.");
strMessage = localize("$$$/JavaScripts/ModeChange/Message=Conditional Mode Change action settings");
strMustUse = localize( "$$$/JavaScripts/ImageProcessor/MustUse=You must use Photoshop CS 2 or later to run this script!" );
// bit flags for checkboxes
FLAG_BITMAP = false;
FLAG_GRAYSCALE = false;
FLAG_DUOTONE = false;
FLAG_INDEXED = false;
FLAG_RGB = true;
FLAG_CMYK = false;
FLAG_LAB = false;
FLAG_MULTICHANNEL = false;
// constants
FLATTEN_UNUSED = 99; // flattening unspecified
DEPTH_UNSET = 99; // depth of the document unset
classNull = charIDToTypeID( 'null' ); // ain't nothing here (error)
classBitmapMode = charIDToTypeID( 'BtmM' );
classGrayscaleMode = charIDToTypeID( 'Grys' );
classDuotoneMode = charIDToTypeID( 'DtnM' );
classIndexedColorMode = charIDToTypeID( 'IndC' );
classRGBColorMode = charIDToTypeID( 'RGBM' );
classCMYKColorMode = charIDToTypeID( 'CMYM' );
classLabColorMode = charIDToTypeID( 'LbCM' );
classMultichannelMode = charIDToTypeID( 'MltC' );
enumUIMultichannel = charIDToTypeID( 'UMlt' );
enumUILab = charIDToTypeID( 'ULab' );
enumUICMYK = charIDToTypeID( 'UCMY' );
enumUIRGB = charIDToTypeID( 'URGB' );
enumUIIndexed = charIDToTypeID( 'UInd' );
enumUIDuotone = charIDToTypeID( 'UDtn' );
enumUIGrayscale = charIDToTypeID( 'UGry' );
enumUIBitmap = charIDToTypeID( 'UBtm' );
keySourceMode = charIDToTypeID( 'SrcM' );
typeSourceMode = charIDToTypeID( 'Cndn' );
keyDestinationMode = charIDToTypeID( 'DstM' );
keyMerge = charIDToTypeID( 'Mrge' );
keyMessage = charIDToTypeID( 'Msge' );
// variables
rollItBack = true; // flag to tell whether to roll back (assumed true until valid MCExecute)
}
// the main class
function ModeChange() {
this.CreateDialog = function() {
var res =
"dialog { \
ModesOKCancel: Group { orientation: 'row', \
STModes: Group { orientation: 'column', \
src: Panel { orientation: 'row', \
text: '" + strSrcMode +"', \
L1: Group { orientation: 'column', \
bmp: Checkbox { text:'" + strChkBitmap +"', alignment:'left'}, \
gry: Checkbox { text:'" + strChkGraysc + "', alignment:'left'}, \
duo: Checkbox { text:'" + strChkDuotone + "', alignment:'left'}, \
ixc: Checkbox { text:'" + strChkIxClr + "', alignment:'left'}, \
AORN: Group { orientation: 'row', \
all: Button { text:'" + strButtonAll +"', properties:{name:'all'} }, \
non: Button { text:'" + strButtonNone +"', properties:{name:'none'} } \
} \
}, \
L2: Group { orientation: 'column', alignment: 'top', \
rgb: Checkbox { text:'" + strChkRGB + "', alignment:'left'}, \
cmy: Checkbox { text:'" + strChkCMYK + "', alignment:'left'}, \
lab: Checkbox { text:'" + strChkLab + "', alignment:'left'}, \
mch: Checkbox { text:'" + strChkMChan + "', alignment:'left'} \
} \
}, \
targ: Panel { orientation: 'column', \
text: '" + strTargMode +"', \
w: Group { orientation: 'row', \
mod: StaticText { text:'" + strModeLbl +"' }, \
drp: DropDownList {alignment:'left'} \
}, \
}, \
}, \
buttons: Group { alignChildren: 'fill', orientation: 'column', alignment: 'top', \
okBtn: Button { text:'" + strButtonOK +"', properties:{name:'ok'} }, \
cancelBtn: Button { text:'" + strButtonCancel + "', properties:{name:'cancel'} } \
} \
} \
}";
// create the main dialog window, this holds all our data
this.dlgMain = new Window(res,strTitle);
// match our dialog background color to the host application
this.dlgMain.graphics.backgroundColor = this.dlgMain.graphics.newBrush (this.dlgMain.graphics.BrushType.THEME_COLOR, "appDialogBackground");
// create a shortcut for easier typing
var d = this.dlgMain;
var drop = d.ModesOKCancel.STModes.targ.w.drp; // for easier typing
drop.add('item',strPopBitmap); // 0
drop.add('item',strPopGraysc); // 1
drop.add('item',strPopDuotone); // 2
drop.add('item',strPopIxClr); // 3
drop.add('item',strPopRGB); // 4
drop.add('item',strPopCMYK); // 5
drop.add('item',strPopLab); // 6
drop.add('item',strPopMChan); // 7
drop.selection = drop.items[5]; // CMYK
changeInfo.destinationMode = 5;
changeInfo.destMode = IndexToMode(changeInfo.destinationMode);
d.ModesOKCancel.STModes.src.L2.rgb.value = true;
d.defaultElement = d.ModesOKCancel.buttons.okBtn;
d.cancelElement = d.ModesOKCancel.buttons.cancelBtn;
} // end of CreateDialog
// initialize variables of dialog
// return false if no document to change, true if found document to change
this.InitVariables = function() {
// look for last used params via Photoshop registry, getCustomOptions will throw if none exist
try {
var desc = app.getCustomOptions("85d5fff3-b16f-432c-96e6-6dbbedbbdcda");
DescriptorToChangeInfo(changeInfo, desc, strMessage);
}
catch(e) {
// it's ok if we don't have any options, continue with defaults
}
// see if I am getting descriptor parameters
DescriptorToChangeInfo(changeInfo, app.playbackParameters, strMessage);
// make internal state reflect saved parameters
changeInfo.destMode = IndexToMode(changeInfo.destinationMode);
FLAG_BITMAP = changeInfo.flagBITMAP;
FLAG_GRAYSCALE = changeInfo.flagGRAYSCALE;
FLAG_DUOTONE = changeInfo.flagDUOTONE;
FLAG_INDEXED = changeInfo.flagINDEXED;
FLAG_RGB = changeInfo.flagRGB;
FLAG_CMYK = changeInfo.flagCMYK;
FLAG_LAB = changeInfo.flagLAB;
FLAG_MULTICHANNEL = changeInfo.flagMULTICHANNEL;
// make sure to do this after get parameters
if (app.documents.length <= 0) // count of documents viewed
{
if ( DialogModes.NO != app.playbackDisplayDialogs ) {
alert(strTextNeedFile);
}
return false; // error, don't proceed
}
if ( DialogModes.ALL == app.playbackDisplayDialogs ) {
var d = this.dlgMain;
var drop = d.ModesOKCancel.STModes.targ.w.drp; // for easier typing
// make dialog reflect saved parameters
drop.selection = drop.items[changeInfo.destinationMode];
d.ModesOKCancel.STModes.src.L1.bmp.value = changeInfo.flagBITMAP;
d.ModesOKCancel.STModes.src.L1.gry.value = changeInfo.flagGRAYSCALE;
d.ModesOKCancel.STModes.src.L1.duo.value = changeInfo.flagDUOTONE;
d.ModesOKCancel.STModes.src.L1.ixc.value = changeInfo.flagINDEXED;
d.ModesOKCancel.STModes.src.L2.rgb.value = changeInfo.flagRGB;
d.ModesOKCancel.STModes.src.L2.cmy.value = changeInfo.flagCMYK;
d.ModesOKCancel.STModes.src.L2.lab.value = changeInfo.flagLAB;
d.ModesOKCancel.STModes.src.L2.mch.value = changeInfo.flagMULTICHANNEL;
}
return true; // all is good, continue
}
// routine for running the dialog and it's interactions
this.RunDialog = function () {
var d = this.dlgMain;
// in case hit cancel button, don't close
d.ModesOKCancel.buttons.cancelBtn.onClick = function() {
var dToCancel = FindDialog( this );
dToCancel.close( cancelButtonID );
rollItBack = true;
}
// nothing for now
d.onShow = function() {
}
// destination dropdown handler
d.ModesOKCancel.STModes.targ.w.drp.onChange = function() {
var theSelection = this.selection.text;
var theSelectionIndex = this.selection.index;
if (theSelection != null) { // only change if selection made
changeInfo.destinationMode = theSelectionIndex;
changeInfo.destMode = IndexToMode(changeInfo.destinationMode);
}
}
// the source mode buttons
d.ModesOKCancel.STModes.src.L1.bmp.onClick = function() {
FLAG_BITMAP = ! FLAG_BITMAP;
changeInfo.flagBITMAP = FLAG_BITMAP;
}
d.ModesOKCancel.STModes.src.L1.gry.onClick = function() {
FLAG_GRAYSCALE = ! FLAG_GRAYSCALE;
changeInfo.flagGRAYSCALE = FLAG_GRAYSCALE;
}
d.ModesOKCancel.STModes.src.L1.duo.onClick = function() {
FLAG_DUOTONE = ! FLAG_DUOTONE;
changeInfo.flagDUOTONE = FLAG_DUOTONE;
}
d.ModesOKCancel.STModes.src.L1.ixc.onClick = function() {
FLAG_INDEXED = ! FLAG_INDEXED;
changeInfo.flagINDEXED = FLAG_INDEXED;
}
d.ModesOKCancel.STModes.src.L2.rgb.onClick = function() {
FLAG_RGB = ! FLAG_RGB;
changeInfo.flagRGB = FLAG_RGB;
}
d.ModesOKCancel.STModes.src.L2.cmy.onClick = function() {
FLAG_CMYK = ! FLAG_CMYK;
changeInfo.flagCMYK = FLAG_CMYK;
}
d.ModesOKCancel.STModes.src.L2.lab.onClick = function() {
FLAG_LAB = ! FLAG_LAB;
changeInfo.flagLAB = FLAG_LAB;
}
d.ModesOKCancel.STModes.src.L2.mch.onClick = function() {
FLAG_MULTICHANNEL = ! FLAG_MULTICHANNEL;
changeInfo.flagMULTICHANNEL = FLAG_MULTICHANNEL;
}
// all or nothing
d.ModesOKCancel.STModes.src.L1.AORN.all.onClick = function() {
var dThis = FindDialog( this );
SetButtons(dThis, true)
}
d.ModesOKCancel.STModes.src.L1.AORN.non.onClick = function() {
var dThis = FindDialog( this );
SetButtons(dThis, false)
}
// hit OK, do mode convert
d.ModesOKCancel.buttons.okBtn.onClick = function () {
var dThis = FindDialog( this );
if (gMC.saveDest != changeInfo.destMode && changeInfo.modeObject != undefined ) {
changeInfo.modeObject = undefined;
changeInfo.modeClass = undefined;
}
var OKflag = MCExecute();
if (OKflag) {
dThis.close(okButtonID);
}
}
if (!this.InitVariables())
{
return true; // no document to change, kick out now
}
// remember our starting mode
this.saveDest = changeInfo.destMode;
// give the hosting app the focus before showing the dialog
app.bringToFront();
this.dlgMain.center();
return d.show();
}
}
// set all buttons on or off
function SetButtons(d, OnOrOff) {
FLAG_BITMAP = OnOrOff;
changeInfo.flagBITMAP = FLAG_BITMAP;
d.ModesOKCancel.STModes.src.L1.bmp.value = OnOrOff;
FLAG_GRAYSCALE = OnOrOff;
changeInfo.flagGRAYSCALE = FLAG_GRAYSCALE;
d.ModesOKCancel.STModes.src.L1.gry.value = OnOrOff;
FLAG_DUOTONE = OnOrOff;
changeInfo.flagDUOTONE = FLAG_DUOTONE;
d.ModesOKCancel.STModes.src.L1.duo.value = OnOrOff;
FLAG_INDEXED = OnOrOff;
changeInfo.flagINDEXED = FLAG_INDEXED;
d.ModesOKCancel.STModes.src.L1.ixc.value = OnOrOff;
FLAG_RGB = OnOrOff;
changeInfo.flagRGB = FLAG_RGB;
d.ModesOKCancel.STModes.src.L2.rgb.value = OnOrOff;
FLAG_CMYK = OnOrOff;
changeInfo.flagCMYK = FLAG_CMYK;
d.ModesOKCancel.STModes.src.L2.cmy.value = OnOrOff;
FLAG_LAB = OnOrOff;
changeInfo.flagLAB = FLAG_LAB;
d.ModesOKCancel.STModes.src.L2.lab.value = OnOrOff;
FLAG_MULTICHANNEL = OnOrOff;
changeInfo.flagMULTICHANNEL = FLAG_MULTICHANNEL;
d.ModesOKCancel.STModes.src.L2.mch.value = OnOrOff;
}
function MCExecute() {
var docRef = app.activeDocument; // for easier typing
var numChannels = docRef.componentChannels.length; // number of channels in the source doc
var doConversion = false; // do the mode conversion?
var preConvertRGB = false; // convert to image to RGB before final conversion?
var preConvertGray = false; // convert to grayscale before final?
var preConvert8bit = false; // convert to 8-bit color before final?
var preConvert16bit = false; // convert to 16-bit color before final?
var depth = 8; // bit-depth of the current doc
var userCancel = false;
var hasErrorMessage = false;
var errorMessage = "";
var keyTo = charIDToTypeID( 'T ' );
var eventConvertMode = charIDToTypeID( 'CnvM' );
var keyDepth = charIDToTypeID( 'Dpth' );
var colorDepthType = docRef.bitsPerChannel; // Retrieve the color depth
var docMode = docRef.mode; // Retrieve the mode (DocumentMode.RGB, etc)
if ( numChannels == 0 )
numChannels = docRef.channels.length; // for multichannel documents the componentChannels is 0 so use regular ol' channels instead
// get bits per channel
if (colorDepthType == BitsPerChannelType.EIGHT) {
depth = 8;
} else if (colorDepthType == BitsPerChannelType.ONE) {
depth = 1;
} else if (colorDepthType == BitsPerChannelType.SIXTEEN) {
depth = 16;
} else if (colorDepthType == BitsPerChannelType.THIRTYTWO) {
depth = 32;
}
depth *= numChannels; // number of bits per pixel
var targetClass = ModeUIToClass(changeInfo.destMode);
if (targetClass == classNull) {
return -1;
}
// if the doc is already in the destination mode, don't bother
if (changeInfo.destMode == docMode)
{
if ( DialogModes.NO != app.playbackDisplayDialogs ) {
alert(strTextModeSame);
}
return false;
}
// tell them they have to supply at least one input mode
if (!FLAG_BITMAP && !FLAG_GRAYSCALE && !FLAG_DUOTONE && !FLAG_INDEXED
&& !FLAG_RGB && !FLAG_CMYK && !FLAG_LAB && !FLAG_MULTICHANNEL)
{
if ( DialogModes.NO != app.playbackDisplayDialogs ) {
alert(strTextOneSrcMode);
}
return false;
}
// See if the source doc mode matches any of our source switches
switch(docMode)
{
case DocumentMode.BITMAP:
if (FLAG_BITMAP)
{
doConversion = true;
preConvertGray = true;
}
break;
case DocumentMode.GRAYSCALE:
if (FLAG_GRAYSCALE)
{
doConversion = true;
}
break;
case DocumentMode.DUOTONE:
if (FLAG_DUOTONE)
doConversion = true;
break;
case DocumentMode.INDEXEDCOLOR:
if (FLAG_INDEXED)
{
doConversion = true;
if (changeInfo.destMode == DocumentMode.BITMAP || changeInfo.destMode == DocumentMode.DUOTONE)
preConvertGray = true;
else if (changeInfo.destMode == DocumentMode.MULTICHANNEL)
preConvertRGB = true;
}
break;
case DocumentMode.RGB:
if (FLAG_RGB)
{
doConversion = true;
if (changeInfo.destMode == DocumentMode.BITMAP || changeInfo.destMode == DocumentMode.DUOTONE)
preConvertGray = true;
}
break;
case DocumentMode.CMYK:
if (FLAG_CMYK)
{
doConversion = true;
if (changeInfo.destMode == DocumentMode.BITMAP || changeInfo.destMode == DocumentMode.DUOTONE)
preConvertGray = true;
else if (changeInfo.destMode == DocumentMode.INDEXEDCOLOR)
preConvertRGB = true;
}
break;
case DocumentMode.LAB:
if (FLAG_LAB)
{
doConversion = true;
if (changeInfo.destMode == DocumentMode.BITMAP || changeInfo.destMode == DocumentMode.DUOTONE)
preConvertGray = true;
else if (changeInfo.destMode == DocumentMode.INDEXEDCOLOR)
preConvertRGB = true;
}
break;
case DocumentMode.MULTICHANNEL:
if (FLAG_MULTICHANNEL)
{
doConversion = true;
// if we don't have at least 3 channels, we're going to grayscale regardless
if (numChannels < 3)
preConvertGray = true;
else
{
if (changeInfo.destMode == DocumentMode.DUOTONE)
preConvertGray = true;
else if (changeInfo.destMode == DocumentMode.CMYK)
{
if (numChannels < 4)
preConvertRGB = true;
}
else if (changeInfo.destMode == DocumentMode.INDEXEDCOLOR)
{
preConvertRGB = true;
}
}
}
break;
}
// only convert depth if we have to
if (depth >= 16 &&
(changeInfo.destMode == DocumentMode.BITMAP
|| changeInfo.destMode == DocumentMode.DUOTONE
|| changeInfo.destMode == DocumentMode.INDEXEDCOLOR) )
preConvert8bit = true;
if (!preConvert8bit && depth >= 32 &&
(changeInfo.destMode == DocumentMode.CMYK
|| changeInfo.destMode == DocumentMode.LAB
|| changeInfo.destMode == DocumentMode.MULTICHANNEL) )
preConvert16bit = true;
// condition wasn't met, so just return
if (!doConversion) {
if ( DialogModes.NO != app.playbackDisplayDialogs ) {
alert(strTextModeMatch);
}
return false; // fauxSPHandledErr;
}
var historyState = app.activeDocument.activeHistoryState; // remember current state
rollItBack = false;
// Force the image to 8-bit mode, if required
// always do this first
if (preConvert8bit) {
var modeDesc8Bit = new ActionDescriptor();
modeDesc8Bit.putInteger(keyDepth, 8);
var returnDesc = executeAction( eventConvertMode, modeDesc8Bit, DialogModes.NO );
if (returnDesc == classNull) {
if ( DialogModes.NO != app.playbackDisplayDialogs ) {
alert(strTextErrIntCnv8);
}
rollItBack = true;
return false;
}
}
// always do this second
if (preConvert16bit) {
var modeDesc16Bit = new ActionDescriptor();
modeDesc16Bit.putInteger(keyDepth, 16);
var returnDesc = executeAction( eventConvertMode, modeDesc16Bit, DialogModes.NO );
if (returnDesc == classNull) {
if ( DialogModes.NO != app.playbackDisplayDialogs ) {
alert(strTextErrIntCnv16);
}
rollItBack = true;
return false;
}
}
// Force the image into RGB, if required
if (preConvertRGB) {
var modeDescRGB = new ActionDescriptor();
modeDescRGB.putClass(keyTo, classRGBColorMode);
var returnDesc = executeAction( eventConvertMode, modeDescRGB, DialogModes.NO );
if (returnDesc == classNull) {
if ( DialogModes.NO != app.playbackDisplayDialogs ) {
alert(strTextErrCvtRGB);
}
rollItBack = true;
return false;
}
}
// Force the image into grayscale, if required
if (preConvertGray) {
var modeDescGray = new ActionDescriptor();
modeDescGray.putClass(keyTo, classGrayscaleMode);
var returnDesc = executeAction( eventConvertMode, modeDescGray, DialogModes.NO );
if (returnDesc == classNull) {
if ( DialogModes.NO != app.playbackDisplayDialogs ) {
alert(strTextErrCvtGray);
}
rollItBack = true;
return false;
}
}
var modeDesc = new ActionDescriptor();
if (changeInfo.modeObject != undefined) {
modeDesc.putObject(keyTo, changeInfo.modeClass, changeInfo.modeObject);
}
else {
modeDesc.putClass(keyTo, targetClass);
}
if (changeInfo.flatten != FLATTEN_UNUSED) {
modeDesc.putBoolean(keyMerge, changeInfo.flatten);
}
var cancelFlag = false;
try {
var returnDesc = executeAction( eventConvertMode, modeDesc, app.playbackDisplayDialogs );
}
catch (e) {
rollItBack = true;
cancelFlag = true; // assume cancel
}
if (returnDesc == classNull) { // error, no returned descriptor (TO DO: IS THIS CORRECT?)
if ( DialogModes.NO != app.playbackDisplayDialogs ) {
alert(strTextErrCvtTarg);
}
rollItBack = true;
}
else if (!rollItBack) { // if completed successfully...
// check for error message in returned descriptor
var messageStr = "";
var hasErrorMessage = returnDesc.hasKey( keyMessage);
if (hasErrorMessage) {
messageStr = returnDesc.getString( keyMessage );
if ( DialogModes.NO != app.playbackDisplayDialogs ) {
alert(messageStr);
}
rollItBack = true;
}
else if ( returnDesc.hasKey( keyTo ) ) {
changeInfo.modeObject = returnDesc.getObjectValue(keyTo);
changeInfo.modeClass = returnDesc.getObjectType(keyTo);
}
}
// check for cancel, error
if (rollItBack) {
app.activeDocument.activeHistoryState = historyState; // rollback state of document
return cancelFlag; // kill dialog box if cancel
}
return true;
}
function IndexToMode(modeIndex) {
var uiMode = 0;
switch (modeIndex) {
case 0: uiMode = DocumentMode.BITMAP; break;
case 1: uiMode = DocumentMode.GRAYSCALE; break;
case 2: uiMode = DocumentMode.DUOTONE; break;
case 3: uiMode = DocumentMode.INDEXEDCOLOR; break;
case 4: uiMode = DocumentMode.RGB; break;
case 5: uiMode = DocumentMode.CMYK; break;
case 6: uiMode = DocumentMode.LAB; break;
case 7: uiMode = DocumentMode.MULTICHANNEL; break;
}
return(uiMode);
}
function ClassToIndex(classMode) {
var uiMode = 0;
switch (classMode) {
case classBitmapMode: uiMode = 0; break;
case classGrayscaleMode: uiMode = 1; break;
case classDuotoneMode: uiMode = 2; break;
case classIndexedColorMode: uiMode = 3; break;
case classRGBColorMode: uiMode = 4; break;
case classCMYKColorMode: uiMode = 5; break;
case classLabColorMode: uiMode = 6; break;
case classMultichannelMode: uiMode = 7; break;
}
return(uiMode);
}
function ModeUIToClass(uiMode) {
var actionType = classNull;
switch (uiMode) {
case DocumentMode.BITMAP: actionType = classBitmapMode; break;
case DocumentMode.GRAYSCALE: actionType = classGrayscaleMode; break;
case DocumentMode.DUOTONE: actionType = classDuotoneMode; break;
case DocumentMode.INDEXEDCOLOR: actionType = classIndexedColorMode; break;
case DocumentMode.RGB: actionType = classRGBColorMode; break;
case DocumentMode.CMYK: actionType = classCMYKColorMode; break;
case DocumentMode.LAB: actionType = classLabColorMode; break;
case DocumentMode.MULTICHANNEL: actionType = classMultichannelMode; break;
}
return(actionType);
}
function CheckVersion() {
var numberArray = version.split(".");
if ( numberArray[0] < 9 ) {
if ( DialogModes.NO != app.playbackDisplayDialogs ) {
alert( strMustUse );
}
throw( strMustUse );
}
}
function FindDialog( inItem ) {
var w = inItem;
while ( 'dialog' != w.type ) {
if ( undefined == w.parent ) {
w = null;
break;
}
w = w.parent;
}
return w;
}
///////////////////////////////////////////////////////////////////////////////
// Function: ChangeInfoToDescriptor
// Usage: create an ActionDescriptor from the ChangeInfo JavaScript Object
// Input: ChangeInfo JavaScript Object (o)
// object unique string (s)
// Return: ActionDescriptor
// NOTE: We use the string id's here. They are mapped to the char id's.
///////////////////////////////////////////////////////////////////////////////
function ChangeInfoToDescriptor (o, s) {
var d = new ActionDescriptor;
d.putString( keyMessage, s );
var l = new ActionList;
if (o.flagBITMAP)
l.putEnumerated( typeSourceMode, enumUIBitmap );
if (o.flagGRAYSCALE)
l.putEnumerated( typeSourceMode, enumUIGrayscale );
if (o.flagDUOTONE)
l.putEnumerated( typeSourceMode, enumUIDuotone );
if (o.flagINDEXED)
l.putEnumerated( typeSourceMode, enumUIIndexed );
if (o.flagRGB)
l.putEnumerated( typeSourceMode, enumUIRGB );
if (o.flagCMYK)
l.putEnumerated( typeSourceMode, enumUICMYK );
if (o.flagLAB)
l.putEnumerated( typeSourceMode, enumUILab );
if (o.flagMULTICHANNEL)
l.putEnumerated( typeSourceMode, enumUIMultichannel );
if (l.count)
d.putList( keySourceMode, l );
if (o.modeObject instanceof ActionDescriptor)
d.putObject( keyDestinationMode, o.modeClass, o.modeObject );
else
d.putClass( keyDestinationMode, ModeUIToClass( o.destMode ) );
if (o.flatten != FLATTEN_UNUSED)
d.putBoolean( keyMerge, o.flatten );
return d;
}
///////////////////////////////////////////////////////////////////////////////
// Function: DescriptorToChangeInfo
// Usage: update a JavaScript Object from an ActionDescriptor
// Input: JavaScript Object (o), current object to update (output)
// Photoshop ActionDescriptor (d), descriptor to pull new params for object from
// object unique string (s)
// Return: Nothing, update is applied to passed in JavaScript Object (o)
///////////////////////////////////////////////////////////////////////////////
function DescriptorToChangeInfo (o, d, s) {
if ( d.hasKey(keyMessage) && ( s != d.getString(keyMessage) )) return;
if ( d.hasKey( keySourceMode ) ) {
// if the value is present it means true
// first we false out all the params
// then read in each one in the list
o.flagBITMAP = false;
o.flagGRAYSCALE = false;
o.flagDUOTONE = false;
o.flagINDEXED = false;
o.flagRGB = false;
o.flagCMYK = false;
o.flagLAB = false;
o.flagMULTICHANNEL = false;
var l = d.getList( keySourceMode );
var c = l.count;
for ( var i = 0; i < c; i++ ) {
switch ( l.getEnumerationValue( i ) ) {
case enumUIMultichannel: o.flagMULTICHANNEL = true; break;
case enumUILab: o.flagLAB = true; break;
case enumUICMYK: o.flagCMYK = true; break;
case enumUIRGB: o.flagRGB = true; break;
case enumUIIndexed: o.flagINDEXED = true; break;
case enumUIDuotone: o.flagDUOTONE = true; break;
case enumUIGrayscale: o.flagGRAYSCALE = true; break;
case enumUIBitmap: o.flagBITMAP = true; break;
}
}
}
if ( d.hasKey( keyMerge ) )
o.flatten = d.getBoolean( keyMerge );
if ( d.hasKey( keyDestinationMode ) ) {
if ( DescValueType.CLASSTYPE == d.getType( keyDestinationMode ) ) {
var targetClass = d.getClass( keyDestinationMode );
o.destinationMode = ClassToIndex( targetClass );
o.destMode = IndexToMode(o.destinationMode);
} else {
o.modeClass = d.getObjectType( keyDestinationMode );
o.modeObject = d.getObjectValue( keyDestinationMode );
o.destinationMode = ClassToIndex( o.modeClass );
o.destMode = IndexToMode(o.destinationMode);
}
}
}
///////////////////////////////////////////////////////////////////////////////
// Function: ChangeInfo
// Usage: object for holding the parameters
// Input:
// Return: object holding the mode change parameters
///////////////////////////////////////////////////////////////////////////////
function ChangeInfo() {
this.destinationMode = 5;
this.destMode = IndexToMode( this.destinationMode );
this.flagBITMAP = FLAG_BITMAP;
this.flagGRAYSCALE = FLAG_GRAYSCALE;
this.flagDUOTONE = FLAG_DUOTONE;
this.flagINDEXED = FLAG_INDEXED;
this.flagRGB = FLAG_RGB;
this.flagCMYK = FLAG_CMYK;
this.flagLAB = FLAG_LAB;
this.flagMULTICHANNEL = FLAG_MULTICHANNEL;
this.flatten = FLATTEN_UNUSED; // Flatten the image, start in unused state
// create these undefined
this.modeObject;
this.modeClass;
}
// Conditional Mode Change.jsx