Ejemplo n.º 1
0
        public static void CreateDocument(int pixelwidth, int pixelheight, int ppi, int fill, int mode, string name)
        {
            System.Diagnostics.Debug.Assert(pixelwidth > 0);
            System.Diagnostics.Debug.Assert(pixelheight > 0);
            System.Diagnostics.Debug.Assert(ppi > 0);
            //PSX.CheckEnum( mode, (int) con.phClassRGBColorMode );
            PSX.CheckEnum(fill, (int)con.phEnumTransparent, (int)con.phEnumBackgroundColor, (int)con.phEnumWhite);


            // Creates a new document


            // Create Desc2
            var Desc2 = PSX.MakeNewDescriptor();

            Desc2.PutString((int)con.phKeyName, name);
            Desc2.PutClass((int)con.phKeyMode, mode);
            Desc2.PutUnitDouble((int)con.phKeyWidth, (int)con.phUnitDistance, pixelwidth);
            Desc2.PutUnitDouble((int)con.phKeyHeight, (int)con.phUnitDistance, pixelheight);
            Desc2.PutUnitDouble((int)con.phKeyResolution, (int)con.phUnitDensity, ppi);
            Desc2.PutEnumerated((int)con.phKeyFill, (int)con.phTypeFill, fill);

            // Create Desc1
            PhotoshopTypeLibrary.IActionDescriptor Desc1 = PSX.MakeNewDescriptor();
            Desc1.PutObject((int)con.phKeyNew, (int)con.phClassDocument, Desc2);


            int old_count = DocumentAPI.GetDocumentCount();

            // Play the Event Into Photoshop
            PSX.PlayEvent((int)con.phEventMake, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checknone);

            DocumentAPI.CheckDocumentCount(old_count + 1);
        }
Ejemplo n.º 2
0
        public static void CreateLayer(string layer_name)
        {
            PSX.CheckStringContents(layer_name);

            // Desc2
            var Desc2 = PSX.MakeNewDescriptor();

            Desc2.PutString((int)con.phKeyName, layer_name);

            // Ref1
            var Ref1 = PSX.MakeNewReference();

            Ref1.PutClass((int)con.phClassLayer);

            // Desc1
            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutReference((int)con.phKeyNull, Ref1);
            Desc1.PutBoolean(PSX.StrToID("below"), PSX.FALSE);
            Desc1.PutObject((int)con.phKeyUsing, (int)con.phClassLayer, Desc2);

            int old_layer_count = LayerAPI.GetLayerCount(-1);

            // Play the event in photoshop
            PSX.PlayEvent((int)con.phEventMake, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checkresult);

            LayerAPI.CheckLayerCount(-1, old_layer_count + 1);
        }
Ejemplo n.º 3
0
        public static void CreateSolidColorFillLayer(string layer_name, int red, int green, int blue)
        {
            // Desc4
            var Desc4 = PSX.CreateDescriptorForRGBColor(red, green, blue);

            // Desc3
            var Desc3 = PSX.MakeNewDescriptor();

            Desc3.PutObject((int)con.phKeyColor, (int)con.phClassRGBColor, Desc4);

            // Desc2
            var Desc2 = PSX.MakeNewDescriptor();

            Desc2.PutString((int)con.phKeyName, layer_name);
            Desc2.PutObject((int)con.phKeyType, PSX.StrToID("solidColorLayer"), Desc3);

            // Ref1
            var Ref1 = PSX.MakeNewReference();

            Ref1.PutClass(PSX.StrToID("contentLayer"));

            // Desc1
            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutReference((int)con.phKeyNull, Ref1);
            Desc1.PutObject((int)con.phKeyUsing, PSX.StrToID("contentLayer"), Desc2);

            // Play the event in photoshop
            PSX.PlayEvent((int)con.phEventMake, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checkresult);
        }
Ejemplo n.º 4
0
        public static void InvertSelection( )
        {
            var Desc1 = PSX.MakeNewDescriptor();

            // Play the event in photoshop
            PSX.PlayEvent((int)con.phEventInverse, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checkresult);
        }
Ejemplo n.º 5
0
        public static void Paste()
        {
            /*
             * System.Windows.Forms.IDataObject ido = System.Windows.Forms.Clipboard.GetDataObject();
             *
             * if (ido!=null)
             * {
             *
             *
             *      string [] formats = ido.GetFormats();
             *      foreach (string s in formats)
             *      {
             *              System.Console.WriteLine( "FMT {0}",s );
             *      }
             * }
             *
             */

            // Desc1
            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutEnumerated((int)con.phKeyAntiAlias, (int)con.phTypeAntiAlias, (int)con.phEnumAntiAliasNone);

            // Play the event in photoshop
            PSX.PlayEvent((int)con.phEventPaste, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checkresult);
        }
Ejemplo n.º 6
0
        public static void DuplicateDocument(string new_name, bool merge_layers)
        {
            System.Diagnostics.Debug.Assert(new_name.Length > 0);

            // Ref1
            var Ref1 = PSX.MakeNewReference();

            Ref1.PutEnumerated((int)con.phClassDocument, (int)con.phTypeOrdinal, (int)con.phEnumFirst);

            // Desc1
            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutReference((int)con.phKeyNull, Ref1);
            Desc1.PutString((int)con.phKeyName, new_name);

            if (merge_layers)
            {
                Desc1.PutBoolean((int)con.phKeyMerged, PSX.TRUE);
            }
            else
            {
                Desc1.PutBoolean((int)con.phKeyMerged, PSX.FALSE);
            }

            int old_count = DocumentAPI.GetDocumentCount();

            // Play the event in photoshop
            PSX.PlayEvent((int)con.phEventDuplicate, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checkresult);

            DocumentAPI.CheckDocumentCount(old_count + 1);
        }
Ejemplo n.º 7
0
        public static void eventSave()
        {
            var Desc1 = PSX.MakeNewDescriptor();

            // Play the event in photoshop
            PSX.PlayEvent((int)con.phEventSave, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checknone);
        }
Ejemplo n.º 8
0
        public static PhotoshopTypeLibrary.IActionDescriptor CreateDescriptorForRGBColor(System.Drawing.Color C)
        {
            var Desc = PSX.MakeNewDescriptor();

            Desc.PutDouble((int)con.phKeyRed, C.R);
            Desc.PutDouble((int)con.phKeyGrain, C.G);
            Desc.PutDouble((int)con.phKeyBlue, C.B);
            return(Desc);
        }
Ejemplo n.º 9
0
        static public PhotoshopTypeLibrary.IActionDescriptor CreateOpacityStop(double percent, int location, int midpoint)
        {
            var OpacityDesc = PSX.MakeNewDescriptor();

            OpacityDesc.PutUnitDouble((int)con.phKeyOpacity, (int)con.phUnitPercent, percent);
            OpacityDesc.PutInteger((int)con.phKeyLocation, location);
            OpacityDesc.PutInteger((int)con.phKeyMidpoint, midpoint);
            return(OpacityDesc);
        }
Ejemplo n.º 10
0
        public static PhotoshopTypeLibrary.IActionDescriptor CreateDescriptorForRGBColor(int red, int green, int blue)
        {
            var Desc = PSX.MakeNewDescriptor();

            Desc.PutDouble((int)con.phKeyRed, red);
            Desc.PutDouble((int)con.phKeyGrain, green);
            Desc.PutDouble((int)con.phKeyBlue, blue);
            return(Desc);
        }
Ejemplo n.º 11
0
        public static PhotoshopTypeLibrary.IActionDescriptor CreateDescriptorForRectangle(System.Drawing.Rectangle r)
        {
            var Desc = PSX.MakeNewDescriptor();

            Desc.PutUnitDouble((int)con.phKeyTop, (int)con.phUnitDistance, r.Top);
            Desc.PutUnitDouble((int)con.phKeyLeft, (int)con.phUnitDistance, r.Left);
            Desc.PutUnitDouble((int)con.phKeyBottom, (int)con.phUnitDistance, r.Bottom);
            Desc.PutUnitDouble((int)con.phKeyRight, (int)con.phUnitDistance, r.Right);
            return(Desc);
        }
Ejemplo n.º 12
0
        public static PhotoshopTypeLibrary.IActionDescriptor CreateDescriptorForRectangle(int left, int top, int right, int bottom)
        {
            var Desc = PSX.MakeNewDescriptor();

            Desc.PutUnitDouble((int)con.phKeyTop, (int)con.phUnitDistance, top);
            Desc.PutUnitDouble((int)con.phKeyLeft, (int)con.phUnitDistance, left);
            Desc.PutUnitDouble((int)con.phKeyBottom, (int)con.phUnitDistance, bottom);
            Desc.PutUnitDouble((int)con.phKeyRight, (int)con.phUnitDistance, right);
            return(Desc);
        }
Ejemplo n.º 13
0
        static public PhotoshopTypeLibrary.IActionDescriptor CreateColorStop(System.Drawing.Color c, int location, int midpoint)
        {
            var Desc5 = PSX.MakeNewDescriptor();

            Desc5.PutObject((int)con.phKeyColor, (int)con.phClassRGBColor, PSX.CreateDescriptorForRGBColor(c));
            Desc5.PutEnumerated((int)con.phKeyType, (int)con.phTypeColorStopType, (int)con.phEnumUserStop);
            Desc5.PutInteger((int)con.phKeyLocation, location);
            Desc5.PutInteger((int)con.phKeyMidpoint, midpoint);
            return(Desc5);
        }
Ejemplo n.º 14
0
        static public void CreateGradientFillLayer(string layer_name, int gradient_type, double angle, PhotoshopTypeLibrary.IActionDescriptor [] opacity_stops, PhotoshopTypeLibrary.IActionDescriptor [] color_stops)
        {
            PSX.CheckRange(angle, 0, 360);
            PSX.CheckEnum(gradient_type, (int)con.phEnumLinear, (int)con.phEnumRadial);
            string gradient_name = "Custom Gradient";

            // List2
            var List2 = PSX.MakeNewList();

            PSX.AddDescriptorsToList(List2, opacity_stops, (int)con.phClassTransparencyStop);

            // List1
            var List1 = PSX.MakeNewList();

            PSX.AddDescriptorsToList(List1, color_stops, (int)con.phClassColorStop);

            // Desc4
            var Desc4 = PSX.MakeNewDescriptor();


            Desc4.PutString((int)con.phKeyName, gradient_name);
            Desc4.PutEnumerated(1198679110, (int)con.phTypeGradientForm, (int)con.phEnumCustomStops);
            Desc4.PutDouble((int)con.phKeyInterfaceIconFrameDimmed, 4096);
            Desc4.PutList((int)con.phKeyColors, List1);
            Desc4.PutList((int)con.phKeyTransparency, List2);

            // Desc3
            var Desc3 = PSX.MakeNewDescriptor();


            Desc3.PutUnitDouble((int)con.phKeyAngle, (int)con.phUnitAngle, angle);
            Desc3.PutEnumerated((int)con.phKeyType, (int)con.phTypeGradientType, gradient_type);
            Desc3.PutObject((int)con.phKeyGradient, (int)con.phClassGradient, Desc4);

            // Desc2
            var Desc2 = PSX.MakeNewDescriptor();


            Desc2.PutString((int)con.phKeyName, layer_name);
            Desc2.PutObject((int)con.phKeyType, PSX.StrToID("gradientLayer"), Desc3);

            // Ref1
            var Ref1 = PSX.MakeNewReference();

            Ref1.PutClass(PSX.StrToID("contentLayer"));

            // Desc1
            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutReference((int)con.phKeyNull, Ref1);
            Desc1.PutObject((int)con.phKeyUsing, PSX.StrToID("contentLayer"), Desc2);

            // Play the event in photoshop
            PSX.PlayEvent((int)con.phEventMake, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checkresult);
        }
Ejemplo n.º 15
0
        public static void GaussianBlur(double radius)
        {
            PSX.CheckRange(radius, 0, 250);

            // Desc1
            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutUnitDouble((int)con.phKeyRadius, (int)con.phUnitPixels, radius);

            // Play the event in photoshop
            PSX.PlayEvent((int)con.phEventGaussianBlur, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checkresult);
        }
Ejemplo n.º 16
0
        public static void DeleteLayer(int layer_index)
        {
            // Ref1
            PhotoshopTypeLibrary.IActionReference Ref1 = LayerAPI.GetReferenceToLayerByIndex(layer_index);

            // Desc1
            PhotoshopTypeLibrary.IActionDescriptor Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutReference((int)con.phKeyNull, Ref1);

            // Play the event in photoshop
            PSX.PlayEvent((int)con.phEventDelete, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checkresult);
        }
Ejemplo n.º 17
0
        public static void RasterizeLayer(int layer_index)
        {
            // Ref1
            var Ref1 = LayerAPI.GetReferenceToLayerByIndex(layer_index);

            // Desc1
            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutReference((int)con.phKeyNull, Ref1);

            // Play the event in photoshop
            PSX.PlayEvent(PSX.StrToID("rasterizeLayer"), Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checkresult);
        }
Ejemplo n.º 18
0
        public static void SetColorEx(int color_id, int color_class, double [] v)
        {
            var Desc2 = PSX.MakeNewDescriptor();

            if (color_class == (int)con.phClassHSBColor)
            {
                Desc2.PutUnitDouble((int)con.phKeyHue, (int)con.phUnitAngle, v[0]);
                Desc2.PutDouble((int)con.phKeySaturation, v[1]);
                Desc2.PutDouble((int)con.phKeyBrightness, v[2]);
            }
            else if (color_class == (int)con.phClassRGBColor)
            {
                Desc2.PutDouble((int)con.phKeyRed, v[0]);
                Desc2.PutDouble((int)con.phKeyGrain, v[1]);
                Desc2.PutDouble((int)con.phKeyBlue, v[2]);
            }
            else if (color_class == (int)con.phClassLabColor)
            {
                Desc2.PutDouble((int)con.phKeyLuminance, v[0]);
                Desc2.PutDouble((int)con.phKeyA, v[1]);
                Desc2.PutDouble((int)con.phKeyB, v[2]);
            }
            else if (color_class == (int)con.phClassCMYKColor)
            {
                Desc2.PutDouble((int)con.phKeyCyan, v[0]);
                Desc2.PutDouble((int)con.phKeyMagenta, v[1]);
                Desc2.PutDouble((int)con.phKeyYellow, v[2]);
                Desc2.PutDouble((int)con.phKeyBlack, v[3]);
            }
            else
            {
                var e = new Photoshop6OM.PhotoshoProxyError("Improper Color Class");
                throw e;
            }

            var Ref1 = PSX.MakeNewReference();

            Ref1.PutProperty((int)con.phClassColor, color_id);

            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutReference((int)con.phKeyNull, Ref1);
            Desc1.PutObject((int)con.phKeyTo, color_class, Desc2);


            // ----------------------------------------
            // Play the event
            // ----------------------------------------
            PSX.PlayEvent((int)con.phEventSet, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checkresult);
        }
Ejemplo n.º 19
0
        public static void SelectLayer( )
        {
            // Ref1
            var Ref1 = PSX.MakeNewReference();

            Ref1.PutEnumerated((int)con.phClassChannel, (int)con.phTypeChannel, (int)con.phEnumMask);

            // Desc1
            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutReference((int)con.phKeyNull, Ref1);

            // Play the event in photoshop
            PSX.PlayEvent((int)con.phEventSelect, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checknone);
        }
Ejemplo n.º 20
0
        public static void AddNoise(int distortion, double amount, int monochromatic)
        {
            PSX.CheckEnum(distortion, (int)con.phEnumUniformDistribution, (int)con.phEnumGaussianDistribution);
            PSX.CheckRange(amount, 0, 400);
            PSX.CheckEnum(monochromatic, PSX.TRUE, PSX.FALSE);
            // Desc1
            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutEnumerated((int)con.phKeyDistortion, (int)con.phTypeDistribution, distortion);
            Desc1.PutUnitDouble((int)con.phKeyNoise, (int)con.phUnitPercent, amount);
            Desc1.PutBoolean((int)con.phKeyMonochromatic, monochromatic);

            // Play the event in photoshop
            PSX.PlayEvent((int)con.phEventAddNoise, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checkresult);
        }
Ejemplo n.º 21
0
        private static void __SetSelection(int item_to_select)
        {
            // Ref1
            var Ref1 = PSX.MakeNewReference();

            Ref1.PutProperty((int)con.phClassChannel, 1718838636);

            // Desc1
            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutReference((int)con.phKeyNull, Ref1);
            Desc1.PutEnumerated((int)con.phKeyTo, (int)con.phTypeOrdinal, item_to_select);

            // Play the event in photoshop
            PSX.PlayEvent((int)con.phEventSet, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checkresult);
        }
Ejemplo n.º 22
0
        public static void UnsharpMask(double amount, double radius, int threshold)
        {
            PSX.CheckRange(amount, 0, 400);
            PSX.CheckRange(radius, 0, 250);
            PSX.CheckRange(threshold, 0, 255);

            // Desc1
            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutUnitDouble((int)con.phKeyAmount, (int)con.phUnitPercent, amount);
            Desc1.PutUnitDouble((int)con.phKeyRadius, (int)con.phUnitPixels, radius);
            Desc1.PutInteger((int)con.phKeyThreshold, threshold);

            // Play the event in photoshop
            PSX.PlayEvent((int)con.phEventUnsharpMask, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checkresult);
        }
Ejemplo n.º 23
0
        public static void ExitQuickMaskMode()
        {
            // Ref1
            var Ref1 = PSX.MakeNewReference();

            Ref1.PutProperty((int)con.phClassProperty, (int)con.phKeyQuickMask);
            Ref1.PutEnumerated((int)con.phClassDocument, (int)con.phTypeOrdinal, (int)con.phEnumTarget);

            // Desc1
            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutReference((int)con.phKeyNull, Ref1);

            // Play the event in photoshop
            PSX.PlayEvent((int)con.phEventClear, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checkresult);
        }
Ejemplo n.º 24
0
        public static void SaveAsPSD(string filename, bool save_as_copy)
        {
            // Desc1
            _start_save(filename);

            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutClass((int)con.phKeyAs, (int)con.phClassPhotoshop35Format);
            Desc1.PutPath((int)con.phKeyIn, filename);
            if (save_as_copy)
            {
                Desc1.PutBoolean((int)con.phKeyCopy, PSX.TRUE);
                Desc1.PutBoolean((int)con.phKeyLayers, PSX.FALSE);
            }

            _end_save(filename, Desc1);
        }
Ejemplo n.º 25
0
        public static void __SetAppColor(int color_id, PhotoshopTypeLibrary.IActionDescriptor RGBCOLORDESC)
        {
            PSX.CheckEnum(color_id, (int)con.phKeyForegroundColor, (int)con.phKeyBackgroundColor);

            // Ref1
            var Ref1 = PSX.MakeNewReference();

            Ref1.PutProperty((int)con.phClassColor, color_id);

            // Desc1
            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutReference((int)con.phKeyNull, Ref1);
            Desc1.PutObject((int)con.phKeyTo, (int)con.phClassRGBColor, RGBCOLORDESC);

            // Play the event in photoshop
            PSX.PlayEvent((int)con.phEventSet, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checknone);
        }
Ejemplo n.º 26
0
        public static void CloseDocument()
        {
            // NOTE: Those closes without prompting for save

            System.Diagnostics.Debug.Assert(DocumentAPI.GetDocumentCount() > 0);

            // Desc1
            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutEnumerated((int)con.phKeySaving, (int)con.phTypeYesNo, (int)con.phEnumNo);

            int old_count = DocumentAPI.GetDocumentCount();

            // Play the event in photoshop
            PSX.PlayEvent((int)con.phEventClose, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checknone);

            DocumentAPI.CheckDocumentCount(old_count - 1);
        }
Ejemplo n.º 27
0
        public static void SaveCopyAsPNG(string filename, int interlace)
        {
            _start_save(filename);
            PSX.CheckEnum(interlace, (int)con.phEnumPNGInterlaceNone, (int)con.phEnumPNGInterlaceAdam7);

            // Desc2
            var Desc2 = PSX.MakeNewDescriptor();

            Desc2.PutEnumerated((int)con.phKeyPNGInterlaceType, (int)con.phTypePNGInterlaceType, interlace);
            Desc2.PutEnumerated((int)con.phKeyPNGFilter, (int)con.phTypePNGFilter, (int)con.phEnumPNGFilterAdaptive);

            // Desc1
            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutObject((int)con.phKeyAs, (int)con.phClassPNGFormat, Desc2);
            Desc1.PutPath((int)con.phKeyIn, filename);
            Desc1.PutBoolean((int)con.phKeyCopy, PSX.TRUE);

            _end_save(filename, Desc1);
        }
Ejemplo n.º 28
0
        public static void Copy()
        {
            var Desc1 = PSX.MakeNewDescriptor();

            // Play the event in photoshop
            PSX.PlayEvent((int)con.phEventCopy, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checkresult);

            System.Windows.Forms.IDataObject ido = System.Windows.Forms.Clipboard.GetDataObject();
            if (ido == null)
            {
                var e = new Photoshop6OM.PhotoshoProxyError("IDO failed");
                throw e;
            }

            string [] formats = ido.GetFormats();
            foreach (string format in formats)
            {
                System.Console.WriteLine("F: {0}", format);
            }
        }
Ejemplo n.º 29
0
        private static void __SelectShape(int left, int top, int right, int bottom, int shape, bool anti_alias, int action_event)
        {
            // WORKITEM: Support con.phEventIntersectWith as the action_event

            // Desc2
            var Desc2 = PSX.CreateDescriptorForRectangle(left, top, right, bottom);

            // Ref1
            var Ref1 = PSX.MakeNewReference();

            Ref1.PutProperty((int)con.phClassChannel, 1718838636);

            // Desc1
            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutReference((int)con.phKeyNull, Ref1);
            Desc1.PutObject((int)con.phKeyTo, shape, Desc2);
            Desc1.PutBoolean((int)con.phKeyAntiAlias, PSX.int_from_bool(anti_alias));

            // Play the event in photoshop
            PSX.PlayEvent(action_event, Desc1, (int)con.phDialogSilent, PSX.PlayBehavior.checkresult);
        }
Ejemplo n.º 30
0
        public static void SaveCopyAsJPEG(string filename, int quality)
        {
            // WORKITEM support matte color

            _start_save(filename);

            PSX.CheckRange(quality, 0, 12);

            // Desc2
            var Desc2 = PSX.MakeNewDescriptor();

            Desc2.PutInteger((int)con.phKeyExtendedQuality, quality);

            // Desc1
            var Desc1 = PSX.MakeNewDescriptor();

            Desc1.PutObject((int)con.phKeyAs, (int)con.phClassJPEGFormat, Desc2);
            // WORKITEM what if they only provided a path
            Desc1.PutPath((int)con.phKeyIn, filename);
            Desc1.PutBoolean((int)con.phKeyCopy, PSX.TRUE);

            _end_save(filename, Desc1);
        }