diff options
| author | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-09-11 14:38:47 +0900 |
|---|---|---|
| committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-09-11 14:38:47 +0900 |
| commit | 884c8093d63402a1ad0b502244b791e3c6782be3 (patch) | |
| tree | a600d4ab0d431a2bdfe4c15b70df43c14fbd8dd0 /debian/lcms/lcms-1.19.dfsg2/tifficc/tiffdiff.c | |
| parent | 14e1aa2006796f147f3f4811fb908a6b01e79253 (diff) | |
| download | extra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.tar.gz extra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.zip | |
Added debian extra dependency packages.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'debian/lcms/lcms-1.19.dfsg2/tifficc/tiffdiff.c')
| -rwxr-xr-x | debian/lcms/lcms-1.19.dfsg2/tifficc/tiffdiff.c | 776 |
1 files changed, 776 insertions, 0 deletions
diff --git a/debian/lcms/lcms-1.19.dfsg2/tifficc/tiffdiff.c b/debian/lcms/lcms-1.19.dfsg2/tifficc/tiffdiff.c new file mode 100755 index 00000000..d63ab8e0 --- /dev/null +++ b/debian/lcms/lcms-1.19.dfsg2/tifficc/tiffdiff.c @@ -0,0 +1,776 @@ +// +// Little cms +// Copyright (C) 1998-2006 Marti Maria +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + +#include "lcms.h" +#include "tiffio.h" +#include <time.h> + +// xgetopt() interface ----------------------------------------------------- + +extern int xoptind; +extern char *xoptarg; +extern int xopterr; +extern char SW; +int cdecl xgetopt(int argc, char *argv[], char *optionS); + +// ------------------------------------------------------------------------ + +static TIFF *Tiff1, *Tiff2, *TiffDiff; +static const char* TiffDiffFilename; +static const char* CGATSout; + +static LCMSBOOL Verbose = FALSE; + +typedef struct { + double n, x, x2; + double Min, Peak; + + } STAT, *LPSTAT; + + +static STAT ColorantStat[4]; +static STAT EuclideanStat; +static STAT ColorimetricStat; + +static uint16 Channels; + +static cmsHPROFILE hLab; + + +static +void ConsoleWarningHandler(const char* module, const char* fmt, va_list ap) +{ + char e[512] = { '\0' }; + if (module != NULL) + strcat(strcpy(e, module), ": "); + + vsprintf(e+strlen(e), fmt, ap); + strcat(e, "."); + if (Verbose) { + + fprintf(stderr, "\nWarning"); + fprintf(stderr, " %s\n", e); + fflush(stderr); + } +} + +static +void ConsoleErrorHandler(const char* module, const char* fmt, va_list ap) +{ + char e[512] = { '\0' }; + + if (module != NULL) + strcat(strcpy(e, module), ": "); + + vsprintf(e+strlen(e), fmt, ap); + strcat(e, "."); + fprintf(stderr, "\nError"); + fprintf(stderr, " %s\n", e); + fflush(stderr); +} + + + +// Force an error and exit w/ return code 1 + +static +void FatalError(const char *frm, ...) +{ + va_list args; + + va_start(args, frm); + ConsoleErrorHandler("TIFFDIFF", frm, args); + va_end(args); + + if (hLab) cmsCloseProfile(hLab); + if (Tiff1) TIFFClose(Tiff1); + if (Tiff2) TIFFClose(Tiff2); + if (TiffDiff) TIFFClose(TiffDiff); + + + exit(1); +} + + +static +void Help() +{ + fprintf(stderr, "Little cms TIFF compare utility. v1.0\n\n"); + + fprintf(stderr, "usage: tiffdiff [flags] input.tif output.tif\n"); + + fprintf(stderr, "\nflags:\n\n"); + + + fprintf(stderr, "%co<tiff> - Output TIFF file\n", SW); + fprintf(stderr, "%cg<CGATS> - Output results in CGATS file\n", SW); + + fprintf(stderr, "\n"); + + fprintf(stderr, "%cv - Verbose (show warnings)\n", SW); + fprintf(stderr, "%ch - This help\n", SW); + + + fflush(stderr); + exit(0); +} + + + +// The toggles stuff + +static +void HandleSwitches(int argc, char *argv[]) +{ + int s; + + while ((s=xgetopt(argc,argv,"o:O:hHvVg:G:")) != EOF) { + + switch (s) { + + + case 'v': + case 'V': + Verbose = TRUE; + break; + + case 'o': + case 'O': + TiffDiffFilename = xoptarg; + break; + + + case 'H': + case 'h': + Help(); + break; + + case 'g': + case 'G': + CGATSout = xoptarg; + break; + + default: + + FatalError("Unknown option - run without args to see valid ones"); + } + } +} + + +static +void ClearStatistics(LPSTAT st) +{ + + st ->n = st ->x = st->x2 = st->Peak = 0; + st ->Min = 1E10; + +} + + +static +void AddOnePixel(LPSTAT st, double dE) +{ + + st-> x += dE; st ->x2 += (dE * dE); st->n += 1.0; + if (dE > st ->Peak) st ->Peak = dE; + if (dE < st ->Min) st ->Min= dE; +} + +static +double Std(LPSTAT st) +{ + return sqrt((st->n * st->x2 - st->x * st->x) / (st->n*(st->n-1))); +} + +static +double Mean(LPSTAT st) +{ + return st ->x/st ->n; +} + + +// Build up the pixeltype descriptor + +static +DWORD GetInputPixelType(TIFF *Bank) +{ + uint16 Photometric, bps, spp, extra, PlanarConfig, *info; + uint16 Compression, reverse = 0; + int ColorChannels, IsPlanar = 0, pt = 0; + + TIFFGetField(Bank, TIFFTAG_PHOTOMETRIC, &Photometric); + TIFFGetFieldDefaulted(Bank, TIFFTAG_BITSPERSAMPLE, &bps); + + if (bps == 1) + FatalError("Sorry, bilevel TIFFs has nothig to do with ICC profiles"); + + if (bps != 8 && bps != 16) + FatalError("Sorry, 8 or 16 bits per sample only"); + + TIFFGetFieldDefaulted(Bank, TIFFTAG_SAMPLESPERPIXEL, &spp); + TIFFGetFieldDefaulted(Bank, TIFFTAG_PLANARCONFIG, &PlanarConfig); + + switch (PlanarConfig) + { + case PLANARCONFIG_CONTIG: IsPlanar = 0; break; + case PLANARCONFIG_SEPARATE: FatalError("Planar TIFF are not supported"); + default: + + FatalError("Unsupported planar configuration (=%d) ", (int) PlanarConfig); + } + + // If Samples per pixel == 1, PlanarConfiguration is irrelevant and need + // not to be included. + + if (spp == 1) IsPlanar = 0; + + + // Any alpha? + + TIFFGetFieldDefaulted(Bank, TIFFTAG_EXTRASAMPLES, &extra, &info); + + + ColorChannels = spp - extra; + + switch (Photometric) { + + case PHOTOMETRIC_MINISWHITE: + + reverse = 1; + + case PHOTOMETRIC_MINISBLACK: + + pt = PT_GRAY; + break; + + case PHOTOMETRIC_RGB: + + pt = PT_RGB; + break; + + + case PHOTOMETRIC_PALETTE: + + FatalError("Sorry, palette images not supported (at least on this version)"); + + case PHOTOMETRIC_SEPARATED: + if (ColorChannels == 4) + pt = PT_CMYK; + else + if (ColorChannels == 3) + pt = PT_CMY; + else + if (ColorChannels == 6) + pt = PT_HiFi; + else + if (ColorChannels == 7) + pt = PT_HiFi7; + else + if (ColorChannels == 8) + pt = PT_HiFi8; + else + if (ColorChannels == 9) + pt = PT_HiFi9; + else + if (ColorChannels == 10) + pt = PT_HiFi10; + else + if (ColorChannels == 11) + pt = PT_HiFi11; + else + if (ColorChannels == 12) + pt = PT_HiFi8; + else + if (ColorChannels == 13) + pt = PT_HiFi13; + else + if (ColorChannels == 14) + pt = PT_HiFi14; + else + if (ColorChannels == 15) + pt = PT_HiFi15; + else + FatalError("What a weird separation of %d channels?!?!", ColorChannels); + break; + + case PHOTOMETRIC_YCBCR: + TIFFGetField(Bank, TIFFTAG_COMPRESSION, &Compression); + { + uint16 subx, suby; + + pt = PT_YCbCr; + TIFFGetFieldDefaulted(Bank, TIFFTAG_YCBCRSUBSAMPLING, &subx, &suby); + if (subx != 1 || suby != 1) + FatalError("Sorry, subsampled images not supported"); + + } + break; + + case 9: + case PHOTOMETRIC_CIELAB: + pt = PT_Lab; + break; + + + case PHOTOMETRIC_LOGLUV: /* CIE Log2(L) (u',v') */ + + TIFFSetField(Bank, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_16BIT); + pt = PT_YUV; // *ICCSpace = icSigLuvData; + bps = 16; // 16 bits forced by LibTiff + break; + + default: + FatalError("Unsupported TIFF color space (Photometric %d)", Photometric); + } + + // Convert bits per sample to bytes per sample + + bps >>= 3; + + return (COLORSPACE_SH(pt)|PLANAR_SH(IsPlanar)|EXTRA_SH(extra)|CHANNELS_SH(ColorChannels)|BYTES_SH(bps)|FLAVOR_SH(reverse)); +} + + + +static +DWORD OpenEmbedded(TIFF* tiff, cmsHPROFILE* PtrProfile, cmsHTRANSFORM* PtrXform) +{ + + DWORD EmbedLen, dwFormat = 0; + LPBYTE EmbedBuffer; + + *PtrProfile = NULL; + *PtrXform = NULL; + + if (TIFFGetField(tiff, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer)) { + + *PtrProfile = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen); + + if (Verbose) { + + fprintf(stdout, "Embedded profile found : %s\n", cmsTakeProductDesc(*PtrProfile)); + fflush(stdout); + } + + dwFormat = GetInputPixelType(tiff); + *PtrXform = cmsCreateTransform(*PtrProfile, dwFormat, + hLab, TYPE_Lab_DBL, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOTPRECALC); + + } + + return dwFormat; +} + + +static +size_t PixelSize(DWORD dwFormat) +{ + return T_BYTES(dwFormat) * (T_CHANNELS(dwFormat) + T_EXTRA(dwFormat)); +} + + +static +int CmpImages(TIFF* tiff1, TIFF* tiff2, TIFF* diff) +{ + LPBYTE buf1, buf2, buf3; + int row, cols, imagewidth = 0, imagelength = 0; + uint16 Photometric; + double dE; + double dR, dG, dB, dC, dM, dY, dK; + int rc = 0; + cmsHPROFILE hProfile1 = 0, hProfile2 = 0; + cmsHTRANSFORM xform1 = 0, xform2 = 0; + DWORD dwFormat1, dwFormat2; + + + + TIFFGetField(tiff1, TIFFTAG_PHOTOMETRIC, &Photometric); + TIFFGetField(tiff1, TIFFTAG_IMAGEWIDTH, &imagewidth); + TIFFGetField(tiff1, TIFFTAG_IMAGELENGTH, &imagelength); + TIFFGetField(tiff1, TIFFTAG_SAMPLESPERPIXEL, &Channels); + + dwFormat1 = OpenEmbedded(tiff1, &hProfile1, &xform1); + dwFormat2 = OpenEmbedded(tiff2, &hProfile2, &xform2); + + + + buf1 = (LPBYTE)_TIFFmalloc(TIFFScanlineSize(tiff1)); + buf2 = (LPBYTE)_TIFFmalloc(TIFFScanlineSize(tiff2)); + + if (diff) { + + TIFFSetField(diff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); + TIFFSetField(diff, TIFFTAG_COMPRESSION, COMPRESSION_NONE); + TIFFSetField(diff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + + TIFFSetField(diff, TIFFTAG_IMAGEWIDTH, imagewidth); + TIFFSetField(diff, TIFFTAG_IMAGELENGTH, imagelength); + + TIFFSetField(diff, TIFFTAG_SAMPLESPERPIXEL, 1); + TIFFSetField(diff, TIFFTAG_BITSPERSAMPLE, 8); + + buf3 = (LPBYTE)_TIFFmalloc(TIFFScanlineSize(diff)); + } + + + + for (row = 0; row < imagelength; row++) { + + if (TIFFReadScanline(tiff1, buf1, row, 0) < 0) goto Error; + if (TIFFReadScanline(tiff2, buf2, row, 0) < 0) goto Error; + + + for (cols = 0; cols < imagewidth; cols++) { + + + + + + switch (Photometric) { + + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + + dE = fabs(buf2[cols] - buf1[cols]); + + AddOnePixel(&ColorantStat[0], dE); + AddOnePixel(&EuclideanStat, dE); + break; + + case PHOTOMETRIC_RGB: + + { + int index = 3 * cols; + + dR = fabs(buf2[index+0] - buf1[index+0]); + dG = fabs(buf2[index+1] - buf1[index+1]); + dB = fabs(buf2[index+2] - buf1[index+2]); + + dE = sqrt(dR * dR + dG * dG + dB * dB) / sqrt(3.); + } + + AddOnePixel(&ColorantStat[0], dR); + AddOnePixel(&ColorantStat[1], dG); + AddOnePixel(&ColorantStat[2], dB); + AddOnePixel(&EuclideanStat, dE); + break; + + case PHOTOMETRIC_SEPARATED: + + { + int index = 4 * cols; + + dC = fabs(buf2[index+0] - buf1[index+0]); + dM = fabs(buf2[index+1] - buf1[index+1]); + dY = fabs(buf2[index+2] - buf1[index+2]); + dK = fabs(buf2[index+3] - buf1[index+3]); + + dE = sqrt(dC * dC + dM * dM + dY * dY + dK * dK) / 2.; + } + AddOnePixel(&ColorantStat[0], dC); + AddOnePixel(&ColorantStat[1], dM); + AddOnePixel(&ColorantStat[2], dY); + AddOnePixel(&ColorantStat[3], dK); + AddOnePixel(&EuclideanStat, dE); + break; + + default: + FatalError("Unsupported channels: %d", Channels); + return 0; + } + + + if (xform1 && xform2) { + + + cmsCIELab Lab1, Lab2; + size_t index1 = cols * PixelSize(dwFormat1); + size_t index2 = cols * PixelSize(dwFormat2); + + cmsDoTransform(xform1, &buf1[index1], &Lab1, 1); + cmsDoTransform(xform2, &buf2[index2], &Lab2, 1); + + dE = cmsDeltaE(&Lab1, &Lab2); + AddOnePixel(&ColorimetricStat, dE); + } + + + if (diff) { + buf3[cols] = (BYTE) (dE + 0.5); + } + + } + + if (diff) { + + if (TIFFWriteScanline(diff, buf3, row, 0) < 0) goto Error; + } + + + } + + rc = 1; + +Error: + + if (hProfile1) cmsCloseProfile(hProfile1); + if (hProfile2) cmsCloseProfile(hProfile2); + if (xform1) cmsDeleteTransform(xform1); + if (xform2) cmsDeleteTransform(xform2); + _TIFFfree(buf1); _TIFFfree(buf2); + if (diff) { + TIFFWriteDirectory(diff); + _TIFFfree(buf3); + } + return rc; +} + + +static +void AssureShortTagIs(TIFF* tif1, TIFF* tiff2, int tag, int Val, const char* Error) +{ + uint16 v1; + + + if (!TIFFGetField(tif1, tag, &v1)) goto Err; + if (v1 != Val) goto Err; + + if (!TIFFGetField(tiff2, tag, &v1)) goto Err; + if (v1 != Val) goto Err; + + return; +Err: + FatalError("%s is not proper", Error); +} + + +static +int CmpShortTag(TIFF* tif1, TIFF* tif2, int tag) +{ + uint16 v1, v2; + + if (!TIFFGetField(tif1, tag, &v1)) return 0; + if (!TIFFGetField(tif2, tag, &v2)) return 0; + + return v1 == v2; +} + +static +int CmpLongTag(TIFF* tif1, TIFF* tif2, int tag) +{ + uint32 v1, v2; + + if (!TIFFGetField(tif1, tag, &v1)) return 0; + if (!TIFFGetField(tif2, tag, &v2)) return 0; + + return v1 == v2; +} + + +static +void EqualShortTag(TIFF* tif1, TIFF* tif2, int tag, const char* Error) +{ + if (!CmpShortTag(tif1, tif2, tag)) + FatalError("%s is different", Error); +} + + + +static +void EqualLongTag(TIFF* tif1, TIFF* tif2, int tag, const char* Error) +{ + if (!CmpLongTag(tif1, tif2, tag)) + FatalError("%s is different", Error); +} + + + +static +void AddOneCGATSRow(LCMSHANDLE hIT8, char *Name, LPSTAT st) +{ + + double Per100 = 100.0 * ((255.0 - Mean(st)) / 255.0); + + cmsIT8SetData(hIT8, Name, "SAMPLE_ID", Name); + cmsIT8SetDataDbl(hIT8, Name, "PER100_EQUAL", Per100); + cmsIT8SetDataDbl(hIT8, Name, "MEAN_DE", Mean(st)); + cmsIT8SetDataDbl(hIT8, Name, "STDEV_DE", Std(st)); + cmsIT8SetDataDbl(hIT8, Name, "MIN_DE", st ->Min); + cmsIT8SetDataDbl(hIT8, Name, "MAX_DE", st ->Peak); + +} + + +static +void CreateCGATS(const char* TiffName1, const char* TiffName2) +{ + LCMSHANDLE hIT8 = cmsIT8Alloc(); + time_t ltime; + char Buffer[256]; + + cmsIT8SetSheetType(hIT8, "TIFFDIFF"); + + + sprintf(Buffer, "Differences between %s and %s", TiffName1, TiffName2); + + cmsIT8SetComment(hIT8, Buffer); + + cmsIT8SetPropertyStr(hIT8, "ORIGINATOR", "TIFFDIFF"); + time( <ime ); + strcpy(Buffer, ctime(<ime)); + Buffer[strlen(Buffer)-1] = 0; // Remove the nasty "\n" + + cmsIT8SetPropertyStr(hIT8, "CREATED", Buffer); + + cmsIT8SetComment(hIT8, " "); + + cmsIT8SetPropertyDbl(hIT8, "NUMBER_OF_FIELDS", 6); + + + cmsIT8SetDataFormat(hIT8, 0, "SAMPLE_ID"); + cmsIT8SetDataFormat(hIT8, 1, "PER100_EQUAL"); + cmsIT8SetDataFormat(hIT8, 2, "MEAN_DE"); + cmsIT8SetDataFormat(hIT8, 3, "STDEV_DE"); + cmsIT8SetDataFormat(hIT8, 4, "MIN_DE"); + cmsIT8SetDataFormat(hIT8, 5, "MAX_DE"); + + + switch (Channels) { + + case 1: + cmsIT8SetPropertyDbl(hIT8, "NUMBER_OF_SETS", 3); + AddOneCGATSRow(hIT8, "GRAY_PLANE", &ColorantStat[0]); + break; + + case 3: + cmsIT8SetPropertyDbl(hIT8, "NUMBER_OF_SETS", 5); + AddOneCGATSRow(hIT8, "R_PLANE", &ColorantStat[0]); + AddOneCGATSRow(hIT8, "G_PLANE", &ColorantStat[1]); + AddOneCGATSRow(hIT8, "B_PLANE", &ColorantStat[2]); + break; + + + case 4: + cmsIT8SetPropertyDbl(hIT8, "NUMBER_OF_SETS", 6); + AddOneCGATSRow(hIT8, "C_PLANE", &ColorantStat[0]); + AddOneCGATSRow(hIT8, "M_PLANE", &ColorantStat[1]); + AddOneCGATSRow(hIT8, "Y_PLANE", &ColorantStat[2]); + AddOneCGATSRow(hIT8, "K_PLANE", &ColorantStat[3]); + break; + + default: FatalError("Internal error: Bad ColorSpace"); + + } + + AddOneCGATSRow(hIT8, "EUCLIDEAN", &EuclideanStat); + AddOneCGATSRow(hIT8, "COLORIMETRIC", &ColorimetricStat); + + cmsIT8SaveToFile(hIT8, CGATSout); + cmsIT8Free(hIT8); +} + +int main(int argc, char* argv[]) +{ + int i; + + Tiff1 = Tiff2 = TiffDiff = NULL; + + HandleSwitches(argc, argv); + + if ((argc - xoptind) != 2) { + + Help(); + } + + + + TIFFSetErrorHandler(ConsoleErrorHandler); + TIFFSetWarningHandler(ConsoleWarningHandler); + + Tiff1 = TIFFOpen(argv[xoptind], "r"); + if (Tiff1 == NULL) FatalError("Unable to open '%s'", argv[xoptind]); + + Tiff2 = TIFFOpen(argv[xoptind+1], "r"); + if (Tiff2 == NULL) FatalError("Unable to open '%s'", argv[xoptind+1]); + + if (TiffDiffFilename) { + + TiffDiff = TIFFOpen(TiffDiffFilename, "w"); + if (TiffDiff == NULL) FatalError("Unable to create '%s'", TiffDiffFilename); + + } + + + AssureShortTagIs(Tiff1, Tiff2, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG, "Planar Config"); + AssureShortTagIs(Tiff1, Tiff2, TIFFTAG_BITSPERSAMPLE, 8, "8 bit per sample"); + + EqualLongTag(Tiff1, Tiff2, TIFFTAG_IMAGEWIDTH, "Image width"); + EqualLongTag(Tiff1, Tiff2, TIFFTAG_IMAGELENGTH, "Image length"); + + EqualShortTag(Tiff1, Tiff2, TIFFTAG_SAMPLESPERPIXEL, "Samples per pixel"); + + + hLab = cmsCreateLabProfile(NULL); + + ClearStatistics(&EuclideanStat); + for (i=0; i < 4; i++) + ClearStatistics(&ColorantStat[i]); + + if (!CmpImages(Tiff1, Tiff2, TiffDiff)) + FatalError("Error comparing images"); + + if (CGATSout) { + CreateCGATS(argv[xoptind], argv[xoptind+1]); + } + else { + + double Per100 = 100.0 * ((255.0 - Mean(&EuclideanStat)) / 255.0); + + printf("Digital counts %g%% equal. mean %g, min %g, max %g, Std %g\n", Per100, Mean(&EuclideanStat), + EuclideanStat.Min, + EuclideanStat.Peak, + Std(&EuclideanStat)); + + if (ColorimetricStat.n > 0) { + + Per100 = 100.0 * ((255.0 - Mean(&ColorimetricStat)) / 255.0); + + printf("dE Colorimetric %g%% equal. mean %g, min %g, max %g, Std %g\n", Per100, Mean(&ColorimetricStat), + ColorimetricStat.Min, + ColorimetricStat.Peak, + Std(&ColorimetricStat)); + } + + } + + if (hLab) cmsCloseProfile(hLab); + if (Tiff1) TIFFClose(Tiff1); + if (Tiff2) TIFFClose(Tiff2); + if (TiffDiff) TIFFClose(TiffDiff); + + return 0; +} + + |
