/* * International Color Consortium Format Library (icclib) * Profile read then re-write skeleton utility. * * Author: Graeme W. Gill * Date: 99/11/29 * Version: 2.00 * * Copyright 1997, 1998, 1999, 2000, 2001 Graeme W. Gill * Please refer to Licence.txt file for 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 */ void error(char *fmt, ...), warning(char *fmt, ...); void usage(void) { fprintf(stderr,"Read and then re-write an ICC profile V2.00\n"); 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[100]; char out_name[100]; icmFile *rd_fp, *wr_fp; icc *icco; int i; 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(); /* 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.03928) { 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 /* ======================================= */ /* 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"); }