Fix a bug where generating thumbnails failed for certain images when using libvips 8.10. Specifically, it failed for single-channel greyscale images and four-channel CMYK images without an embedded color profile. In these cases we specified an sRGB fallback profile, but under libvips 8.10 this failed because the sRGB profile was incompatible with single-channel and four-channel images. Before libvips 8.10 this worked, but as of 8.10 it's a hard error. The way libvips handles fallback color profiles differs across versions, so we have to use different arguments for different versions. In 8.7, vips doesn't have builtin color profiles, so we have to specify our own manually. In 8.9, it has builtin profiles, so we can omit the import profile, but we're still required to set the export profile to sRGB, otherwise it will leave CMYK images as CMYK when generating thumbnails. In 8.10, we have to _not_ to set the import or export profile to sRGB, otherwise it will fail with an incompatible profile error when it tries to convert CMYK images to RGB. The builtin sRGB profile used by libvips[1] is different than the one we used previously[2]. The builtin one comes from LCMS[3], whereas ours came from ArgyllCMS.[4] Not all sRGB profiles are created the same[5], so this may result in some imperceptible differences in thumbnail output. The ArgyllCMS profile was used before because it seemed to be the best one[6], but realistically it probably doesn't matter. 1: https://github.com/libvips/libvips/blob/v8.10.6/libvips/colour/profiles/sRGB.icm 2: https://github.com/danbooru/danbooru/blob/906eec190d45d58941f83f5ec8165ddeba205317/config/sRGB.icm 3: https://www.littlecms.com/ 4: https://www.argyllcms.com/ 5: https://ninedegreesbelow.com/photography/srgb-profile-comparison.html 6: https://ninedegreesbelow.com/photography/srgb-profile-comparison.html#addendum
Logical
This directory contains library code used through Danbooru. This includes things like defining API clients, dealing with sources, parsing tag searches, storing and resizing images, and so on.
Many of the files here use the Service Object pattern. Instead of putting complex code in models or controllers, it goes here, in plain old Ruby objects (POROs). This keeps models and controllers simpler, and keeps domain logic isolated and independent from the database and the HTTP request cycle.