|
15 | 15 | #define VIPS_GIF_RESOLUTION_LIMITED \
|
16 | 16 | (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION <= 12)
|
17 | 17 |
|
| 18 | +#define VIPS_SCRGB_ALPHA_FIXED \ |
| 19 | + (VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 15)) |
| 20 | + |
18 | 21 | #ifndef VIPS_META_BITS_PER_SAMPLE
|
19 | 22 | #define VIPS_META_BITS_PER_SAMPLE "palette-bit-depth"
|
20 | 23 | #endif
|
@@ -139,6 +142,110 @@ vips_black_go(VipsImage **out, int width, int height, int bands) {
|
139 | 142 | return res;
|
140 | 143 | }
|
141 | 144 |
|
| 145 | +/* Vips loads linear alpha in the 0.0-1.0 range but uses the 0.0-255.0 range. |
| 146 | + * https://github.com/libvips/libvips/pull/3627 fixes this behavior |
| 147 | + */ |
| 148 | +int |
| 149 | +vips_fix_scRGB_alpha_tiff(VipsImage *in, VipsImage **out) { |
| 150 | +#if VIPS_SCRGB_ALPHA_FIXED |
| 151 | + #warning Revise vips_fix_scRGB_tiff |
| 152 | + return vips_copy(in, out, NULL); |
| 153 | +#else |
| 154 | + VipsImage *base = vips_image_new(); |
| 155 | + VipsImage **t = (VipsImage **) vips_object_local_array(VIPS_OBJECT(base), 4); |
| 156 | + |
| 157 | + int res = |
| 158 | + vips_extract_band(in, &t[0], 0, "n", 3, NULL) || |
| 159 | + vips_extract_band(in, &t[1], 3, "n", in->Bands - 3, NULL) || |
| 160 | + vips_linear1(t[1], &t[2], 255.0, 0, NULL) || |
| 161 | + vips_cast(t[2], &t[3], in->BandFmt, NULL) || |
| 162 | + vips_bandjoin2(t[0], t[3], out, NULL); |
| 163 | + |
| 164 | + clear_image(&base); |
| 165 | + |
| 166 | + return res; |
| 167 | +#endif |
| 168 | +} |
| 169 | + |
| 170 | +/* Vips loads linear BW TIFFs as VIPS_INTERPRETATION_B_W or VIPS_INTERPRETATION_GREY16 |
| 171 | + * but these colourspaces are not linear. We should properly convert them to |
| 172 | + * VIPS_INTERPRETATION_GREY16 |
| 173 | + */ |
| 174 | +int |
| 175 | +vips_fix_BW_float_tiff(VipsImage *in, VipsImage **out) { |
| 176 | + VipsImage *base = vips_image_new(); |
| 177 | + VipsImage **t = (VipsImage **) vips_object_local_array(VIPS_OBJECT(base), 8); |
| 178 | + |
| 179 | + VipsImage *color = in; |
| 180 | + VipsImage *alpha = NULL; |
| 181 | + |
| 182 | + /* Extract and fix alpha. Float WB TIFF uses the 0.0-1.0 range but we need |
| 183 | + * the 0.0-65535.0 range |
| 184 | + */ |
| 185 | + if (in->Bands > 1) { |
| 186 | + if ( |
| 187 | + vips_extract_band(in, &t[0], 0, NULL) || |
| 188 | + vips_extract_band(in, &t[1], 1, "n", in->Bands - 1, NULL) || |
| 189 | + vips_linear1(t[1], &t[2], 65535.0, 0, NULL) || |
| 190 | + vips_cast_ushort(t[2], &t[3], NULL) || |
| 191 | + vips_copy(t[3], &t[4], "interpretation", VIPS_INTERPRETATION_GREY16, NULL) |
| 192 | + ) { |
| 193 | + clear_image(&base); |
| 194 | + return 1; |
| 195 | + } |
| 196 | + |
| 197 | + color = t[0]; |
| 198 | + alpha = t[4]; |
| 199 | + } |
| 200 | + |
| 201 | + /* Craft an scRGB image and convert it back to GREY16 to apply a gamma |
| 202 | + * correction |
| 203 | + */ |
| 204 | + VipsImage *rgb[3] = { color, color, color }; |
| 205 | + if ( |
| 206 | + vips_bandjoin(rgb, &t[5], 3, NULL) || |
| 207 | + vips_colourspace(t[5], &t[6], VIPS_INTERPRETATION_GREY16, |
| 208 | + "source_space", VIPS_INTERPRETATION_scRGB, NULL) |
| 209 | + ) { |
| 210 | + clear_image(&base); |
| 211 | + return 1; |
| 212 | + } |
| 213 | + |
| 214 | + int res; |
| 215 | + |
| 216 | + if (alpha) |
| 217 | + res = |
| 218 | + vips_bandjoin2(t[6], alpha, &t[7], NULL) || |
| 219 | + vips_icc_remove(t[7], out); |
| 220 | + else |
| 221 | + res = vips_icc_remove(t[6], out); |
| 222 | + |
| 223 | + clear_image(&base); |
| 224 | + |
| 225 | + return res; |
| 226 | +} |
| 227 | + |
| 228 | +int |
| 229 | +vips_fix_float_tiff(VipsImage *in, VipsImage **out) { |
| 230 | + /* Vips loads linear alpha in the 0.0-1.0 range but uses the 0.0-255.0 range. |
| 231 | + * https://github.com/libvips/libvips/pull/3627 fixes this behavior |
| 232 | + */ |
| 233 | + if (in->Type == VIPS_INTERPRETATION_scRGB && in->Bands > 3) |
| 234 | + return vips_fix_scRGB_alpha_tiff(in, out); |
| 235 | + |
| 236 | + /* Vips loads linear BW TIFFs as VIPS_INTERPRETATION_B_W or VIPS_INTERPRETATION_GREY16 |
| 237 | + * but these colourspaces are not linear. We should properly convert them to |
| 238 | + * VIPS_INTERPRETATION_GREY16 |
| 239 | + */ |
| 240 | + if ( |
| 241 | + (in->Type == VIPS_INTERPRETATION_B_W || in->Type == VIPS_INTERPRETATION_GREY16) && |
| 242 | + (in->BandFmt == VIPS_FORMAT_FLOAT || in->BandFmt == VIPS_FORMAT_DOUBLE) |
| 243 | + ) |
| 244 | + return vips_fix_BW_float_tiff(in, out); |
| 245 | + |
| 246 | + return vips_copy(in, out); |
| 247 | +} |
| 248 | + |
142 | 249 | int
|
143 | 250 | vips_get_orientation(VipsImage *image) {
|
144 | 251 | int orientation;
|
|
0 commit comments