-
Notifications
You must be signed in to change notification settings - Fork 61
Basic concepts
Many image formats only really support sequential reading. For example, libpng provides png_read_row(), a function which reads the next line of pixels from a file. You call it once for each line in the image to get every pixel.
However, many operations require random access to pixels. For example, a 90-degree rotate will need to read a column of pixels for every output line it writes. If it just used png_read_row() it would need to decompress the input image many, many times in order to create the output.
To prevent this libvips will first decompress the entire image to a large temporary area and then process from that. This temporary area is in memory for small files or on disc for large files.
Not all operations need random access to their source pixels. For example, thumbnailing, the process of shrinking images for display, can work strictly top-to-bottom. To help speed up operations of this type you can give a hint to read operations to indicate that you only need sequential access. For example:
a = Vips::Image.new_from_file filename, access: :sequential
When libvips opens this image it will not decompress to a temporary buffer but, instead, stream pixels from the png decompressor directly through the operation. This saves first writing and then reading back the temporary area.
See the longer discussion on the libvips blog for details and benchmarks.
It's just an array you use to pre-calculate results.
For an 8-bit image, there are only 256 possible values for pixels. You don't need to calculate pow() for every pixel in an 8-bit image, instead you can just call pow() 256 times on the 256 possible values, then use those results as a look-up table.
lut = Vips::Image.identity
This makes a 1 band image, 256 elements across and one element deep, where elements have the values 0, 1, 2, 3, 4, 5, ... 255. It's called "identity" because it creates an identity function.
lut = lut ** 0.5 * 255 / 255 ** 0.5
This runs the pow() on the identity LUT. So element 123 (for example) will contain
123 ** 0.5 * 255 / 255 ** 0.5
ie. the result that every pixel with the value 123 out to be changed to.
Finally this:
im = im.maplut lut
loops over the large image looking up every pixel value in lut and replacing it with the pre-calculated result.
See http://libvips.blogspot.co.uk/2012/06/how-libvips-opens-file.html.