From b940c2fda5de510ea814ce63c903bcffb99b92db Mon Sep 17 00:00:00 2001 From: Michael Vrhel Date: Wed, 16 Aug 2017 12:39:20 -0700 Subject: mudraw: Add ability to specify icc profile for target colorspace. --- source/fitz/colorspace.c | 6 ++-- source/tools/mudraw.c | 75 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 71 insertions(+), 10 deletions(-) (limited to 'source') diff --git a/source/fitz/colorspace.c b/source/fitz/colorspace.c index 17892256..1692a439 100644 --- a/source/fitz/colorspace.c +++ b/source/fitz/colorspace.c @@ -3670,8 +3670,8 @@ fz_new_icc_colorspace(fz_context *ctx, const char *name, int num, fz_buffer *buf fz_cmm_init_profile(ctx, profile); - /* Check if correct type */ - if (num != profile->num_devcomp) + /* Check if correct type, if a particular type was expected */ + if (num != 0 && num != profile->num_devcomp) { fz_drop_buffer(ctx, profile->buffer); fz_cmm_fin_profile(ctx, profile); @@ -3682,7 +3682,7 @@ fz_new_icc_colorspace(fz_context *ctx, const char *name, int num, fz_buffer *buf fz_md5_icc(ctx, profile); if (profile->num_devcomp == 4) flags |= FZ_CS_SUBTRACTIVE; - cs = fz_new_colorspace(ctx, name, num, flags, NULL, NULL, NULL, is_lab ? clamp_lab_icc : clamp_default_icc, free_icc, profile, sizeof(profile)); + cs = fz_new_colorspace(ctx, name, profile->num_devcomp, flags, NULL, NULL, NULL, is_lab ? clamp_lab_icc : clamp_default_icc, free_icc, profile, sizeof(profile)); if (profile->num_devcomp == 4) { diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c index f08abac1..8f3547b7 100644 --- a/source/tools/mudraw.c +++ b/source/tools/mudraw.c @@ -39,7 +39,7 @@ enum { OUT_GPROOF }; -enum { CS_INVALID, CS_UNSET, CS_MONO, CS_GRAY, CS_GRAY_ALPHA, CS_RGB, CS_RGB_ALPHA, CS_CMYK, CS_CMYK_ALPHA }; +enum { CS_INVALID, CS_UNSET, CS_MONO, CS_GRAY, CS_GRAY_ALPHA, CS_RGB, CS_RGB_ALPHA, CS_CMYK, CS_CMYK_ALPHA, CS_ICC }; enum { SPOTS_NONE, SPOTS_OVERPRINT_SIM, SPOTS_FULL }; @@ -108,12 +108,12 @@ typedef struct { int format; int default_cs; - int permitted_cs[6]; + int permitted_cs[7]; } format_cs_table_t; static const format_cs_table_t format_cs_table[] = { - { OUT_PNG, CS_RGB, { CS_GRAY, CS_GRAY_ALPHA, CS_RGB, CS_RGB_ALPHA } }, + { OUT_PNG, CS_RGB, { CS_GRAY, CS_GRAY_ALPHA, CS_RGB, CS_RGB_ALPHA, CS_ICC } }, { OUT_PPM, CS_RGB, { CS_GRAY, CS_RGB } }, { OUT_PNM, CS_GRAY, { CS_GRAY, CS_RGB } }, { OUT_PAM, CS_RGB_ALPHA, { CS_GRAY, CS_GRAY_ALPHA, CS_RGB, CS_RGB_ALPHA, CS_CMYK, CS_CMYK_ALPHA } }, @@ -124,7 +124,7 @@ static const format_cs_table_t format_cs_table[] = { OUT_PCL, CS_MONO, { CS_MONO, CS_RGB } }, { OUT_PCLM, CS_RGB, { CS_RGB, CS_GRAY } }, { OUT_PS, CS_RGB, { CS_GRAY, CS_RGB, CS_CMYK } }, - { OUT_PSD, CS_CMYK, { CS_GRAY, CS_GRAY_ALPHA, CS_RGB, CS_RGB_ALPHA, CS_CMYK, CS_CMYK_ALPHA } }, + { OUT_PSD, CS_CMYK, { CS_GRAY, CS_GRAY_ALPHA, CS_RGB, CS_RGB_ALPHA, CS_CMYK, CS_CMYK_ALPHA, CS_ICC } }, { OUT_TGA, CS_RGB, { CS_GRAY, CS_GRAY_ALPHA, CS_RGB, CS_RGB_ALPHA } }, { OUT_TRACE, CS_RGB, { CS_RGB } }, @@ -246,6 +246,7 @@ static int alphabits_text = 8; static int alphabits_graphics = 8; static int out_cs = CS_UNSET; +static const char *icc_filename = NULL; static float gamma_value = 1; static int invert = 0; static int band_height = 0; @@ -1193,8 +1194,10 @@ parse_colorspace(const char *name) if (!strcmp(name, cs_name_table[i].name)) return cs_name_table[i].colorspace; } - fprintf(stderr, "Unknown colorspace \"%s\"\n", name); - exit(1); + + /* Assume ICC. We will error out later if not the case. */ + icc_filename = name; + return CS_ICC; } typedef struct @@ -1718,12 +1721,70 @@ int mudraw_main(int argc, char **argv) colorspace = fz_device_cmyk(ctx); alpha = (out_cs == CS_CMYK_ALPHA); break; + case CS_ICC: + fz_try(ctx) + colorspace = fz_new_icc_colorspace_from_file(ctx, NULL, icc_filename); + fz_catch(ctx) + { + fprintf(stderr, "Invalid ICC destination color space\n"); + exit(1); + } + if (colorspace == NULL) + { + fprintf(stderr, "Invalid ICC destination color space\n"); + exit(1); + } + alpha = 0; + break; default: fprintf(stderr, "Unknown colorspace!\n"); exit(1); break; } - colorspace = fz_keep_colorspace(ctx, colorspace); + + if (out_cs != CS_ICC) + colorspace = fz_keep_colorspace(ctx, colorspace); + else + { + int i, j, okay; + + /* Check to make sure this icc profile is ok with the output format */ + okay = 0; + for (i = 0; i < nelem(format_cs_table); i++) + { + if (format_cs_table[i].format == output_format) + { + for (j = 0; j < nelem(format_cs_table[i].permitted_cs); j++) + { + switch (format_cs_table[i].permitted_cs[j]) + { + case CS_MONO: + case CS_GRAY: + case CS_GRAY_ALPHA: + if (fz_colorspace_n(ctx, colorspace) == 1) + okay = 1; + break; + case CS_RGB: + case CS_RGB_ALPHA: + if (fz_colorspace_n(ctx, colorspace) == 3) + okay = 1; + break; + case CS_CMYK: + case CS_CMYK_ALPHA: + if (fz_colorspace_n(ctx, colorspace) == 4) + okay = 1; + break; + } + } + } + } + + if (!okay) + { + fprintf(stderr, "ICC profile uses a colorspace that cannot be used for this format\n"); + exit(1); + } + } #if FZ_ENABLE_PDF if (output_format == OUT_PDF) -- cgit v1.2.3