4
Vote

Throw more descriptive error message in CheckSufficientMemory

description

The simple "Out of memory" error confuses people.
So please add to the message the amount of available ram and the needed ram to get the psd file in memory. This would help a lot to support them in case of this error.

file attachments

comments

jimshaw wrote Jul 14, 2015 at 4:12 AM

I created this patch to PsdLoad.cs which flattens all the layers in the psd when there's not enough ram to load all the layers (motivation, I was sent a psd file with ~500 layers which would need 80Gb of memory to load)

@@ -52,10 +52,33 @@ public static Document Load(System.IO.Stream input)
     psdFile.VerifyLayerSections();
     ApplyLayerSections(psdFile.Layers);
  • var pdnLayers = psdFile.Layers.AsParallel().AsOrdered()
  • .Select(psdLayer => psdLayer.DecodeToPdnLayer())
  • .ToList();
  • document.Layers.AddRange(pdnLayers);
  • var numLayers = psdFile.Layers.Count + 2;
  • if (psdFile.Layers.Count == 0)
  • numLayers++;
    +
  • long numPixels = (long)psdFile.ColumnCount * psdFile.RowCount;
  • ulong bytesRequired = (ulong)(checked(4 * numPixels * numLayers));
  • var computerInfo = new Microsoft.VisualBasic.Devices.ComputerInfo();
  • var accessibleMemory = Math.Min(computerInfo.TotalPhysicalMemory, computerInfo.TotalVirtualMemory);
    +
  • if (accessibleMemory >= bytesRequired)
  • {
  • var pdnLayers = psdFile.Layers.Where(x => x.Rect.Width != 0 || x.Rect.Height != 0).AsParallel().AsOrdered()
  • .Select(psdLayer => psdLayer.DecodeToPdnLayer())
  • .ToList();
  • document.Layers.AddRange(pdnLayers);
  • }
  • else
  • {
  • document.Layers.Add(psdFile.Layers.First().DecodeToPdnLayer());
  • foreach (var layer in psdFile.Layers.Skip(1))
  • {
  • document.Layers.Add(layer.DecodeToPdnLayer());
  • var oldDoc = document;
  • document = document.Flatten();
  • oldDoc.Dispose();
  • }
  • }
    }

    SetPdnResolutionInfo(psdFile, document);
    @@ -248,6 +271,17 @@ private static void CheckSufficientMemory(PsdFile psdFile)
    var computerInfo = new Microsoft.VisualBasic.Devices.ComputerInfo();
    var accessibleMemory = Math.Min(computerInfo.TotalPhysicalMemory,
     computerInfo.TotalVirtualMemory);
    +
  • //need to flatten it on load
  • if (bytesRequired > accessibleMemory)
  • {
  • //2 in the source for flattening
  • //1 in the flattened
  • //+2 for each document
  • numLayers = 7;
  • bytesRequired = (ulong)(checked(4 * numPixels * numLayers));
  • }
    +
    if (bytesRequired > accessibleMemory)
     throw new OutOfMemoryException();
    }

jimshaw wrote Jul 14, 2015 at 4:14 AM

diff attached