Skip to content

Commit 9f590ce

Browse files
authored
fix the pngsave bitdepth param (#4516)
* fix the pngsave bitdepth param Saving an 8-bit image as 16-but PNG (and vice versa) didn't work correctly. See #4512 * oops! * sigh * fix uint16 srgb case * revise colourspace it now enforces the format, so srgb -> srgb conversion (for example) will make a uchar image * we can remove some if()s now * fix cast to output type and revise coments a bit
1 parent d87f9ed commit 9f590ce

File tree

7 files changed

+128
-106
lines changed

7 files changed

+128
-106
lines changed

libvips/colour/colourspace.c

Lines changed: 54 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -211,14 +211,15 @@ typedef struct _VipsColourRoute {
211211
#define scRGB VIPS_INTERPRETATION_scRGB
212212
#define sRGB VIPS_INTERPRETATION_sRGB
213213
#define HSV VIPS_INTERPRETATION_HSV
214+
#define BW VIPS_INTERPRETATION_B_W
214215
#define RGB16 VIPS_INTERPRETATION_RGB16
215216
#define GREY16 VIPS_INTERPRETATION_GREY16
216217
#define YXY VIPS_INTERPRETATION_YXY
217-
#define BW VIPS_INTERPRETATION_B_W
218218

219219
/* All the routes we know about.
220220
*/
221221
static VipsColourRoute vips_colour_routes[] = {
222+
{ XYZ, XYZ, { vips_cast_float, NULL } },
222223
{ XYZ, LAB, { vips_XYZ2Lab, NULL } },
223224
{ XYZ, LABQ, { vips_XYZ2Lab, vips_Lab2LabQ, NULL } },
224225
{ XYZ, LCH, { vips_XYZ2Lab, vips_Lab2LCh, NULL } },
@@ -234,6 +235,7 @@ static VipsColourRoute vips_colour_routes[] = {
234235
{ XYZ, YXY, { vips_XYZ2Yxy, NULL } },
235236

236237
{ LAB, XYZ, { vips_Lab2XYZ, NULL } },
238+
{ LAB, LAB, { vips_cast_float, NULL } },
237239
{ LAB, LABQ, { vips_Lab2LabQ, NULL } },
238240
{ LAB, LCH, { vips_Lab2LCh, NULL } },
239241
{ LAB, CMC, { vips_Lab2LCh, vips_LCh2CMC, NULL } },
@@ -249,6 +251,7 @@ static VipsColourRoute vips_colour_routes[] = {
249251

250252
{ LABQ, XYZ, { vips_LabQ2Lab, vips_Lab2XYZ, NULL } },
251253
{ LABQ, LAB, { vips_LabQ2Lab, NULL } },
254+
{ LABQ, LABQ, { NULL } },
252255
{ LABQ, LCH, { vips_LabQ2Lab, vips_Lab2LCh, NULL } },
253256
{ LABQ, CMC, { vips_LabQ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } },
254257
{ LABQ, LABS, { vips_LabQ2LabS, NULL } },
@@ -264,6 +267,7 @@ static VipsColourRoute vips_colour_routes[] = {
264267
{ LCH, XYZ, { vips_LCh2Lab, vips_Lab2XYZ, NULL } },
265268
{ LCH, LAB, { vips_LCh2Lab, NULL } },
266269
{ LCH, LABQ, { vips_LCh2Lab, vips_Lab2LabQ, NULL } },
270+
{ LCH, LCH, { vips_cast_float, NULL } },
267271
{ LCH, CMC, { vips_LCh2CMC, NULL } },
268272
{ LCH, LABS, { vips_LCh2Lab, vips_Lab2LabS, NULL } },
269273
{ LCH, CMYK, { vips_LCh2Lab, vips_Lab2XYZ, vips_XYZ2CMYK, NULL } },
@@ -279,6 +283,7 @@ static VipsColourRoute vips_colour_routes[] = {
279283
{ CMC, LAB, { vips_CMC2LCh, vips_LCh2Lab, NULL } },
280284
{ CMC, LABQ, { vips_CMC2LCh, vips_LCh2Lab, vips_Lab2LabQ, NULL } },
281285
{ CMC, LCH, { vips_CMC2LCh, NULL } },
286+
{ CMC, CMC, { vips_cast_float, NULL } },
282287
{ CMC, LABS, { vips_CMC2LCh, vips_LCh2Lab, vips_Lab2LabS, NULL } },
283288
{ CMC, CMYK, { vips_CMC2LCh, vips_LCh2Lab, vips_Lab2XYZ, vips_XYZ2CMYK, NULL } },
284289
{ CMC, scRGB, { vips_CMC2LCh, vips_LCh2Lab, vips_Lab2XYZ, vips_XYZ2scRGB, NULL } },
@@ -294,6 +299,7 @@ static VipsColourRoute vips_colour_routes[] = {
294299
{ LABS, LABQ, { vips_LabS2LabQ, NULL } },
295300
{ LABS, LCH, { vips_LabS2Lab, vips_Lab2LCh, NULL } },
296301
{ LABS, CMC, { vips_LabS2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } },
302+
{ LABS, LABS, { vips_cast_short, NULL } },
297303
{ LABS, CMYK, { vips_LabS2Lab, vips_Lab2XYZ, vips_XYZ2CMYK, NULL } },
298304
{ LABS, scRGB, { vips_LabS2Lab, vips_Lab2XYZ, vips_XYZ2scRGB, NULL } },
299305
{ LABS, sRGB, { vips_LabS2Lab, vips_Lab2XYZ, vips_XYZ2scRGB, vips_scRGB2sRGB, NULL } },
@@ -303,44 +309,48 @@ static VipsColourRoute vips_colour_routes[] = {
303309
{ LABS, GREY16, { vips_LabS2Lab, vips_Lab2XYZ, vips_XYZ2scRGB, vips_scRGB2BW16, NULL } },
304310
{ LABS, YXY, { vips_LabS2Lab, vips_Lab2XYZ, vips_XYZ2Yxy, NULL } },
305311

306-
{ scRGB, XYZ, { vips_scRGB2XYZ, NULL } },
307-
{ scRGB, LAB, { vips_scRGB2XYZ, vips_XYZ2Lab, NULL } },
308-
{ scRGB, LABQ, { vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabQ, NULL } },
309-
{ scRGB, LCH, { vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, NULL } },
310-
{ scRGB, CMC, { vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } },
311-
{ scRGB, CMYK, { vips_scRGB2XYZ, vips_XYZ2CMYK, NULL } },
312-
{ scRGB, sRGB, { vips_scRGB2sRGB, NULL } },
313-
{ scRGB, HSV, { vips_scRGB2sRGB, vips_sRGB2HSV, NULL } },
314-
{ scRGB, BW, { vips_scRGB2BW, NULL } },
315-
{ scRGB, LABS, { vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabS, NULL } },
316-
{ scRGB, RGB16, { vips_scRGB2RGB16, NULL } },
317-
{ scRGB, GREY16, { vips_scRGB2BW16, NULL } },
318-
{ scRGB, YXY, { vips_scRGB2XYZ, vips_XYZ2Yxy, NULL } },
319-
320312
{ CMYK, XYZ, { vips_CMYK2XYZ, NULL } },
321313
{ CMYK, LAB, { vips_CMYK2XYZ, vips_XYZ2Lab, NULL } },
322314
{ CMYK, LABQ, { vips_CMYK2XYZ, vips_XYZ2Lab, vips_Lab2LabQ, NULL } },
323315
{ CMYK, LCH, { vips_CMYK2XYZ, vips_XYZ2Lab, vips_Lab2LCh, NULL } },
324316
{ CMYK, CMC, { vips_CMYK2XYZ, vips_XYZ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } },
317+
{ CMYK, LABS, { vips_CMYK2XYZ, vips_XYZ2Lab, vips_Lab2LabS, NULL } },
318+
// can be 8 or 16 bit, so do nothing
319+
{ CMYK, CMYK, { NULL } },
325320
{ CMYK, scRGB, { vips_CMYK2XYZ, vips_XYZ2scRGB, NULL } },
326321
{ CMYK, sRGB, { vips_CMYK2XYZ, vips_XYZ2scRGB, vips_scRGB2sRGB, NULL } },
327322
{ CMYK, HSV, { vips_CMYK2XYZ, vips_XYZ2scRGB, vips_scRGB2sRGB, vips_sRGB2HSV, NULL } },
328323
{ CMYK, BW, { vips_CMYK2XYZ, vips_XYZ2scRGB, vips_scRGB2BW, NULL } },
329-
{ CMYK, LABS, { vips_CMYK2XYZ, vips_XYZ2Lab, vips_Lab2LabS, NULL } },
330324
{ CMYK, RGB16, { vips_CMYK2XYZ, vips_XYZ2scRGB, vips_scRGB2RGB16, NULL } },
331325
{ CMYK, GREY16, { vips_CMYK2XYZ, vips_XYZ2scRGB, vips_scRGB2BW16, NULL } },
332326
{ CMYK, YXY, { vips_CMYK2XYZ, vips_XYZ2Yxy, NULL } },
333327

328+
{ scRGB, XYZ, { vips_scRGB2XYZ, NULL } },
329+
{ scRGB, LAB, { vips_scRGB2XYZ, vips_XYZ2Lab, NULL } },
330+
{ scRGB, LABQ, { vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabQ, NULL } },
331+
{ scRGB, LCH, { vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, NULL } },
332+
{ scRGB, CMC, { vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } },
333+
{ scRGB, LABS, { vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabS, NULL } },
334+
{ scRGB, CMYK, { vips_scRGB2XYZ, vips_XYZ2CMYK, NULL } },
335+
{ scRGB, scRGB, { vips_cast_float, NULL } },
336+
{ scRGB, sRGB, { vips_scRGB2sRGB, NULL } },
337+
{ scRGB, HSV, { vips_scRGB2sRGB, vips_sRGB2HSV, NULL } },
338+
{ scRGB, BW, { vips_scRGB2BW, NULL } },
339+
{ scRGB, RGB16, { vips_scRGB2RGB16, NULL } },
340+
{ scRGB, GREY16, { vips_scRGB2BW16, NULL } },
341+
{ scRGB, YXY, { vips_scRGB2XYZ, vips_XYZ2Yxy, NULL } },
342+
334343
{ sRGB, XYZ, { vips_sRGB2scRGB, vips_scRGB2XYZ, NULL } },
335344
{ sRGB, LAB, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, NULL } },
336345
{ sRGB, LABQ, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabQ, NULL } },
337346
{ sRGB, LCH, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, NULL } },
338347
{ sRGB, CMC, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } },
348+
{ sRGB, LABS, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabS, NULL } },
339349
{ sRGB, CMYK, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2CMYK, NULL } },
340350
{ sRGB, scRGB, { vips_sRGB2scRGB, NULL } },
351+
{ sRGB, sRGB, { vips_cast_uchar, NULL } },
341352
{ sRGB, HSV, { vips_sRGB2HSV, NULL } },
342353
{ sRGB, BW, { vips_sRGB2scRGB, vips_scRGB2BW, NULL } },
343-
{ sRGB, LABS, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabS, NULL } },
344354
{ sRGB, RGB16, { vips_sRGB2RGB16, NULL } },
345355
{ sRGB, GREY16, { vips_sRGB2scRGB, vips_scRGB2BW16, NULL } },
346356
{ sRGB, YXY, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Yxy, NULL } },
@@ -350,26 +360,43 @@ static VipsColourRoute vips_colour_routes[] = {
350360
{ HSV, LABQ, { vips_HSV2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabQ, NULL } },
351361
{ HSV, LCH, { vips_HSV2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, NULL } },
352362
{ HSV, CMC, { vips_HSV2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } },
363+
{ HSV, LABS, { vips_HSV2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabS, NULL } },
353364
{ HSV, CMYK, { vips_HSV2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2CMYK, NULL } },
354365
{ HSV, scRGB, { vips_HSV2sRGB, vips_sRGB2scRGB, NULL } },
355366
{ HSV, sRGB, { vips_HSV2sRGB, NULL } },
367+
{ HSV, HSV, { vips_cast_uchar, NULL } },
356368
{ HSV, BW, { vips_HSV2sRGB, vips_sRGB2scRGB, vips_scRGB2BW, NULL } },
357-
{ HSV, LABS, { vips_HSV2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabS, NULL } },
358369
{ HSV, RGB16, { vips_HSV2sRGB, vips_sRGB2RGB16, NULL } },
359370
{ HSV, GREY16, { vips_HSV2sRGB, vips_sRGB2scRGB, vips_scRGB2BW16, NULL } },
360371
{ HSV, YXY, { vips_HSV2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Yxy, NULL } },
361372

373+
{ BW, XYZ, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, NULL } },
374+
{ BW, LAB, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, NULL } },
375+
{ BW, LABQ, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabQ, NULL } },
376+
{ BW, LCH, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, NULL } },
377+
{ BW, CMC, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } },
378+
{ BW, LABS, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabS, NULL } },
379+
{ BW, CMYK, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2CMYK, NULL } },
380+
{ BW, scRGB, { vips_BW2sRGB, vips_sRGB2scRGB, NULL } },
381+
{ BW, sRGB, { vips_BW2sRGB, NULL } },
382+
{ BW, HSV, { vips_BW2sRGB, vips_sRGB2HSV, NULL } },
383+
{ BW, BW, { vips_cast_uchar, NULL } },
384+
{ BW, RGB16, { vips_BW2sRGB, vips_sRGB2RGB16, NULL } },
385+
{ BW, GREY16, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2BW16, NULL } },
386+
{ BW, YXY, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Yxy, NULL } },
387+
362388
{ RGB16, XYZ, { vips_sRGB2scRGB, vips_scRGB2XYZ, NULL } },
363389
{ RGB16, LAB, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, NULL } },
364390
{ RGB16, LABQ, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabQ, NULL } },
365391
{ RGB16, LCH, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, NULL } },
366392
{ RGB16, CMC, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } },
393+
{ RGB16, LABS, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabS, NULL } },
367394
{ RGB16, CMYK, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2CMYK, NULL } },
368395
{ RGB16, scRGB, { vips_sRGB2scRGB, NULL } },
369396
{ RGB16, sRGB, { vips_RGB162sRGB, NULL } },
370397
{ RGB16, HSV, { vips_RGB162sRGB, vips_sRGB2HSV, NULL } },
371398
{ RGB16, BW, { vips_sRGB2scRGB, vips_scRGB2BW, NULL } },
372-
{ RGB16, LABS, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabS, NULL } },
399+
{ RGB16, RGB16, { vips_cast_ushort, NULL } },
373400
{ RGB16, GREY16, { vips_sRGB2scRGB, vips_scRGB2BW16, NULL } },
374401
{ RGB16, YXY, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Yxy, NULL } },
375402

@@ -378,29 +405,16 @@ static VipsColourRoute vips_colour_routes[] = {
378405
{ GREY16, LABQ, { vips_GREY162RGB16, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabQ, NULL } },
379406
{ GREY16, LCH, { vips_GREY162RGB16, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, NULL } },
380407
{ GREY16, CMC, { vips_GREY162RGB16, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } },
408+
{ GREY16, LABS, { vips_GREY162RGB16, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabS, NULL } },
381409
{ GREY16, CMYK, { vips_GREY162RGB16, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2CMYK, NULL } },
382410
{ GREY16, scRGB, { vips_GREY162RGB16, vips_sRGB2scRGB, NULL } },
383411
{ GREY16, sRGB, { vips_GREY162RGB16, vips_RGB162sRGB, NULL } },
384412
{ GREY16, HSV, { vips_GREY162RGB16, vips_RGB162sRGB, vips_sRGB2HSV, NULL } },
385413
{ GREY16, BW, { vips_GREY162RGB16, vips_sRGB2scRGB, vips_scRGB2BW, NULL } },
386-
{ GREY16, LABS, { vips_GREY162RGB16, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabS, NULL } },
387414
{ GREY16, RGB16, { vips_GREY162RGB16, NULL } },
415+
{ GREY16, GREY16, { vips_cast_ushort, NULL } },
388416
{ GREY16, YXY, { vips_GREY162RGB16, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Yxy, NULL } },
389417

390-
{ BW, XYZ, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, NULL } },
391-
{ BW, LAB, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, NULL } },
392-
{ BW, LABQ, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabQ, NULL } },
393-
{ BW, LCH, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, NULL } },
394-
{ BW, CMC, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } },
395-
{ BW, CMYK, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2CMYK, NULL } },
396-
{ BW, scRGB, { vips_BW2sRGB, vips_sRGB2scRGB, NULL } },
397-
{ BW, sRGB, { vips_BW2sRGB, NULL } },
398-
{ BW, HSV, { vips_BW2sRGB, vips_sRGB2HSV, NULL } },
399-
{ BW, LABS, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LabS, NULL } },
400-
{ BW, RGB16, { vips_BW2sRGB, vips_sRGB2RGB16, NULL } },
401-
{ BW, GREY16, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2BW16, NULL } },
402-
{ BW, YXY, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Yxy, NULL } },
403-
404418
{ YXY, XYZ, { vips_Yxy2XYZ, NULL } },
405419
{ YXY, LAB, { vips_Yxy2XYZ, vips_XYZ2Lab, NULL } },
406420
{ YXY, LABQ, { vips_Yxy2XYZ, vips_XYZ2Lab, vips_Lab2LabQ, NULL } },
@@ -413,7 +427,8 @@ static VipsColourRoute vips_colour_routes[] = {
413427
{ YXY, HSV, { vips_Yxy2XYZ, vips_XYZ2scRGB, vips_scRGB2sRGB, vips_sRGB2HSV, NULL } },
414428
{ YXY, BW, { vips_Yxy2XYZ, vips_XYZ2scRGB, vips_scRGB2BW, NULL } },
415429
{ YXY, RGB16, { vips_Yxy2XYZ, vips_XYZ2scRGB, vips_scRGB2RGB16, NULL } },
416-
{ YXY, GREY16, { vips_Yxy2XYZ, vips_XYZ2scRGB, vips_scRGB2BW16, NULL } }
430+
{ YXY, GREY16, { vips_Yxy2XYZ, vips_XYZ2scRGB, vips_scRGB2BW16, NULL } },
431+
{ YXY, YXY, { vips_cast_float, NULL } },
417432

418433
};
419434

@@ -468,8 +483,7 @@ vips_colourspace_build(VipsObject *object)
468483

469484
int i, j;
470485
VipsImage *x;
471-
VipsImage **t = (VipsImage **)
472-
vips_object_local_array(object, 1);
486+
VipsImage **t = (VipsImage **) vips_object_local_array(object, 1);
473487
VipsImage **pipe = (VipsImage **)
474488
vips_object_local_array(object, MAX_STEPS);
475489

@@ -502,25 +516,14 @@ vips_colourspace_build(VipsObject *object)
502516
if (interpretation == VIPS_INTERPRETATION_RGB)
503517
interpretation = VIPS_INTERPRETATION_sRGB;
504518

505-
/* No conversion necessary.
506-
*/
507-
if (interpretation == colourspace->space) {
508-
g_object_set(colourspace, "out", vips_image_new(), NULL);
509-
510-
return vips_image_write(colourspace->in, colourspace->out);
511-
}
512-
513519
for (i = 0; i < VIPS_NUMBER(vips_colour_routes); i++)
514520
if (vips_colour_routes[i].from == interpretation &&
515521
vips_colour_routes[i].to == colourspace->space)
516522
break;
517523
if (i == VIPS_NUMBER(vips_colour_routes)) {
518-
vips_error("vips_colourspace",
519-
_("no known route from '%s' to '%s'"),
520-
vips_enum_nick(VIPS_TYPE_INTERPRETATION,
521-
interpretation),
522-
vips_enum_nick(VIPS_TYPE_INTERPRETATION,
523-
colourspace->space));
524+
vips_error("vips_colourspace", _("no known route from '%s' to '%s'"),
525+
vips_enum_nick(VIPS_TYPE_INTERPRETATION, interpretation),
526+
vips_enum_nick(VIPS_TYPE_INTERPRETATION, colourspace->space));
524527
return -1;
525528
}
526529

libvips/foreign/foreign.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,13 +1375,16 @@ vips_foreign_save_new_from_string(const char *string)
13751375

13761376
/* Apply a set of saveable flags.
13771377
*
1378+
* - unpack rad and labq
13781379
* - if the saver supports mono and we have a mono-looking image, we are done
13791380
* - if the saver supports CMYK and we have a CMYK-looking image, we are done
13801381
* - if this is a CMYK-looking image, import to XYZ
1381-
* - go to rgb
1382-
* - if the saver supports rgb, we are done
1382+
* - if the saver supports rgb, go to rgb
13831383
* - if the saver supports cmyk, go to cmyk
13841384
* - if the saver supports mono, go to mono
1385+
*
1386+
* we output 16 bit images if the source is 16 bits ... a later stage
1387+
* uses the format[] table to cut this down to the size the saver wants
13851388
*/
13861389
static int
13871390
vips_foreign_apply_saveable(VipsImage *in, VipsImage **ready,
@@ -1404,7 +1407,7 @@ vips_foreign_apply_saveable(VipsImage *in, VipsImage **ready,
14041407
return 0;
14051408
}
14061409

1407-
/* If this is an VIPS_CODING_LABQ, we can go straight to RGB.
1410+
/* If this is VIPS_CODING_LABQ, we can go straight to RGB.
14081411
*/
14091412
if (in->Coding == VIPS_CODING_LABQ) {
14101413
if (vips_LabQ2sRGB(in, &out, NULL)) {
@@ -1415,7 +1418,7 @@ vips_foreign_apply_saveable(VipsImage *in, VipsImage **ready,
14151418
in = out;
14161419
}
14171420

1418-
/* If this is an VIPS_CODING_RAD, we unpack to float. This could be
1421+
/* If this is VIPS_CODING_RAD, we unpack to float. This could be
14191422
* scRGB or XYZ.
14201423
*/
14211424
if (in->Coding == VIPS_CODING_RAD) {
@@ -1478,7 +1481,7 @@ vips_foreign_apply_saveable(VipsImage *in, VipsImage **ready,
14781481
return 0;
14791482
}
14801483

1481-
/* If the saver supports CMYK, go to RGB, or RGB16 if this is a ushort
1484+
/* If the saver supports CMYK, go to CMYK, 16 bits if this is a ushort
14821485
* source.
14831486
*/
14841487
if (saveable & VIPS_FOREIGN_SAVEABLE_CMYK) {
@@ -1639,10 +1642,10 @@ vips__foreign_convert_saveable(VipsImage *in, VipsImage **ready,
16391642
}
16401643
}
16411644

1642-
/* Convert to the format the saver likes, based on the original format.
1645+
/* Convert to the format the saver likes.
16431646
*/
16441647
if (in->Coding == VIPS_CODING_NONE) {
1645-
if (vips_cast(in, &out, format[original_format], NULL)) {
1648+
if (vips_cast(in, &out, format[in->BandFmt], NULL)) {
16461649
g_object_unref(in);
16471650
return -1;
16481651
}

libvips/foreign/pngsave.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ vips_foreign_save_png_build(VipsObject *object)
102102
VipsForeignSavePng *png = (VipsForeignSavePng *) object;
103103

104104
VipsImage *in;
105+
VipsImage *x;
105106

106107
if (VIPS_OBJECT_CLASS(vips_foreign_save_png_parent_class)->build(object))
107108
return -1;
@@ -124,18 +125,27 @@ vips_foreign_save_png_build(VipsObject *object)
124125
if (vips_object_argument_isset(object, "colours"))
125126
png->bitdepth = ceil(log2(png->colours));
126127

127-
/* Cast in down to 8 bit if we can.
128+
/* The bitdepth param can change the interpretation.
128129
*/
129-
if (png->bitdepth <= 8) {
130-
VipsImage *x;
131-
132-
if (vips_cast(in, &x, VIPS_FORMAT_UCHAR, NULL)) {
133-
g_object_unref(in);
134-
return -1;
135-
}
130+
VipsInterpretation interpretation;
131+
if (in->Bands > 2) {
132+
if (png->bitdepth > 8)
133+
interpretation = VIPS_INTERPRETATION_RGB16;
134+
else
135+
interpretation = VIPS_INTERPRETATION_sRGB;
136+
}
137+
else {
138+
if (png->bitdepth > 8)
139+
interpretation = VIPS_INTERPRETATION_GREY16;
140+
else
141+
interpretation = VIPS_INTERPRETATION_B_W;
142+
}
143+
if (vips_colourspace(in, &x, interpretation, NULL)) {
136144
g_object_unref(in);
137-
in = x;
145+
return -1;
138146
}
147+
g_object_unref(in);
148+
in = x;
139149

140150
/* If this is a RGB or RGBA image and a low bit depth has been
141151
* requested, enable palettization.
@@ -358,10 +368,8 @@ vips_foreign_save_png_file_build(VipsObject *object)
358368
if (!(png->target = vips_target_new_to_file(file->filename)))
359369
return -1;
360370

361-
if (VIPS_OBJECT_CLASS(vips_foreign_save_png_file_parent_class)->build(object))
362-
return -1;
363-
364-
return 0;
371+
return VIPS_OBJECT_CLASS(vips_foreign_save_png_file_parent_class)->
372+
build(object);
365373
}
366374

367375
static void

0 commit comments

Comments
 (0)