The problem was that we were stripping color profiles from thumbnails, but we weren't setting `export_profile: "srgb"` to convert images to sRGB first. This resulted in wrong colors for images with non-sRGB color profiles, such as Adobe RGB. The fix is to convert images to sRGB when possible, while leaving CMYK and greyscale images alone. We leave CMYK images alone because we can't convert CMYK to sRGB without losing color. We leave greyscale images alone if they don't have a color profile, that way they stay as one-channel greyscale (or two-channel greyscale, in case of alpha) instead of being converted to three-channel sRGB. However, if a greyscale image has a color profile, then we have to convert to sRGB, otherwise the colors would be wrong when we strip the profile. We also have to set the import profile, otherwise images with broken embedded color profiles won't have a fallback profile and may get incorrect colors. In this case we also have to be careful, because we can't specify an sRGB fallback for greyscale or CMYK images.
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.