Index was outside the bounds of the array when saving psb

Hello, I am updating the XMP metadata of a PSB file approximately 2.7GB in size. However, upon saving the file, I encountered the following error:
“System.IndexOutOfRangeException: Index was outside the bounds of the array.”
This issue does not occur when working with PSB files smaller than 1GB. Below, I’ve included the code and the complete stack trace of the error for reference.

Aspose.PSD version 24.11.0

private bool UpdateXmpMetadata(UpdateXmpMetadataMediaAction action)
{
    if (!string.IsNullOrEmpty(action.XmpMetadataMapping))
    {
        PsdImage img = null;

        // First attempt to load the PSD/PSB file
        try
        {
            using (var inputStream = File.OpenRead(action.Path))
            {
                img = (PsdImage)Image.Load(inputStream);
            }
        }
        catch (ImageLoadException e)
        {
            // Cannot suppport PSD/PSB files with Multichannel or Duotone color mode at this time due to known Aspose bug
            if (e.Message.ToLower().Contains("image") && e.InnerException.Message.ToLower().Contains("color mode") && e.InnerException.Message.ToLower().Contains("compression"))
            {
                throw new MediaEngineException("PSD/PSB files with Multichannel or Duotone color mode are not supported.", false);
            }
        }
        catch (Exception)
        {
            // Something unexpected went wrong while loading
            throw;
        }

        // Since we loaded successfully, process it
        using (img)
        {
            // Cannot suppport PSD/PSB files with Lab color mode which have 16 bits per channel at this time due to known Aspose bug
            if (img.ColorMode == ColorModes.Lab && img.BitsPerChannel == 16)
            {
                throw new MediaEngineException("PSD/PSB files with Lab color mode which have 16 bits per channel are not supported.", false);
            }

            // Cannot suppport PSD/PSB files with CMYK color mode which have less than 4 or more than 5 channels at this time due to known Aspose bug
            if (img.ColorMode == ColorModes.Cmyk && (img.ChannelsCount < 4 || img.ChannelsCount > 5))
            {
                throw new MediaEngineException("PSD/PSB files with CMYK color mode must have 4 or 5 channels.", false);
            }

            // Cannot suppport PSD/PSB files with RGB/Lab color mode which have less than 3 or more than 4 channels at this time due to known Aspose bug
            if ((img.ColorMode == ColorModes.Rgb || img.ColorMode == ColorModes.Lab) && (img.ChannelsCount < 3 || img.ChannelsCount > 4))
            {
                throw new MediaEngineException("PSD/PSB files with RGB/Lab color must have 3 or 4 channels.", false);
            }

            XDocument xmpMapping = XDocument.Parse(action.XmpMetadataMapping);

            // Getting the xmp metadata
            XmpPacketWrapper xmpData = img.XmpData;

            if (xmpData == null)
            {
                // Create xmp metadata if the image doesn't contains any xmp data.
                XmpHeaderPi xmpHeader = new XmpHeaderPi(Guid.NewGuid().ToString());
                XmpTrailerPi xmpTrailer = new XmpTrailerPi(true);
                XmpMeta xmpMeta = new XmpMeta();

                xmpData = new XmpPacketWrapper(xmpHeader, xmpTrailer, xmpMeta);
                img.XmpData = xmpData;
            }

            foreach (var mapping in xmpMapping.Descendants("xmpMapping").Elements("add"))
            {
                var xmpNamespace = mapping.Attribute("namespace").Value;
                var xmpName = mapping.Attribute("name").Value;
                var xmpPrefix = mapping.Attribute("prefix").Value;
                var xmpValue = mapping.Value;

                if (xmpData.ContainsPackage(xmpNamespace))
                {
                    // Update or add XMP property value in existing namespace
                    foreach (var xmpPackage in xmpData.Packages)
                    {
                        if (xmpPackage.NamespaceUri.Trim().ToLower() == xmpNamespace.Trim())
                        {
                            if (xmpPackage.ContainsKey(xmpPackage.Prefix + ":" + xmpName))
                            {
                                xmpPackage[(xmpPackage.Prefix + ":" + xmpName)] = xmpValue;
                            }
                            else
                            {
                                xmpPackage.AddValue(xmpPackage.Prefix + ":" + xmpName, xmpValue);
                            }
                        }
                    }
                }
                else
                {
                    // Create XMP namespace, since it does not yet exist
                    XmpBasicPackage xmp = new XmpBasicPackage(xmpPrefix, xmpNamespace);
                    xmp.AddValue(xmpPrefix + ":" + xmpName, xmpValue);
                    xmpData.AddPackage(xmp);
                }
            }

            img.Save(action.OutputPath);
        }

        return true;
    }

    return false;
}
Adam.Core.MediaEngines.MediaEngineException: Action UpdateXmpMetadata failed to execute using all engines. The last engine (AsposePsd) failed with error "Index was outside the bounds of the array.". ---> System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at Aspose.PSD.FileFormats.Psd.Layers.ChannelInformation.(Byte[] , Size , Rectangle )
   at    ..(Dictionary`2 , Size , Rectangle )
   at    ..Process(Rectangle , Int32[] , Point , Point )
   at    ..  ​ ​(Rectangle )
   at .(   , IList`1 ,    )
   at .(Rectangle ,    ,  , Int32 , Int32 ,    )
   at .(Rectangle ,    ,    )
   at  .(Object )
   at  .(MethodBase , Boolean )
   at  .()
   at  .(Boolean )
   at  .(Object )
   at  .()
   at  .(Object , UInt32 )
   at  .(Boolean )
   at  .(Object[] , Type[] , Type[] , Object[] )
   at    .LoadPartialArgb32Pixels(Rectangle , IPartialArgb32PixelLoader )
   at    .  ​ ​(Rectangle )
   at .(   , IList`1 ,    )
   at .(Rectangle ,    ,  , Int32 , Int32 ,    )
   at    .   ​ ​(Rectangle , IPartialArgb32PixelLoader )
   at    .(Int32 , IColorPalette ,     , Int32 )
   at    .(StreamContainer , Int32 , IColorPalette ,     , Int32 )
   at Aspose.PSD.FileFormats.Psd.PsdImage.SaveData(Stream stream)
   at Aspose.PSD.DataStreamSupporter.Save(Stream stream)
   at Aspose.PSD.DataStreamSupporter.Save(String filePath)
   at Adam.Core.MediaEngines.AsposePsdMediaEngine.UpdateXmpMetadata(UpdateXmpMetadataMediaAction action)
   at Adam.Core.MediaEngines.MediaManager.RunAction(MediaAction action, IMediaEngine engine, Exception& exception)
   --- End of inner exception stack trace ---
   at Adam.Core.MediaEngines.MediaManager.LogActionFailure(MediaAction action, IMediaEngine lastFailedEngine, Exception lastException)
   at Adam.Core.MediaEngines.MediaManager.RunInternal(IEnumerable`1 engines, IEnumerable`1 actions)
   at Adam.Core.Orders.UpdateXmpMetadataOrderTargetAction.OnExecute()
   at Adam.Core.Orders.OrderRunner.ExecuteRegisteredActions()

Here is the test file
https://drive.google.com/file/d/10Jbf4nEFWd6zRCbiPbYghBUyC0sP3JY7/view?usp=sharing

@3stan

The error you are encountering, “System.IndexOutOfRangeException: Index was outside the bounds of the array,” when saving a large PSB file (approximately 2.7GB) is likely related to known limitations or bugs in the Aspose.PSD library when handling large files or specific color modes.

Here are a few steps you can take to troubleshoot and potentially resolve the issue:

  1. Check Color Modes: Ensure that the PSB file does not use unsupported color modes. The Aspose.PSD library has known limitations with certain color modes, such as:

    • Multichannel or Duotone color modes.
    • Lab color mode with 16 bits per channel.
    • CMYK color mode with less than 4 or more than 5 channels.
    • RGB or Lab color modes with less than 3 or more than 4 channels.

    If your PSB file falls into any of these categories, you may need to convert it to a supported format before processing.

  2. Update Aspose.PSD Library: Ensure that you are using the latest version of the Aspose.PSD library. Updates often include bug fixes and improvements that may resolve your issue.

  3. Reduce File Size: If possible, try to work with a smaller version of the PSB file to see if the issue persists. This can help determine if the problem is related to file size.

  4. Contact Support: If the issue continues, consider reaching out to Aspose support with the details of your problem, including the stack trace and the specific PSB file you are working with. They may have more insights or a workaround for this specific error.

  5. Monitor for Updates: Keep an eye on the Aspose forums or issue tracking system for any updates related to this error. There may be ongoing investigations or fixes being developed for similar issues.

If you have further questions or need additional assistance, feel free to ask!

Color mode is RGB and it does not fall in any category above

@3stan

We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.

Please don’t delete file this week. Aspose.PSD team needs time to download and investigate this file.

Issue ID(s): PSDNET-2288

You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.

1 Like

@Dmitriy.Sorokin

Any updates on the issue or any leads with the investigation if there are any workaround with this issue? Thanks

@3stan were made preliminary investigation, we were not able to reproduce it, so we will continue work on it on different configurations. Could you please check if the issue is reproducable on 24.12?

@Dmitriy.Sorokin

We’ve tried the version 24.12 which is the latest however, we are still encountering this kind of error.

Adam.Core.MediaEngines.MediaEngineException: Action UpdateXmpMetadata failed to execute using all engines. The last engine (AsposePsd) failed with error "Index was outside the bounds of the array.". ---> System.IndexOutOfRangeException: Index was outside the bounds of the array. at Aspose.PSD.FileFormats.Psd.Layers.ChannelInformation.(Byte[] , Size , Rectangle ) at ..(Dictionary2 , Size , Rectangle ) at …Process(Rectangle , Int32[] , Point , Point ) at … (Rectangle ) at .( , IList1 , ) at .(Rectangle , , , Int32 , Int32 , ) at .(Rectangle , , ) at .(Object ) at .(MethodBase , Boolean ) at .() at .(Boolean ) at .(Object ) at .() at .(Object , UInt32 ) at .(Boolean ) at .(Object[] , Type[] , Type[] , Object[] ) at .LoadPartialArgb32Pixels(Rectangle , IPartialArgb32PixelLoader ) at . (Rectangle ) at .( , IList1 , ) at .(Rectangle , , , Int32 , Int32 , ) at . (Rectangle , IPartialArgb32PixelLoader ) at .(Int32 , IColorPalette , , Int32 ) at .(StreamContainer , Int32 , IColorPalette , , Int32 ) at Aspose.PSD.FileFormats.Psd.PsdImage.SaveData(Stream stream) at Aspose.PSD.DataStreamSupporter.Save(Stream stream) at Aspose.PSD.DataStreamSupporter.Save(String filePath) at Adam.Core.MediaEngines.AsposePsdMediaEngine.UpdateXmpMetadata(UpdateXmpMetadataMediaAction action) at Adam.Core.MediaEngines.MediaManager.RunAction(MediaAction action, IMediaEngine engine, Exception& exception) — End of inner exception stack trace — at Adam.Core.MediaEngines.MediaManager.LogActionFailure(MediaAction action, IMediaEngine lastFailedEngine, Exception lastException) at Adam.Core.MediaEngines.MediaManager.RunInternal(IEnumerable1 engines, IEnumerable1 actions) at Adam.Core.Orders.UpdateXmpMetadataOrderTargetAction.OnExecute() at Adam.Core.Orders.OrderRunner.ExecuteRegisteredActions()`

Also, We’ve noticed that the execution time of Saving the PSD took around 13 mins to process for 2GB PSB file.

@3stan I can confirm the issue. At this moment, planned release with fixes is 25.02.

@Dmitriy.Sorokin

Thank you. Appreciate your help

Hi,

Can you possibly confirm the timeline 25.2 is to become available, our estimate at the moment is that its likely to be early March giving previous cadence of releases?

Is there any possibility to move this fix up to 25.1 at all, this issue is causing a major customer impact and obviously a February timeline would be much better than a March one (if that is correct).

Appreciate the help.

Kind Regards

Dan.

@DJCWanderer could you please provide input file and minimum required code to reproduce the issue. Your case can be different from the case of topic starter. Release 25.1 is already published. Release 25.2 is planned on the 20th of February estimately.

@Dmitriy.Sorokin

We’ve observed that the issue occurs when writing XMP to the file and then saving it. However, if XMP is not written back to the file, the save operation is successful. I’ve created a simplified code snippet that writes an XMP and then saves the file.

public void WriteXMP(string filePath)
{
    try
    {

        string stringXmp = "<xmpMapping><add namespace=\"http://purl.org/dc/elements/1.1/\" prefix=\"dc\" name=\"summary\">\"Test\"</add></xmpMapping>";
        
        Stopwatch stopwatch = new Stopwatch();
        stopwatch.Start();

        XDocument xmpMapping = XDocument.Parse(stringXmp);

        using (img)
        {
            Console.WriteLine("Checking for existing XMP Data");
            XmpPacketWrapper xmpData = img.XmpData;

            if (xmpData == null)
            {
                Console.WriteLine("Writing new XMP Data");

                // Create xmp metadata if the image doesn't contains any xmp data.
                XmpHeaderPi xmpHeader = new XmpHeaderPi(Guid.NewGuid().ToString());
                XmpTrailerPi xmpTrailer = new XmpTrailerPi(true);
                XmpMeta xmpMeta = new XmpMeta();

                xmpData = new XmpPacketWrapper(xmpHeader, xmpTrailer, xmpMeta);
                img.XmpData = xmpData;
            }

            Console.WriteLine("Writing XMP Data");
            foreach (var mapping in xmpMapping.Descendants("xmpMapping").Elements("add"))
            {
                var xmpNamespace = mapping.Attribute("namespace").Value;
                var xmpName = mapping.Attribute("name").Value;
                var xmpPrefix = mapping.Attribute("prefix").Value;
                var xmpValue = mapping.Value;

                if (xmpData.ContainsPackage(xmpNamespace))
                {
                    // Update or add XMP property value in existing namespace
                    foreach (var xmpPackage in xmpData.Packages)
                    {
                        if (xmpPackage.NamespaceUri.Trim().ToLower() == xmpNamespace.Trim())
                        {
                            if (xmpPackage.ContainsKey(xmpPackage.Prefix + ":" + xmpName))
                            {
                                xmpPackage[(xmpPackage.Prefix + ":" + xmpName)] = xmpValue;
                            }
                            else
                            {
                                xmpPackage.AddValue(xmpPackage.Prefix + ":" + xmpName, xmpValue);
                            }
                        }
                    }
                }
                else
                {
                    // Create XMP namespace, since it does not yet exist
                    XmpBasicPackage xmp = new XmpBasicPackage(xmpPrefix, xmpNamespace);
                    xmp.AddValue(xmpPrefix + ":" + xmpName, xmpValue);
                    xmpData.AddPackage(xmp);
                }
            }

            Console.WriteLine("Saving File..");

            img.Save(filePath);
            stopwatch.Stop();
            Console.WriteLine($"Elapsed Time: {stopwatch.Elapsed} (hh:mm:ss:ms)");
            Console.WriteLine("Saving Done");
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
    }
}

You can used the file from my previous post as it is still available and this code used the latest 25.1

I know this is a free support but can you please give us any updates on your findings after this since we also need to give an update to our customer.

Thanks,
Mark

@3stan team works on this issue. At this moment “Index Out of Range” exception is fixed, also speed of processing improved, but the final file can not be opened with PS. The work continues.

@Dmitriy.Sorokin

May I know the target release and release date when the issue will be fix?

@3stan it’s still planned on 25.2, but in the worst case release of this feature will be moved to 25.3

@Dmitriy.Sorokin

Thank you for the update.

@Dmitriy.Sorokin

We really need this in 25.2 because of its impact on our customers. If it doesn’t make it in time, would your team be able to patch it on top of 25.2?

@3stan team is actively work on this task. But I can not guarantee that it will be fixed in the top of February.

@Dmitriy.Sorokin

Any updates on the fix? Are the fix can still make it on 25.2 release? We need to get the updates on the progress as we also need to update our customer.

Thanks

@3stan the issue was more complex. At this moment the issue with saving of files larger than 2gb is fixed. Also, rendering of masks were optimized. The fix should be presented in 25.2