/* $Xorg: loadData.c,v 1.4 2000/08/17 19:54:13 cpqbld Exp $ */ /* * (c) Copyright 1990 Tektronix Inc. * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Tektronix not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. * * Tektronix disclaims all warranties with regard to this software, including * all implied warranties of merchantability and fitness, in no event shall * Tektronix be liable for any special, indirect or consequential damages or * any damages whatsoever resulting from loss of use, data or profits, * whether in an action of contract, negligence or other tortious action, * arising out of or in connection with the use or performance of this * software. * * * NAME * LoadSCCData.c * * DESCRIPTION * TekCMS API routine that reads screen data from a file * and then loads the data on the root window of the screen. * * * */ /* $XFree86: xc/programs/xcmsdb/loadData.c,v 3.3 2001/07/25 15:05:18 dawes Exp $ */ /* * INCLUDES */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "SCCDFile.h" /* * EXTERNS * External declarations required locally to this package * that are not already declared in any of the included header * files (external includes or internal includes). */ #include /* * LOCAL TYPEDEFS * typedefs local to this package (for use with local vars). * */ typedef const struct _DefineEntry { const char *pString; int define; } DefineEntry; /* * LOCAL VARIABLES */ static int linenum = 0; static DefineEntry KeyTbl[] = { { SC_BEGIN_KEYWORD, SC_BEGIN }, { SC_END_KEYWORD, SC_END }, { COMMENT_KEYWORD, COMMENT }, { NAME_KEYWORD, NAME }, { MODEL_KEYWORD, MODEL }, { PART_NUMBER_KEYWORD, PART_NUMBER }, { SERIAL_NUMBER_KEYWORD, SERIAL_NUMBER }, { REVISION_KEYWORD, REVISION }, { SCREEN_CLASS_KEYWORD, SCREEN_CLASS }, { COLORIMETRIC_BEGIN_KEYWORD, COLORIMETRIC_BEGIN }, { COLORIMETRIC_END_KEYWORD, COLORIMETRIC_END }, { XYZTORGBMAT_BEGIN_KEYWORD, XYZTORGBMAT_BEGIN }, { XYZTORGBMAT_END_KEYWORD, XYZTORGBMAT_END }, { WHITEPT_XYZ_BEGIN_KEYWORD, WHITEPT_XYZ_BEGIN }, { WHITEPT_XYZ_END_KEYWORD, WHITEPT_XYZ_END }, { RGBTOXYZMAT_BEGIN_KEYWORD, RGBTOXYZMAT_BEGIN }, { RGBTOXYZMAT_END_KEYWORD, RGBTOXYZMAT_END }, { IPROFILE_BEGIN_KEYWORD, IPROFILE_BEGIN }, { IPROFILE_END_KEYWORD, IPROFILE_END }, { ITBL_BEGIN_KEYWORD, ITBL_BEGIN }, { ITBL_END_KEYWORD, ITBL_END }, { "", -1 } }; static DefineEntry ScrnClassTbl[] = { { VIDEO_RGB_KEYWORD, VIDEO_RGB }, #ifdef GRAY { VIDEO_GRAY_KEYWORD, VIDEO_GRAY }, #endif /* GRAY */ { "", -1 } }; #define KEY_VISUALID 1 #define KEY_DEPTH 2 #define KEY_CLASS 3 #define KEY_RED_MASK 4 #define KEY_GREEN_MASK 5 #define KEY_BLUE_MASK 6 #define KEY_COLORMAP_SIZE 7 #define KEY_BITS_PER_RGB 8 static DefineEntry VisualOptKeyTbl[] = { { "visualid", KEY_VISUALID }, { "depth", KEY_DEPTH }, { "class", KEY_CLASS }, { "red_mask", KEY_RED_MASK }, { "green_mask", KEY_GREEN_MASK }, { "blue_mask", KEY_BLUE_MASK }, { "colormap_size", KEY_COLORMAP_SIZE }, { "bits_per_rgb", KEY_BITS_PER_RGB }, { "", -1 } }; static DefineEntry VisualClassTbl[] = { { "StaticGray", StaticGray }, { "GrayScale", GrayScale }, { "StaticColor", StaticColor }, { "PseudoColor", PseudoColor }, { "TrueColor", TrueColor }, { "DirectColor", DirectColor }, { "", -1 } }; /************************************************************************ * * * PRIVATE ROUTINES * * * ************************************************************************/ /* * NAME * StrToDefine - convert a string to a define * * SYNOPSIS */ static int StrToDefine(DefineEntry pde[], /* IN: table of X string-define pairs */ /* last entry must contain pair "", 0 */ const char *pstring) /* IN: string to be looked up in that table */ /* * DESCRIPTION * Converts a string to an integer define. * * Looks up the string in the table and returns the integer * associated with the string. * * Later may need similar function for unsigned long define. * * * * RETURNS * The int equivalent of the defined string. * -1 if the string is not found in table * */ { while (strcmp(pde->pString, "") != 0) { if (strcmp(pde->pString, pstring) == 0) { return (pde->define); } pde++; } return (-1); } /* * NAME * DefineToStr * * SYNOPSIS */ static const char * DefineToStr(DefineEntry pde[], /* IN: table of X string-define pairs */ /* last entry must contain pair "", 0 */ int id) /* IN: id to be looked up in that table */ /* * DESCRIPTION * Converts an integer define to a string. * * Looks up the integer in the table and returns the string * associated with the integer. * * Later may need similar function for unsigned long define. * * * * RETURNS * The int equivalent of the defined string. * NULL if the string is not found in table * */ { while (pde->define != -1) { if (pde->define == id) { return (pde->pString); } pde++; } return (NULL); } /* * NAME * SCKeyOf - convert keyword into key ID * * SYNOPSIS */ static int SCKeyOf(const char *string) /* * DESCRIPTION * Converts a string to an integer define. * * Looks up the string in the table and returns the integer * associated with the string. * * Later may need similar function for unsigned long define. * * * * RETURNS * The int equivalent of the defined string. * -1 if the string is not found in table * */ { return (StrToDefine(KeyTbl, string)); } /* * NAME * SCScrnClassOf - convert screen class string into class ID * * SYNOPSIS */ static int SCScrnClassOf(const char *string) /* * DESCRIPTION * Converts a string to an integer define. * * Looks up the string in the table and returns the integer * associated with the string. * * Later may need similar function for unsigned long define. * * * * RETURNS * The int equivalent of the defined string. * -1 if the string is not found in table * */ { return (StrToDefine(ScrnClassTbl, string)); } /* * NAME * SCScrnClassStringOf - convert screen class id into class string * * SYNOPSIS */ static const char * SCScrnClassStringOf(int id) /* * DESCRIPTION * Converts a id to astring * * RETURNS * Pointer to string if found; otherwise "unknown". * */ { const char *str = DefineToStr(ScrnClassTbl, id); if (str != NULL) return str; else return "unknown"; } /* close the stream and return any memory allocated. */ static void closeS(FILE *stream, XDCCC_Correction *pCorrection) { if (stream) { fclose(stream); } while (pCorrection) { XDCCC_Correction *pNext = pCorrection->next; free(pCorrection); pCorrection = pNext; } } /* * Get a line of text from the stream. */ static char * nextline(char *buf, int maxch, FILE *stream) { linenum++; return (fgets(buf, maxch, stream)); } static int ProcessColorimetric(FILE *stream, XDCCC_Matrix *pMatrix, int VisualFlag) { char buf[BUFSIZ]; char keyword[BUFSIZ]; char token[BUFSIZ]; unsigned int matrices_processed = 0; /* bit 0 for XYZtoRGB matrix */ /* bit 1 for RGBtoXYZ matrix */ int state = 0; /* 0 -- looking for matrix */ /* 1 -- processing data from matrix */ /* 2 -- both matrices processed */ /* Note: the order of the matrices is not important. */ int count = -1; XcmsFloat *pElement = NULL; while ((nextline(buf, BUFSIZ, stream)) != NULL) { int ntok = sscanf(buf, "%1023s %1023s", keyword, token); if (ntok > 0) { switch (SCKeyOf(keyword)) { case XYZTORGBMAT_BEGIN: if (VisualFlag != VIDEO_RGB) { fprintf(stderr, "Line %d: Keyword XYZTORGBMAT_BEGIN mismatch for visual %s.\n", linenum, SCScrnClassStringOf(VisualFlag)); return (0); } if (state != 0) { fprintf(stderr, "Line %d: Extraneous keyword %s.\n", linenum, keyword); return (0); } state = 1; count = 0; pElement = (XcmsFloat *) pMatrix->XYZtoRGBmatrix; break; case XYZTORGBMAT_END: if (VisualFlag != VIDEO_RGB) { fprintf(stderr, "Line %d: Keyword XYZTORGBMAT_END mismatch for visual %s.\n", linenum, SCScrnClassStringOf(VisualFlag)); return (0); } if ((state != 1) || (count != 9)) { fprintf(stderr, "Line %d: Incomplete XYZtoRGB matrix -- Premature %s\n", linenum, keyword); return (0); } matrices_processed |= 0x1; if (matrices_processed == 3) { state = 2; } else { state = 0; } break; case RGBTOXYZMAT_BEGIN: if (VisualFlag != VIDEO_RGB) { fprintf(stderr, "Line %d: Keyword RGBTOXYZMAT_BEGIN mismatch for visual %s.\n", linenum, SCScrnClassStringOf(VisualFlag)); return (0); } if (state != 0) { fprintf(stderr, "Line %d: Extraneous keyword %s.\n", linenum, keyword); return (0); } state = 1; count = 0; pElement = (XcmsFloat *) pMatrix->RGBtoXYZmatrix; break; case RGBTOXYZMAT_END: if (VisualFlag != VIDEO_RGB) { fprintf(stderr, "Line %d: Keyword RGBTOXYZMAT_END mismatch for visual %s.\n", linenum, SCScrnClassStringOf(VisualFlag)); return (0); } if ((state != 1) || (count != 9)) { fprintf(stderr, "Line %d: Incomplete RGBtoXYZ matrix -- Premature %s\n", linenum, keyword); return (0); } matrices_processed |= 0x2; if (matrices_processed == 3) { state = 2; } else { state = 0; } break; #ifdef GRAY case WHITEPT_XYZ_BEGIN: if (VisualFlag != VIDEO_GRAY) { fprintf(stderr, "Line %d: Keyword WHITEPT_XYZ_BEGIN mismatch for visual %s.\n", linenum, SCScrnClassStringOf(VisualFlag)); return (0); } if (state != 0) { fprintf(stderr, "Line %d: Extraneous keyword %s.\n", linenum, keyword); return (0); } state = 1; count = 0; pElement = (XcmsFloat *) pMatrix->XYZtoRGBmatrix; break; case WHITEPT_XYZ_END: if (VisualFlag != VIDEO_GRAY) { fprintf(stderr, "Line %d: Keyword WHITEPT_XYZ_END mismatch for visual %s.\n", linenum, SCScrnClassStringOf(VisualFlag)); return (0); } if ((state != 1) || (count != 3)) { fprintf(stderr, "Line %d: Incomplete white point -- Premature %s\n", linenum, keyword); return (0); } state = 2; break; #endif /* GRAY */ case DATA: for (char *ptoken = strtok(buf, DATA_DELIMS); ptoken != NULL; ptoken = strtok(NULL, DATA_DELIMS)) { if (sscanf(ptoken, "%lf", pElement) != 1) { if (VisualFlag == VIDEO_RGB) { fprintf(stderr, "Line %d: Invalid matrix value %s.", linenum, ptoken); } else { fprintf(stderr, "Line %d: Invalid CIEXYZ value %s.\n", linenum, ptoken); } return (0); } pElement++; if (VisualFlag == VIDEO_RGB) { if (++count > 9) { fprintf(stderr, "Line %d: Extra matrix value %s\n", linenum, ptoken); return (0); } } else { if (++count > 3) { fprintf(stderr, "Line %d: Extra CIEXYZ value %s.\n", linenum, ptoken); return (0); } } } break; case COLORIMETRIC_BEGIN: fprintf(stderr, "Line %d: Extraneous keyword %s.\n", linenum, keyword); return (0); case COLORIMETRIC_END: if (state != 2) { fprintf(stderr, "Line %d: Incomplete Colorimetric data -- Premature %s\n", linenum, keyword); return (0); } return (1); case COMMENT: /* Currently, do nothing. */ break; default: fprintf(stderr, "Line %d: Unexpected keyword %s\n", linenum, keyword); return (0); } } else if (ntok < 0) { /* mismatch */ fprintf(stderr, "Line %d: Unrecognized keyword\n", linenum); return (0); } } return (0); } static int ProcessIProfile(FILE *stream, XDCCC_Correction *pCorrection) { char buf[BUFSIZ]; char *tableStr, *sizeStr; int size; int state = 0; /************************************************ * 0 -- Looking for Intensity Table(s) * * 1 -- Processing Intensity Table(s) * ************************************************/ int nTbl = 0; int count = 0; IntensityRec *pIRec = NULL; while ((nextline(buf, BUFSIZ, stream)) != NULL) { char *ptoken = strtok(buf, DATA_DELIMS); char *keyword = ptoken; if (keyword != NULL) { switch (SCKeyOf(keyword)) { case ITBL_BEGIN: if (state != 0) { fprintf(stderr, "Line %d: unexpected keyword %s\n", linenum, keyword); return (0); } tableStr = strtok(NULL, DATA_DELIMS); sizeStr = strtok(NULL, DATA_DELIMS); if ((sizeStr == NULL) || sscanf(sizeStr, "%d", &size) != 1) { fprintf(stderr, "Line %d: invalid Intensity Table size, %s.\n", linenum, sizeStr ? sizeStr : "\"\""); return (0); } if (size < 0) { fprintf(stderr, "Line %d: count %d < 0 for Intensity Table.\n", linenum, size); return (0); } if (strcmp(tableStr, "GREEN") == 0) { if (pCorrection->nTables != 3) { fprintf(stderr, "Line %d: incorrect number of tables\n", linenum); return (0); } if (pCorrection->pGreenTbl->pBase != NULL) { fprintf(stderr, "Line %d: multiple GREEN Intensity Profiles\n", linenum); return (0); } pCorrection->pGreenTbl->nEntries = size; pCorrection->pGreenTbl->pBase = calloc(size, sizeof(IntensityRec)); if (pCorrection->pGreenTbl->pBase == NULL) { fprintf(stderr, "Line %d: Unable to allocate space for GREEN Intensity Profile\n", linenum); return (0); } pIRec = pCorrection->pGreenTbl->pBase; } else if (strcmp(tableStr, "BLUE") == 0) { if (pCorrection->nTables != 3) { fprintf(stderr, "Line %d: incorrect number of tables\n", linenum); return (0); } if (pCorrection->pBlueTbl->pBase != NULL) { fprintf(stderr, "Line %d: multiple BLUE Intensity Profiles\n", linenum); return (0); } pCorrection->pBlueTbl->nEntries = size; pCorrection->pBlueTbl->pBase = calloc(size, sizeof(IntensityRec)); if (pCorrection->pBlueTbl->pBase == NULL) { fprintf(stderr, "Line %d: Unable to allocate space for BLUE Intensity Profile\n", linenum); return (0); } pIRec = pCorrection->pBlueTbl->pBase; } else { if (!strcmp(tableStr, "RGB") && pCorrection->nTables != 1) { fprintf(stderr, "Line %d: multiple RGB Intensity Tables", linenum); return (0); } if (pCorrection->pRedTbl->pBase != NULL) { fprintf(stderr, "Line %d: multiple RED or GREEN or BLUE Intensity Tables\n", linenum); return (0); } pCorrection->pRedTbl->nEntries = size; pCorrection->pRedTbl->pBase = calloc(size, sizeof(IntensityRec)); if (pCorrection->pRedTbl->pBase == NULL) { fprintf(stderr, "Line %d: Unable to allocate space for intensity table\n", linenum); return (0); } pIRec = pCorrection->pRedTbl->pBase; } state = 1; count = 0; break; case ITBL_END: if ((state != 1) || (count != size)) { fprintf(stderr, "Line %d: incomplete Intensity Table -- Premature %s\n", linenum, keyword); return (0); } nTbl++; state = 0; break; case DATA: if (pIRec == NULL) { fprintf(stderr, "Line %d: Invalid Intensity Profile -- Premature %s\n", linenum, keyword); return (0); } do { /******************************************************** * Note: tableType should only be 0 or 1 at this point. * 0 indicates value and intensity stored. * 1 indicates only intensity stored. ********************************************************/ if (pCorrection->tableType) { if (sscanf(ptoken, "%lf", &pIRec->intensity) != 1) { fprintf(stderr, "Line %d: invalid Intensity Profile value %s\n", linenum, ptoken); return (0); } /* With tableType 1 only store the intensity. */ pIRec++; } else { short tmp; /* Note ANSI C can handle 0x preceding hex number */ if (sscanf(ptoken, "%hi", &tmp) != 1) { fprintf(stderr, "Line %d: invalid Intensity Profile value %s\n", linenum, ptoken); return (0); } else pIRec->value = tmp; if ((ptoken = strtok(NULL, DATA_DELIMS)) == NULL) { fprintf(stderr, "Line %d: missing Intensity Profile value\n", linenum); return (0); } if (sscanf(ptoken, "%lf", &pIRec->intensity) != 1) { fprintf(stderr, "Line %d: invalid Intensity Profile intensity %s\n", linenum, ptoken); return (0); } /* With tableType 0 only store both value & intensity */ pIRec++; } if (++count > size) { fprintf(stderr, "Line %d: extra Intensity value %s\n", linenum, ptoken); return (0); } ptoken = strtok(NULL, DATA_DELIMS); } while (ptoken != NULL); break; case IPROFILE_BEGIN: fprintf(stderr, "Line %d: extraneous keyword %s\n", linenum, keyword); return (0); case IPROFILE_END: if ((state != 0) || (nTbl != pCorrection->nTables)) { fprintf(stderr, "Line %d: incomplete Intensity Profile data -- Premature %s\n", linenum, keyword); return (0); } return (1); case COMMENT: /* ignore line */ break; default: fprintf(stderr, "Line %d: unexpected keyword %s\n", linenum, keyword); return (0); } } /* else its was just a blank line */ } return (0); } static void PutTableType0Card8(IntensityTbl *pTbl, unsigned char **pCard8) { unsigned int count; IntensityRec *pIRec; pIRec = pTbl->pBase; count = pTbl->nEntries; **pCard8 = count - 1; *pCard8 += 1; for (; count; count--, pIRec++) { **pCard8 = pIRec->value >> 8; *pCard8 += 1; **pCard8 = pIRec->intensity * 255.0; *pCard8 += 1; } } static void PutTableType1Card8(IntensityTbl *pTbl, unsigned char **pCard8) { unsigned int count; IntensityRec *pIRec; pIRec = pTbl->pBase; count = pTbl->nEntries; **pCard8 = count - 1; *pCard8 += 1; for (; count; count--, pIRec++) { **pCard8 = pIRec->intensity * 255.0; *pCard8 += 1; } } static void PutTableType0Card16(IntensityTbl *pTbl, unsigned short **pCard16) { unsigned int count; IntensityRec *pIRec; pIRec = pTbl->pBase; count = pTbl->nEntries; **pCard16 = count - 1; *pCard16 += 1; for (; count; count--, pIRec++) { **pCard16 = pIRec->value; *pCard16 += 1; **pCard16 = pIRec->intensity * 65535.0; *pCard16 += 1; } } static void PutTableType1Card16(IntensityTbl *pTbl, unsigned short **pCard16) { unsigned int count; IntensityRec *pIRec; pIRec = pTbl->pBase; count = pTbl->nEntries; **pCard16 = count - 1; *pCard16 += 1; for (; count; count--, pIRec++) { **pCard16 = pIRec->intensity * 65535.0; *pCard16 += 1; } } static void PutTableType0Card32(IntensityTbl *pTbl, unsigned long **pCard32) { unsigned int count; IntensityRec *pIRec; pIRec = pTbl->pBase; count = pTbl->nEntries; **pCard32 = count - 1; *pCard32 += 1; for (; count; count--, pIRec++) { **pCard32 = pIRec->value; *pCard32 += 1; **pCard32 = pIRec->intensity * 4294967295.0; *pCard32 += 1; } } static void PutTableType1Card32(IntensityTbl *pTbl, unsigned long **pCard32) { unsigned int count; IntensityRec *pIRec; pIRec = pTbl->pBase; count = pTbl->nEntries; **pCard32 = count - 1; *pCard32 += 1; for (; count; count--, pIRec++) { **pCard32 = pIRec->intensity * 4294967295.0; *pCard32 += 1; } } static void LoadMatrix(Display * pDpy, Window root, XDCCC_Matrix * pMatrix) { int count; unsigned long *pCard32; unsigned long Card32Array[18]; Atom MatricesAtom; XcmsFloat *pValue; /* * Store the XDCCC_LINEAR_RGB_MATRICES */ pCard32 = Card32Array; pValue = (XcmsFloat *) pMatrix->XYZtoRGBmatrix; for (count = 0; count < 9; count++) { *pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER); } pValue = (XcmsFloat *) pMatrix->RGBtoXYZmatrix; for (count = 0; count < 9; count++) { *pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER); } MatricesAtom = XInternAtom(pDpy, XDCCC_MATRIX_ATOM_NAME, False); XChangeProperty(pDpy, root, MatricesAtom, XA_INTEGER, 32, PropModeReplace, (unsigned char *) Card32Array, 18); } static int LoadCorrections(Display *pDpy, Window root, XDCCC_Correction *pCorrection, int targetFormat) { unsigned char *pCard8; unsigned char *pCard8Array = NULL; unsigned short *pCard16; unsigned short *pCard16Array = NULL; unsigned long *pCard32; unsigned long *pCard32Array = NULL; Atom CorrectAtom; int total; int i; /* * Store each XDCCC_CORRECTION into XDCCC_LINEAR_RGB_CORRECTION property */ CorrectAtom = XInternAtom(pDpy, XDCCC_CORRECT_ATOM_NAME, False); for (i = 0; pCorrection; i++, pCorrection = pCorrection->next) { if ((pCorrection->tableType != 0) && (pCorrection->tableType != 1)) { if (pCorrection->visual_info.visualid) { fprintf(stderr, "RGB Correction for visualid %ld: Invalid intensity table type %d.\n", pCorrection->visual_info.visualid, pCorrection->tableType); } else { fprintf(stderr, "Global RGB Correction: Invalid intensity table type %d.\n", pCorrection->tableType); } return (0); } if (pCorrection->nTables != 1 && pCorrection->nTables != 3) { if (pCorrection->visual_info.visualid) { fprintf(stderr, "RGB Correction for visualid %ld: %d invalid number of tables.\n", pCorrection->visual_info.visualid, pCorrection->nTables); } else { fprintf(stderr, "Global RGB Correction: %d invalid number of tables.\n", pCorrection->nTables); } return (0); } if (pCorrection->nTables == 1) { if (pCorrection->pRedTbl->nEntries < 2) { if (pCorrection->visual_info.visualid) { fprintf(stderr, "RGB Correction for visualid %ld: Illegal number of entries in table\n", pCorrection->visual_info.visualid); } else { fprintf(stderr, "Global RGB Correction: Illegal number of entries in table\n"); } return (0); } switch (targetFormat) { case 8: total = 7 + (pCorrection->pRedTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)); pCard8 = pCard8Array = calloc(total, sizeof(unsigned char)); if (pCard8 == NULL) { fprintf(stderr, "Unable allocate array of ints\n"); return (0); } *pCard8++ = (pCorrection->visual_info.visualid >> 24) & 0xFF; *pCard8++ = (pCorrection->visual_info.visualid >> 16) & 0xFF; *pCard8++ = (pCorrection->visual_info.visualid >> 8) & 0xFF; *pCard8++ = (pCorrection->visual_info.visualid) & 0xFF; *pCard8++ = pCorrection->tableType; /* type */ *pCard8++ = 1; /* number of tables = 1 */ if (pCorrection->tableType == 0) { PutTableType0Card8(pCorrection->pRedTbl, &pCard8); } else { PutTableType1Card8(pCorrection->pRedTbl, &pCard8); } XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 8, i ? PropModeAppend : PropModeReplace, (unsigned char *) pCard8Array, total); free(pCard8Array); break; case 16: total = 5 + (pCorrection->pRedTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)); pCard16 = pCard16Array = calloc(total, sizeof (unsigned short)); if (pCard16 == NULL) { fprintf(stderr, "Unable allocate array of ints\n"); return (0); } *pCard16++ = (pCorrection->visual_info.visualid >> 16) & 0xFFFF; *pCard16++ = (pCorrection->visual_info.visualid) & 0xFFFF; *pCard16++ = pCorrection->tableType; /* type */ *pCard16++ = 1; /* number of tables = 1 */ if (pCorrection->tableType == 0) { PutTableType0Card16(pCorrection->pRedTbl, &pCard16); } else { PutTableType1Card16(pCorrection->pRedTbl, &pCard16); } XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 16, i ? PropModeAppend : PropModeReplace, (unsigned char *) pCard16Array, total); free(pCard16Array); break; case 32: total = 4 + (pCorrection->pRedTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)); pCard32 = pCard32Array = calloc(total, sizeof(unsigned long)); if (pCard32 == NULL) { fprintf(stderr, "Unable allocate array of ints\n"); return (0); } *pCard32++ = pCorrection->visual_info.visualid; *pCard32++ = pCorrection->tableType; /* type */ *pCard32++ = 1; /* number of tables = 1 */ if (pCorrection->tableType == 0) { PutTableType0Card32(pCorrection->pRedTbl, &pCard32); } else { PutTableType1Card32(pCorrection->pRedTbl, &pCard32); } XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 32, i ? PropModeAppend : PropModeReplace, (unsigned char *) pCard32Array, total); free(pCard32Array); break; default: if (pCorrection->visual_info.visualid) { fprintf(stderr, "RGB Correction for visualid %ld: Invalid property format\n", pCorrection->visual_info.visualid); } else { fprintf(stderr, "Global RGB Correction: Invalid property format\n"); } return (0); } } else { /* pCorrection->nTables == 3 */ if ((pCorrection->pRedTbl->nEntries < 2) || (pCorrection->pGreenTbl->nEntries < 2) || (pCorrection->pBlueTbl->nEntries < 2)) { if (pCorrection->visual_info.visualid) { fprintf(stderr, "RGB Correction for visualid %ld: Illegal number of entries in table\n", pCorrection->visual_info.visualid); } else { fprintf(stderr, "Global RGB Correction: Illegal number of entries in table\n"); } return (0); } switch (targetFormat) { case 8: total = 9 + /* visualID, type, and 3 lengths */ (pCorrection->pRedTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) + (pCorrection->pGreenTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) + (pCorrection->pBlueTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)); pCard8 = pCard8Array = calloc(total, sizeof(unsigned char)); if (pCard8 == NULL) { fprintf(stderr, "Unable allocate array of ints\n"); return (0); } *pCard8++ = (pCorrection->visual_info.visualid >> 24) & 0xFF; *pCard8++ = (pCorrection->visual_info.visualid >> 16) & 0xFF; *pCard8++ = (pCorrection->visual_info.visualid >> 8) & 0xFF; *pCard8++ = (pCorrection->visual_info.visualid) & 0xFF; *pCard8++ = pCorrection->tableType; /* type */ *pCard8++ = 3; /* number of tables = 3 */ if (pCorrection->tableType == 0) { PutTableType0Card8(pCorrection->pRedTbl, &pCard8); PutTableType0Card8(pCorrection->pGreenTbl, &pCard8); PutTableType0Card8(pCorrection->pBlueTbl, &pCard8); } else { PutTableType1Card8(pCorrection->pRedTbl, &pCard8); PutTableType1Card8(pCorrection->pGreenTbl, &pCard8); PutTableType1Card8(pCorrection->pBlueTbl, &pCard8); } XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 8, i ? PropModeAppend : PropModeReplace, (unsigned char *) pCard8Array, total); free(pCard8Array); break; case 16: total = 7 + /* visualID, type, and 3 lengths */ (pCorrection->pRedTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) + (pCorrection->pGreenTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) + (pCorrection->pBlueTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)); pCard16 = pCard16Array = calloc(total, sizeof(unsigned short)); if (pCard16 == NULL) { fprintf(stderr, "Unable allocate array of ints\n"); return (0); } *pCard16++ = (pCorrection->visual_info.visualid >> 16) & 0xFFFF; *pCard16++ = (pCorrection->visual_info.visualid) & 0xFFFF; *pCard16++ = pCorrection->tableType; /* type = 0 */ *pCard16++ = 3; /* number of tables = 3 */ if (pCorrection->tableType == 0) { PutTableType0Card16(pCorrection->pRedTbl, &pCard16); PutTableType0Card16(pCorrection->pGreenTbl, &pCard16); PutTableType0Card16(pCorrection->pBlueTbl, &pCard16); } else { PutTableType1Card16(pCorrection->pRedTbl, &pCard16); PutTableType1Card16(pCorrection->pGreenTbl, &pCard16); PutTableType1Card16(pCorrection->pBlueTbl, &pCard16); } XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 16, i ? PropModeAppend : PropModeReplace, (unsigned char *) pCard16Array, total); free(pCard16Array); break; case 32: total = 6 + /* visualID, type, and 3 lengths */ (pCorrection->pRedTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) + (pCorrection->pGreenTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)) + (pCorrection->pBlueTbl->nEntries * (pCorrection->tableType == 0 ? 2 : 1)); pCard32 = pCard32Array = calloc(total, sizeof(unsigned long)); if (pCard32 == NULL) { fprintf(stderr, "Unable allocate array of ints\n"); return (0); } *pCard32++ = pCorrection->visual_info.visualid; *pCard32++ = pCorrection->tableType; /* type */ *pCard32++ = 3; /* number of tables = 3 */ if (pCorrection->tableType == 0) { PutTableType0Card32(pCorrection->pRedTbl, &pCard32); PutTableType0Card32(pCorrection->pGreenTbl, &pCard32); PutTableType0Card32(pCorrection->pBlueTbl, &pCard32); } else { PutTableType1Card32(pCorrection->pRedTbl, &pCard32); PutTableType1Card32(pCorrection->pGreenTbl, &pCard32); PutTableType1Card32(pCorrection->pBlueTbl, &pCard32); } XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 32, i ? PropModeAppend : PropModeReplace, (unsigned char *) pCard32Array, total); free(pCard32Array); break; default: if (pCorrection->visual_info.visualid) { fprintf(stderr, "RGB Correction for visualid %ld: Invalid property format\n", pCorrection->visual_info.visualid); } else { fprintf(stderr, "Global RGB Correction: Invalid property format\n"); } return (0); } } } return (1); } #ifdef GRAY static int LoadDataGray(Display *pDpy, window root, int tableType, LINEAR_RGB_SCCData *pScreenData, int targetFormat) { int nLevels; unsigned char *pCard8; unsigned char *pCard8Array = NULL; unsigned short *pCard16; unsigned short *pCard16Array = NULL; unsigned long *pCard32; unsigned long *pCard32Array = NULL; unsigned long Card32Array[18]; Atom MatricesAtom, CorrectAtom; XcmsFloat *pValue; int total; /* Now store the XDCCC_SCREENWHITEPT */ pCard32 = Card32Array; pValue = (XcmsFloat *) pScreenData->XYZtoRGBmatrix; for (int count = 0; count < 3; count++) { *pCard32++ = (unsigned long) (*pValue++ * (XcmsFloat) XDCCC_NUMBER); } MatricesAtom = XInternAtom(pDpy, XDCCC_SCREENWHITEPT_ATOM_NAME, False); XChangeProperty(pDpy, root, MatricesAtom, XA_INTEGER, 32, PropModeReplace, (unsigned char *) Card32Array, 3); /* Now store the XDCCC_GRAY_CORRECTION */ CorrectAtom = XInternAtom(pDpy, XDCCC_GRAY_CORRECT_ATOM_NAME, False); if (tableType == CORR_TYPE_NONE) { unsigned char *ret_prop; Atom ret_atom; int ret_format; unsigned long ret_len, ret_after; XGetWindowProperty(pDpy, root, CorrectAtom, 0, 5, False, XA_INTEGER, &ret_atom, &ret_format, &ret_len, &ret_after, &ret_prop); if (ret_format != 0) { XDeleteProperty(pDpy, root, CorrectAtom); XFree(ret_prop); } return (1); } nLevels = pScreenData->pRedTbl->nEntries; if (nLevels < 2) { fprintf(stderr, "Illegal number of entries in table\n"); return (0); } switch (targetFormat) { case 8: total = 6 /* visualID, type, length */ + (nLevels * (tableType == 0 ? 2 : 1)); pCard8 = pCard8Array = calloc(total, sizeof(unsigned char)); if (pCard8 == NULL) { fprintf(stderr, "Unable allocate array of Card8\n"); return (0); } *pCard8++ = 0; /* VisualID = 0 */ *pCard8++ = 0; /* VisualID = 0 */ *pCard8++ = 0; /* VisualID = 0 */ *pCard8++ = 0; /* VisualID = 0 */ *pCard8++ = tableType; /* type */ if (tableType == 0) { PutTableType0Card8(pScreenData->pRedTbl, &pCard8); } else { /* tableType == 1 */ PutTableType1Card8(pScreenData->pRedTbl, &pCard8); } XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 8, PropModeReplace, (unsigned char *) pCard8Array, total); free(pCard8Array); break; case 16: total = 4 /* visualID, type, length */ + (nLevels * (tableType == 0 ? 2 : 1)); pCard16 = pCard16Array = calloc(total, sizeof(unsigned short)); if (pCard16 == NULL) { fprintf(stderr, "Unable allocate array of Card16\n"); return (0); } *pCard16++ = 0; /* VisualID = 0 */ *pCard16++ = 0; /* VisualID = 0 */ *pCard16++ = tableType; /* type */ if (tableType == 0) { PutTableType0Card16(pScreenData->pRedTbl, &pCard16); } else { /* tableType == 1 */ PutTableType1Card16(pScreenData->pRedTbl, &pCard16); } XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 16, PropModeReplace, (unsigned char *) pCard16Array, total); free(pCard16Array); break; case 32: total = 3 /* visualID, type, length */ + (nLevels * (tableType == 0 ? 2 : 1)); pCard32 = pCard32Array = calloc(total, sizeof(unsigned long)); if ((pCard32 == NULL) { fprintf(stderr, "Unable allocate array of Card32\n"); return (0); } *pCard32++ = 0; /* VisualID = 0 */ *pCard32++ = tableType; /* type */ if (tableType == 0) { PutTableType0Card32(pScreenData->pRedTbl, &pCard32); } else { /* tableType == 1 */ PutTableType1Card32(pScreenData->pRedTbl, &pCard32); } XChangeProperty(pDpy, root, CorrectAtom, XA_INTEGER, 32, PropModeReplace, (unsigned char *) pCard32Array, total); free(pCard32Array); break; default: fprintf(stderr, "Invalid property format\n"); return (0); } return (1); } #endif /* GRAY */ static void PrintVisualOptions(XDCCC_Correction * pCorrection) { if (pCorrection->visual_info_mask & VisualIDMask) { fprintf(stderr, "\t%s:0x%lx\n", DefineToStr(VisualOptKeyTbl, KEY_VISUALID), (unsigned long) pCorrection->visual_info.visualid); } if (pCorrection->visual_info_mask & VisualDepthMask) { fprintf(stderr, "\t%s:%d\n", DefineToStr(VisualOptKeyTbl, KEY_DEPTH), pCorrection->visual_info.depth); } if (pCorrection->visual_info_mask & VisualClassMask) { fprintf(stderr, "\t%s:%s\n", DefineToStr(VisualOptKeyTbl, KEY_CLASS), DefineToStr(VisualClassTbl, pCorrection->visual_info.class)); } if (pCorrection->visual_info_mask & VisualRedMaskMask) { fprintf(stderr, "\t%s:0x%lx\n", DefineToStr(VisualOptKeyTbl, KEY_RED_MASK), pCorrection->visual_info.red_mask); } if (pCorrection->visual_info_mask & VisualGreenMaskMask) { fprintf(stderr, "\t%s:0x%lx\n", DefineToStr(VisualOptKeyTbl, KEY_GREEN_MASK), pCorrection->visual_info.green_mask); } if (pCorrection->visual_info_mask & VisualBlueMaskMask) { fprintf(stderr, "\t%s:0x%lx\n", DefineToStr(VisualOptKeyTbl, KEY_BLUE_MASK), pCorrection->visual_info.blue_mask); } if (pCorrection->visual_info_mask & VisualColormapSizeMask) { fprintf(stderr, "\t%s:0x%x\n", DefineToStr(VisualOptKeyTbl, KEY_COLORMAP_SIZE), pCorrection->visual_info.colormap_size); } if (pCorrection->visual_info_mask & VisualBitsPerRGBMask) { fprintf(stderr, "\t%s:%d\n", DefineToStr(VisualOptKeyTbl, KEY_BITS_PER_RGB), pCorrection->visual_info.bits_per_rgb); } } static int ParseVisualOptions(Display *pDpy, XDCCC_Correction *pCorrection, char *pbuf) { char *key; XVisualInfo *vinfo; int n_matches; const char *delims = DATA_DELIMS ":"; pCorrection->visual_info_mask = VisualNoMask; key = strtok(pbuf, delims); do { long tmp; char *value = strtok(NULL, delims); if ((key == NULL) || (value == NULL)) { return (0); } switch (StrToDefine(VisualOptKeyTbl, key)) { case KEY_VISUALID: if (sscanf(value, "%li", &tmp) != 1) { fprintf(stderr, "Line %d: invalid VisualID specified, %s\n", linenum, value); return (0); } else pCorrection->visual_info.visualid = tmp; pCorrection->visual_info_mask |= VisualIDMask; break; case KEY_DEPTH: if (sscanf(value, "%i", &pCorrection->visual_info.depth) != 1) { fprintf(stderr, "Line %d: invalid depth specified, %s\n", linenum, value); return (0); } pCorrection->visual_info_mask |= VisualDepthMask; break; case KEY_CLASS: switch (pCorrection->visual_info.class = StrToDefine(VisualClassTbl, value)) { case StaticColor: break; case PseudoColor: break; case TrueColor: break; case DirectColor: break; case StaticGray: /* invalid, fall through */ case GrayScale: /* invalid, fall through */ default: fprintf(stderr, "Line %d: invalid Visual Class -- %s\n", linenum, value); return (0); } pCorrection->visual_info_mask |= VisualClassMask; break; case KEY_RED_MASK: if (sscanf(value, "%li", &tmp) != 1) { fprintf(stderr, "Line %d: invalid red_mask specified -- %s\n", linenum, value); return (0); } else pCorrection->visual_info.red_mask = tmp; pCorrection->visual_info_mask |= VisualRedMaskMask; break; case KEY_GREEN_MASK: if (sscanf(value, "%li", &tmp) != 1) { fprintf(stderr, "Line %d: invalid green_mask specified -- %s\n", linenum, value); return (0); } else pCorrection->visual_info.green_mask = tmp; pCorrection->visual_info_mask |= VisualGreenMaskMask; break; case KEY_BLUE_MASK: if (sscanf(value, "%li", &tmp) != 1) { fprintf(stderr, "Line %d: invalid blue_mask specified -- %s\n", linenum, value); return (0); } else pCorrection->visual_info.blue_mask = tmp; pCorrection->visual_info_mask |= VisualBlueMaskMask; break; case KEY_COLORMAP_SIZE: if (sscanf(value, "%i", &pCorrection->visual_info.colormap_size) != 1) { fprintf(stderr, "Line %d: invalid colormap_size specified -- %s\n", linenum, value); return (0); } pCorrection->visual_info_mask |= VisualColormapSizeMask; break; case KEY_BITS_PER_RGB: if (sscanf(value, "%i", &pCorrection->visual_info.bits_per_rgb) != 1) { fprintf(stderr, "Line %d: invalid bits_per_rgb specified -- %s\n", linenum, value); return (0); } pCorrection->visual_info_mask |= VisualBitsPerRGBMask; break; default: fprintf(stderr, "Line %d: invalid keyword %s\n", linenum, key); return (0); } key = strtok(NULL, delims); } while (key != NULL); vinfo = XGetVisualInfo(pDpy, pCorrection->visual_info_mask, &pCorrection->visual_info, &n_matches); if (!n_matches) { fprintf(stderr, "Line %d: Cannot find visual matching ...\n", linenum); PrintVisualOptions(pCorrection); fprintf(stderr, "\n"); return (0); } if (n_matches > 1) { fprintf(stderr, "Line %d: Found more than one visual matching ...\n", linenum); PrintVisualOptions(pCorrection); fprintf(stderr, " Using VisualId 0x%lx\n", (unsigned long) vinfo->visualid); } memcpy(&pCorrection->visual_info, vinfo, sizeof(XVisualInfo)); return (1); } /************************************************************************ * * * PUBLIC ROUTINES * * * ************************************************************************/ /* * NAME * LoadSCCData - Read and store the screen data * * SYNOPSIS */ int LoadSCCData(Display *pDpy, int screenNumber, const char *filename, int targetFormat) /* * DESCRIPTION * Using the X Device Color Characterization Convention (XDCCC) * read the screen data and store it on the root window of the * screen. * * RETURNS * Returns 0 if failed; otherwise 1. * */ { FILE *stream; char *pStr; char buf[BUFSIZ]; char *keyword, *token1, *token2, *token3; int state = 0; int VisualFlag = -2; Window root; XDCCC_Matrix matrix; XDCCC_Correction *CorrectionTail = NULL; XDCCC_Correction *CorrectionHead = NULL; XDCCC_Correction *pCurrent; if (screenNumber < 0) { fprintf(stderr, "Invalid Screen Number %d\n", screenNumber); return (0); } root = RootWindow(pDpy, screenNumber); if (!root) { /* if no root window is available then return an error */ fprintf(stderr, "Could not open root window supplied.\n "); return (0); } /* * Open the file, determine its size, then read it into memory. */ if (filename == NULL) { stream = stdin; filename = "stdin"; } else if ((stream = fopen(filename, "r")) == NULL) { fprintf(stderr, "Could not open file %s.\n", filename); return (0); } /* * Advance to starting keyword * Anything before this keyword is just treated as comments. */ while ((pStr = nextline(buf, BUFSIZ, stream)) != NULL) { keyword = strtok(buf, DATA_DELIMS); if (keyword != NULL && (strcmp(keyword, SC_BEGIN_KEYWORD) == 0)) { break; } /* else ignore the line */ } if (pStr == NULL) { fprintf(stderr, "File %s is missing %s\n", filename, SC_BEGIN_KEYWORD); closeS(stream, CorrectionHead); return (0); } token1 = strtok(NULL, DATA_DELIMS); if (token1 && (strcmp(token1, TXT_FORMAT_VERSION) != 0) && (strcmp(token1, "0.3") != 0)) { fprintf(stderr, "Screen data format version mismatch in file %s-- expected %s, found %s\n", filename, TXT_FORMAT_VERSION, token1); closeS(stream, CorrectionHead); return (0); } while ((pStr = nextline(buf, BUFSIZ, stream)) != NULL) { keyword = strtok(buf, DATA_DELIMS); if (keyword != NULL) { switch (SCKeyOf(keyword)) { case COMMENT: case NAME: case PART_NUMBER: case MODEL: case SERIAL_NUMBER: case REVISION: /* Do nothing */ break; case SCREEN_CLASS: token1 = strtok(NULL, DATA_DELIMS); token2 = strtok(NULL, DATA_DELIMS); if ((token1 == NULL) || ((VisualFlag = SCScrnClassOf(token1)) == -1)) { closeS(stream, CorrectionHead); return (0); } /*include code to handle screen number input */ if (token2 != NULL) { screenNumber = atoi(token2); if (screenNumber < 0) { fprintf(stderr, "Invalid Screen Number %d\n", screenNumber); } else { root = RootWindow(pDpy, screenNumber); if (!root) { /* if no root window is available then return an error */ fprintf(stderr, "Could not open root window supplied.\n "); return (0); } } } break; case COLORIMETRIC_BEGIN: if (VisualFlag == -2) { closeS(stream, CorrectionHead); return (0); } if (!ProcessColorimetric(stream, &matrix, VisualFlag)) { closeS(stream, CorrectionHead); return (0); } state |= 0x02; break; case IPROFILE_BEGIN: if (VisualFlag == -2) { closeS(stream, CorrectionHead); return (0); } token1 = strtok(NULL, DATA_DELIMS); token2 = strtok(NULL, DATA_DELIMS); if ((token1 == NULL) || (token2 == NULL)) { fprintf(stderr, "Line %d: Intensity profile missing TableType and/or nTables.", linenum); closeS(stream, CorrectionHead); return (0); } pCurrent = calloc(1, sizeof(XDCCC_Correction)); if (pCurrent == NULL) { fprintf(stderr, "Line %d: Could not allocate memory for intensity profile.", linenum); closeS(stream, CorrectionHead); return (0); } if (sscanf(token1, "%d", &pCurrent->tableType) != 1 || (pCurrent->tableType < 0 || pCurrent->tableType > 1)) { fprintf(stderr, "Line %d: invalid table type specified -- %s\n", linenum, buf); closeS(stream, CorrectionHead); free(pCurrent); return (0); } if ((VisualFlag == VIDEO_RGB) && (token2 == NULL)) { fprintf(stderr, "Line %d: invalid number of tables specified -- %s\n", linenum, buf); closeS(stream, CorrectionHead); free(pCurrent); return (0); } if (VisualFlag == VIDEO_RGB) { if (sscanf(token2, "%d", &pCurrent->nTables) != 1 || (pCurrent->nTables != 0 && pCurrent->nTables != 1 && pCurrent->nTables != 3)) { fprintf(stderr, "Line %d: invalid number of tables (must be 0, 1, or 3)\n", linenum); closeS(stream, CorrectionHead); free(pCurrent); return (0); } } else { pCurrent->nTables = 0; } token3 = strtok(NULL, "\n"); if (token3 != NULL) { if (!ParseVisualOptions(pDpy, pCurrent, token3)) { goto ByPassThisIProfile; } } switch (pCurrent->nTables) { case 3: pCurrent->pRedTbl = calloc(1, sizeof(IntensityTbl)); if (pCurrent->pRedTbl == NULL) { fprintf(stderr, "Line %d: Could not allocate Red Intensity Table\n", linenum); closeS(stream, CorrectionHead); free(pCurrent); return (0); } pCurrent->pGreenTbl = calloc(1, sizeof(IntensityTbl)); if (pCurrent->pGreenTbl == NULL) { fprintf(stderr, "Line %d: Could not allocate Green Intensity Table\n", linenum); closeS(stream, CorrectionHead); free(pCurrent->pRedTbl); free(pCurrent); return (0); } pCurrent->pBlueTbl = calloc(1, sizeof(IntensityTbl)); if (pCurrent->pBlueTbl == NULL) { fprintf(stderr, "Line %d: Could not allocate Blue Intensity Table", linenum); closeS(stream, CorrectionHead); free(pCurrent->pRedTbl); free(pCurrent->pGreenTbl); free(pCurrent); return (0); } if (!ProcessIProfile(stream, pCurrent)) { goto ByPassThisIProfile; } break; case 1: pCurrent->pRedTbl = calloc(1, sizeof(IntensityTbl)); if (pCurrent->pRedTbl == NULL) { fprintf(stderr, "Line %d: Could not allocate Red Intensity Table", linenum); closeS(stream, CorrectionHead); free(pCurrent); return (0); } pCurrent->pGreenTbl = pCurrent->pRedTbl; pCurrent->pBlueTbl = pCurrent->pRedTbl; if (!ProcessIProfile(stream, pCurrent)) { goto ByPassThisIProfile; } break; default: /* do nothing */ break; } if (CorrectionHead == NULL) { CorrectionHead = CorrectionTail = pCurrent; } else { CorrectionTail->next = pCurrent; CorrectionTail = pCurrent; } state |= 0x04; break; ByPassThisIProfile: /* read till INTENSITY_PROFILE_END */ while ((pStr = nextline(buf, BUFSIZ, stream)) != NULL) { keyword = strtok(buf, DATA_DELIMS); if (keyword != NULL) { switch (SCKeyOf(keyword)) { case ITBL_BEGIN: case ITBL_END: case COMMENT: case DATA: break; case IPROFILE_END: goto IProfileProcessed; default: closeS(stream, CorrectionHead); return (0); } } } free(pCurrent); IProfileProcessed: state |= 0x04; break; case SC_END: if (!(state & 0x02)) { fprintf(stderr, "File %s is missing Colorimetric data.\n", filename); closeS(stream, CorrectionHead); return (0); } if (!(state & 0x04)) { fprintf(stderr, "File %s is missing Intensity Profile Data.\n", filename); } if (VisualFlag == VIDEO_RGB) { LoadMatrix(pDpy, root, &matrix); if (!LoadCorrections(pDpy, root, CorrectionHead, targetFormat)) { closeS(stream, CorrectionHead); return (0); } #ifdef GRAY } else if (VisualFlag == VIDEO_GRAY) { if (!LoadDataGray(pDpy, root, pCurrent->tableType, pScreenData, targetFormat)) { closeS(stream, CorrectionHead); return (0); } #endif /* GRAY */ } else { fprintf(stderr, "File %s Visual missing.", filename); } closeS(stream, CorrectionHead); return (1); default: fprintf(stderr, "Line %d: extraneous keyword %s\n", linenum, keyword); closeS(stream, CorrectionHead); return (0); } } /* else it was just a blank line */ } closeS(stream, CorrectionHead); return (1); }