• EditorBugs
  • Error packing images: NegativeArraySize

Problem statement

Describe: 1) what you have tried, 2) what you expected, and 3) what actually happened.

I'm working on an automated export pipeline for the artists on the team, and I've hit one folder of slices that gives a weird error when I attempt to pack it. I first encountered it from the command line, but it gives essentially the same error when exported through the GUI as well.

Give step-by-step instructions so we can reproduce the problem, if possible.

Pack a folder of slices with a command like this:

Spine.com -Xmx65536m -i "C:/Users/Hazel/KO_OP/plastic/GVH Raw Animation/Artwork/Building Blocks/Fang/Fang_MS_Basic_edited 2_autoslice" -o "C:/Users/Hazel/KO_OP/plastic/GVH Raw Animation/Export/Atlases" -n "Fang_MS_Basic_edited 2" -p "C:/Users/Hazel/KO_OP/plastic/GVH Raw Animation/Export/settings/4_0/pack.json"

It will give the error shown in the log below.
Other folders are still working fine, though it's worth noting that this is easily our largest one.

Editor information

Tell us your Spine Editor version.
4.1.19

Post your entire spine.log file here (or attach it), if you got any error messages.

Spine Launcher 4.0.41
Esoteric Software LLC (C) 2013-2021 | http://esotericsoftware.com
Windows 10 Pro amd64 10.0
Starting: Spine 4.1.19 Professional
Spine 4.1.19 Professional
Licensed to: *******
Pack: Fang_MS_Basic_edited 2
ERROR: Error packing images:
[error] Error packing images: C:\Users\Hazel\KO_OP\plastic\GVH Raw Animation\Artwork\Building Blocks\Fang\Fang_MS_Basic_edited 2_autoslice
   at s.WOL._(_:165)
   at s.eLi._(_:78)
   at s.eLi._(_:126)
   at s.EnT._(_:297)
   at s.ePE._(_:39)
   <events>
Cause: [error] Error processing directory: C:\Users\Hazel\KO_OP\plastic\GVH Raw Animation\Artwork\Building Blocks\Fang\Fang_MS_Basic_edited 2_autoslice
   at s.gLQ._(_:136)
   at s.Npb._(_:133)
   at s.gLQ._(_:99)
   at s.Npb._(_:115)
   at s.WOL._(_:159) ...
Cause: [NegativeArraySize] -2147483648
   at java.awt.image.DataBufferByte.<init>(Unknown Source)
   at java.awt.image.Raster.createInterleavedRaster(Unknown Source)
   at java.awt.image.BufferedImage.<init>(Unknown Source)
   at s.itZ._(_:248)
   at s.itZ._(_:181)
   at s.qFg._(_:134)
   at s.Npb._(_:284)
   at s.Npb._(_:276)
   at s.gLQ._(_:134) ...
Related Discussions
...

Are you packing extremely large images?

It looks like the size of the packed atlas page image is too large to be allocated. This is not a limitation of the memory available to Spine, but of the int datatype used for the image size. We'll add a better error message so the size can be seen.

Note -Xmx65536m allows Spine to use up to 65.5GB of RAM. It's extremely unlikely that is necessary. Setting a high maximum doesn't hurt if you actually have that much available, but it does mean that Spine may not reclaim memory it would with a lower limit. When Spine is not anywhere near the limit, it may just allocate more of the available memory.

The largest individual image is only 5020x2055, but there are 950 of them to pack (though many are as small as 74x89).

What is your atlas page max size set to?

One 5020x2055 requires a buffer that is 41.26MB. 950 of those is 39.2GB! If your atlas mage max size is very large, it could be trying to make an atlas page image that is unreasonably large.

OK, I was confused because it had been working fine with powerOfTwo disabled, and obviously enabling powerOfTwo made the textures larger, but it didn't seem likely that it would make it larger ENOUGH to push it over any kind of limit, when with POT disabled it was producing a 32756x14972 image, and POT would only bump it up to 32768x32768, and even 32768x32768 is only 1,073,741,824, far below the 2,147,483,647 limit for a signed 32-bit integer.
But I just realised, since there's four channels, it's presumably making an array four times that size, and indeed, 32756x14972x4 = 2,092,715,328, just barely below the limit. So that's that.

Is there any hope that this would be an easy fix (i.e. 64-bit integers), or should I start looking into TexturePacker's Spine atlas support?

Spine is written in Java, where the max array size is 2,147,483,647. It's possible to work with larger amounts of memory, but it would require a fair amount of effort. I'm not sure it's worth it since it's borderline unreasonable to load such a large image.

32768 * 32768 * 4 = 4,294,967,296 or 4.29GB. That is a massive image. It will be smaller on disk with compression from PNG, but to load it into the GPU uncompressed it will require 4.29GB of RAM to load it and 4.29GB of video memory to store it, for just one of those images. Note only that, but video hardware and/or the API used to access the hardware can have texture size limits. If you expect your software to run everywhere, you should target reasonable texture sizes.

Why do you need an image that is so large? An atlas can have multiple pages. If the reason is to reduce draw calls, increase batching, or otherwise avoid texture changes, there may be other ways to achieve that goal. For example, you could use texture arrays.