Loading a subset of images from large imagetables

Hi,

My game builds up lots of animations that are 300-1000 frames long made up of 400x240px images.

The images for these are sourced from around 10 image tables that currently each hold 300 frames (20x15 images). Each of these image tables is 1-2MB. Call these imagetables A (‘A-table-400-240’), B, C, etc. There’s no requirement for the source tables to be 300 frames long, that is just the way that I have generated them.

I am constructing new tables made up of images from the source tables. For example, I want images using frames A[1-50], B[55-70], A[51-60], C[1-3].

The game will have lots (100+) of these constructed tables, so to save on disk space I’m defining the frames in a config file and constructing them when they are needed at run time by reading the source tables. I only ever need to use them one at a time and its ok if it takes a few seconds to build them.

My question is: Is there a way that I can load in only the images that I actually need from these imagetables, without having to load the entire source table in memory?

Currently I’m doing something akin to this:

local config = { {source="A", start=1, end=50} , ... }
local newImages = {}

for i = 1, #config do

  local c = config[i]

  local sourceImages = gfx.imagetable.new('assets/img/'..c.source)
  
  for j = c.start, c.end do
    table.insert(newImages, sourceImages:getImage(j):copy()) 
  end

  coroutine.yield()
  
end

Which is just a killer for performance because it brings in the entire source table into memory to potentially grab only a couple of images.

I know that there are some quick wins to be had, like pulling all the images I need from each source table while its open, so that you only load each source table once. But in the worst case to construct A[1], B[1], C[1],… I’d still need to load in all of the source tables.

Is there a way to load only a range of images from the imagetable e.g. gfx.imagetable.new('assets/img/A', start, end) or by using the image api gfx.image.new(‘assets/img/A-5’) to load the 5th image of A.

I’ll try a few quick wins, but failing that the only other performant option I can think of is to store my imagetables in smaller chunks e.g. using 30 frames instead of 300. Will there be any performance overhead to loading in more smaller imagetables vs loading in fewer big ones?

As you can tell, I’m having 16MB of fun :grin:

1 Like

Hmm, I don’t think so. Your pdt/pdi on device will be zlib compressed. zlib does support partial decompression, but I believe it has to always start from the start of the stream.
It might be better in the long run to split up the tables into smaller sub sections if you’re only going to be loading sections of them at a time?

Thanks, that’s kind of what I’d thought too. I’m still figuring out exactly how I’ll use these images, and how many frames from each I’ll be needing, but wanted to see if I was heading down the wrong path to begin with. At the end of the day there will probably be a few hot-spots that I’ll pull out into separate file.