From 22f703cab05b7cd368f4de9e03991b7664dc5022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 1 Sep 2014 13:56:46 +0200 Subject: Initial import of argyll version 1.5.1-8 --- icc/iccrw.c | 311 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 icc/iccrw.c (limited to 'icc/iccrw.c') diff --git a/icc/iccrw.c b/icc/iccrw.c new file mode 100644 index 0000000..807c5f4 --- /dev/null +++ b/icc/iccrw.c @@ -0,0 +1,311 @@ + +/* + * International Color Consortium Format Library (icclib) + * Profile read then re-write skeleton utility. + * + * Author: Graeme W. Gill + * Date: 1999/11/29 + * Version: 2.15 + * + * Copyright 1997 - 2012 Graeme W. Gill + * + * This material is licensed with an "MIT" free use license:- + * see the License.txt file in this directory for licensing details. + */ + +/* TTBD: + * + */ + +#include +#include +#include +#include +#include +#include +#include "icc.h" + +#undef TEST_VIDGAMTAG /* Add ColorSync 2.5 VideoCardGamma tag with linear table */ +#undef TEST_SRGB_FIX /* Some test code */ +#undef WP_PATCH /* Overwrite the white point */ +#undef INVERT_GRAY /* Invert single TRC gray profile */ +#undef MOD_A2B /* 0 */ /* Modify A2B RGB tables */ + +void error(char *fmt, ...), warning(char *fmt, ...); + +void usage(void) { + fprintf(stderr,"Read and then re-write an ICC profile V%s\n",ICCLIB_VERSION_STR); + fprintf(stderr,"Author: Graeme W. Gill\n"); + fprintf(stderr,"usage: iccrw readprofile writeprofile\n"); + exit(1); +} + +int +main(int argc, char *argv[]) { + int fa,nfa; /* argument we're looking at */ + char in_name[500]; + char out_name[500]; + icmFile *rd_fp, *wr_fp; + icc *icco; + int verb = 0; + int rv = 0; + + if (argc < 3) + usage(); + + /* Process the arguments */ + for(fa = 1;fa < argc;fa++) { + nfa = fa; /* skip to nfa if next argument is used */ + if (argv[fa][0] == '-') { /* Look for any flags */ + char *na = NULL; /* next argument after flag, null if none */ + + if (argv[fa][2] != '\000') + na = &argv[fa][2]; /* next is directly after flag */ + else { + if ((fa+1) < argc) { + if (argv[fa+1][0] != '-') { + nfa = fa + 1; + na = argv[nfa]; /* next is seperate non-flag argument */ + } + } + } + + if (argv[fa][1] == '?') + usage(); + + if (argv[fa][1] == 'v' || argv[fa][1] == 'V') + verb = 1; + + /* No options */ + usage(); + + } else + break; + } + + if (fa >= argc || argv[fa][0] == '-') usage(); + strcpy(in_name,argv[fa++]); + + if (fa >= argc || argv[fa][0] == '-') usage(); + strcpy(out_name,argv[fa]); + + /* Open up the profile for reading */ + if ((rd_fp = new_icmFileStd_name(in_name,"r")) == NULL) + error ("Can't open file '%s'",in_name); + + if ((icco = new_icc()) == NULL) + error ("Creation of ICC object failed"); + + /* Read header etc. */ + if ((rv = icco->read(icco,rd_fp,0)) != 0) + error ("%d, %s",rv,icco->err); + + /* Read every tag */ + if (icco->read_all_tags(icco) != 0) { + error("Unable to read all tags: %d, %s",icco->errc,icco->err); + } + + rd_fp->del(rd_fp); + + /* ======================================= */ + /* Change profile in here. */ + +#ifdef TEST_SRGB_FIX /* Some test code */ + /* Try deleting the black point tag */ + { + if (icco->delete_tag(icco, icSigMediaBlackPointTag) != 0) { + error("Unable to delete blackpoint tag: %d, %s",icco->errc,icco->err); + } + } + + /* Fix up sRGB profile curve */ + { + icmCurve *ro; + int i; + + /* Try and read the tag from the file */ + ro = (icmCurve *)icco->read_tag(icco, icSigRedTRCTag); + if (ro == NULL) + error("Unable to read rTRC"); + + /* Need to check that the cast is appropriate. */ + if (ro->ttype != icSigCurveType) + error("rTRC is not CurveType"); + + for (i = 0; i < ro->size; i++) { + double vi, vo; + vi = i/(double)(ro->size-1); + + if (vi < 0.04045) { + vo = vi/12.92; + } else { + vo = pow((0.055+vi)/1.055,2.4); + } + ro->data[i] = vo; + } + } + + /* Show we modified this ICC file */ + icco->header->cmmId = str2tag("argl"); /* CMM for profile - Argyll CMM */ +#endif + +#ifdef TEST_VIDGAMTAG + /* delete video card gamma tag (c/o Neil Okamoto) */ + { + if (icco->find_tag(icco, icSigVideoCardGammaTag) == 0) + if (icco->delete_tag(icco, icSigVideoCardGammaTag) != 0) + error("Unable to delete videocardgamma tag: %d, %s",icco->errc,icco->err); + } + /* Add a video card gamma table */ + { + int c,i; + icmVideoCardGamma *wo; + wo = (icmVideoCardGamma *)icco->add_tag(icco, icSigVideoCardGammaTag, icSigVideoCardGammaType); + if (wo == NULL) + error ("Unable to add VideoCardGamma tag"); + + wo->tagType = icmVideoCardGammaTableType; + wo->u.table.channels = 3; /* rgb */ + wo->u.table.entryCount = 256; /* full lut */ + wo->u.table.entrySize = 1; /* byte */ + wo->allocate((icmBase*)wo); + for (c=0; c<3; c++) + for (i=0; i<256; i++) + ((unsigned char*)wo->u.table.data)[256*c+i] = 255-i; + } + + /* Show we modified this ICC file */ + icco->header->cmmId = str2tag("argl"); /* CMM for profile - Argyll CMM */ +#endif + +#ifdef WP_PATCH /* Overwrite the white point */ + /* delete white point tag */ + { + if (icco->find_tag(icco, icSigMediaWhitePointTag) == 0) + if (icco->delete_tag(icco, icSigMediaWhitePointTag) != 0) + error("Unable to delete white point tag tag: %d, %s",icco->errc,icco->err); + } + /* Add a new white point tag */ + { + double lab[3]; + icmXYZArray *wo; + /* Note that tag types icSigXYZType and icSigXYZArrayType are identical */ + if ((wo = (icmXYZArray *)icco->add_tag( + icco, icSigMediaWhitePointTag, icSigXYZArrayType)) == NULL) + error("add_tag failed: %d, %s",icco->errc, icco->err); + + wo->size = 1; + wo->allocate((icmBase *)wo); /* Allocate space */ + lab[0] = 79.8296; + lab[1] = -0.004042 + 0.842312; + lab[2] = 3.019928 + 0.810044; + icmLab2XYZ(&icmD50, lab, lab); + icmAry2XYZ(wo->data[0], lab); + } + + /* Show we modified this ICC file */ + icco->header->cmmId = str2tag("argl"); /* CMM for profile - Argyll CMM */ +#endif +#ifdef INVERT_GRAY /* Invert single TRC gray profile */ + { + icmCurve *ro; + int i; + + /* Try and read the tag from the file */ + ro = (icmCurve *)icco->read_tag(icco, icSigGrayTRCTag); + if (ro == NULL) + error("Unable to read GrayTRC"); + + /* Need to check that the cast is appropriate. */ + if (ro->ttype != icSigCurveType) + error("GrayTRC is not CurveType"); + + /* Swap the curve entries from top to bottom */ + for (i = 0; i < (ro->size/2); i++) { + double temp; + int ii = 255 - i; + + temp = ro->data[ii]; + ro->data[ii] = ro->data[i]; + ro->data[i] = temp; + } + } + +#endif + +#ifdef MOD_A2B + { + icmLut *ro; + unsigned long size; + unsigned int i, j; + icTagSignature sig; + + if (MOD_A2B == 0) + sig = icSigAToB0Tag; + else if (MOD_A2B == 1) + sig = icSigAToB1Tag; + else + sig = icSigAToB2Tag; + + /* Try and read the tag from the file */ + ro = (icmLut *)icco->read_tag(icco, sig); + if (ro == NULL) + error("Failed to read A2B tag"); + + /* Need to check that the cast is appropriate. */ + if (ro->ttype != icSigLut16Type) + error("A2B is not 16 bitg"); + + /* Simply apply a gamma to the corresponding input curve */ + for (i = 0; i < ro->inputChan; i++) { /* Input tables */ + double val; + j = MOD_A2B; + val = ro->inputTable[i * ro->inputEnt + j]; + val = pow(val, 2.0); + ro->inputTable[i * ro->inputEnt + j] = val; + } + } +#endif /* MOD_A2B */ + + /* ======================================= */ + + /* Open up the other profile for writing */ + if ((wr_fp = new_icmFileStd_name(out_name,"w")) == NULL) + error ("Can't open file '%s'",out_name); + + if ((rv = icco->write(icco,wr_fp,0)) != 0) + error ("Write file: %d, %s",rv,icco->err); + + icco->del(icco); + wr_fp->del(wr_fp); + + return 0; +} + +/* ------------------------------------------------ */ +/* Basic printf type error() and warning() routines */ + +void +error(char *fmt, ...) +{ + va_list args; + + fprintf(stderr,"iccrw: Error - "); + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + fprintf(stderr, "\n"); + exit (-1); +} + +void +warning(char *fmt, ...) +{ + va_list args; + + fprintf(stderr,"iccrw: Warning - "); + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + fprintf(stderr, "\n"); +} -- cgit v1.2.3