📄 tkimgphoto.c
字号:
options.toY + height); } /* * Call the handler's file read procedure to read the data * into the image. */ result = (*imageFormat->fileReadProc)(interp, chan, options.name, options.format, (Tk_PhotoHandle) masterPtr, options.toX, options.toY, width, height, options.fromX, options.fromY); if (chan != NULL) { Tcl_Close(NULL, chan); } return result; } else if ((c == 'r') && (length >= 3) && (strncmp(argv[1], "redither", length) == 0)) { if (argc == 2) { /* * Call Dither if any part of the image is not correctly * dithered at present. */ x = masterPtr->ditherX; y = masterPtr->ditherY; if (masterPtr->ditherX != 0) { Dither(masterPtr, x, y, masterPtr->width - x, 1); } if (masterPtr->ditherY < masterPtr->height) { x = 0; Dither(masterPtr, 0, masterPtr->ditherY, masterPtr->width, masterPtr->height - masterPtr->ditherY); } if (y < masterPtr->height) { /* * Tell the core image code that part of the image has changed. */ Tk_ImageChanged(masterPtr->tkMaster, x, y, (masterPtr->width - x), (masterPtr->height - y), masterPtr->width, masterPtr->height); } } else { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " redither\"", (char *) NULL); return TCL_ERROR; } } else if ((c == 'w') && (strncmp(argv[1], "write", length) == 0)) { /* * Prevent file system access in safe interpreters. */ if (Tcl_IsSafe(interp)) { Tcl_AppendResult(interp, "can't write image to a file in a", " safe interpreter", (char *) NULL); return TCL_ERROR; } /* * photo write command - first parse and check any options given. */ index = 2; memset((VOID *) &options, 0, sizeof(options)); options.name = NULL; options.format = NULL; if (ParseSubcommandOptions(&options, interp, OPT_FORMAT | OPT_FROM, &index, argc, argv) != TCL_OK) { return TCL_ERROR; } if ((options.name == NULL) || (index < argc)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " write fileName ?-format format-name?", "?-from x1 y1 x2 y2?\"", (char *) NULL); return TCL_ERROR; } if ((options.fromX > masterPtr->width) || (options.fromY > masterPtr->height) || (options.fromX2 > masterPtr->width) || (options.fromY2 > masterPtr->height)) { Tcl_AppendResult(interp, "coordinates for -from option extend ", "outside image", (char *) NULL); return TCL_ERROR; } /* * Fill in default values for unspecified parameters. */ if (((options.options & OPT_FROM) == 0) || (options.fromX2 < 0)) { options.fromX2 = masterPtr->width; options.fromY2 = masterPtr->height; } /* * Search for an appropriate image file format handler, * and give an error if none is found. */ matched = 0; for (imageFormat = formatList; imageFormat != NULL; imageFormat = imageFormat->nextPtr) { if ((options.format == NULL) || (strncasecmp(options.format, imageFormat->name, strlen(imageFormat->name)) == 0)) { matched = 1; if (imageFormat->fileWriteProc != NULL) { break; } } } if (imageFormat == NULL) { if (options.format == NULL) { Tcl_AppendResult(interp, "no available image file format ", "has file writing capability", (char *) NULL); } else if (!matched) { Tcl_AppendResult(interp, "image file format \"", options.format, "\" is unknown", (char *) NULL); } else { Tcl_AppendResult(interp, "image file format \"", options.format, "\" has no file writing capability", (char *) NULL); } return TCL_ERROR; } /* * Call the handler's file write procedure to write out * the image. */ Tk_PhotoGetImage((Tk_PhotoHandle) masterPtr, &block); block.pixelPtr += options.fromY * block.pitch + options.fromX * 3; block.width = options.fromX2 - options.fromX; block.height = options.fromY2 - options.fromY; return (*imageFormat->fileWriteProc)(interp, options.name, options.format, &block); } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be blank, cget, configure, copy, get, put,", " read, redither, or write", (char *) NULL); return TCL_ERROR; } return TCL_OK;}/* *---------------------------------------------------------------------- * * ParseSubcommandOptions -- * * This procedure is invoked to process one of the options * which may be specified for the photo image subcommands, * namely, -from, -to, -zoom, -subsample, -format, and -shrink. * * Results: * A standard Tcl result. * * Side effects: * Fields in *optPtr get filled in. * *---------------------------------------------------------------------- */static intParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, argc, argv) struct SubcommandOptions *optPtr; /* Information about the options specified * and the values given is returned here. */ Tcl_Interp *interp; /* Interpreter to use for reporting errors. */ int allowedOptions; /* Indicates which options are valid for * the current command. */ int *optIndexPtr; /* Points to a variable containing the * current index in argv; this variable is * updated by this procedure. */ int argc; /* Number of arguments in argv[]. */ char **argv; /* Arguments to be parsed. */{ int index, c, bit, currentBit; size_t length; char *option, **listPtr; int values[4]; int numValues, maxValues, argIndex; for (index = *optIndexPtr; index < argc; *optIndexPtr = ++index) { /* * We can have one value specified without an option; * it goes into optPtr->name. */ option = argv[index]; if (option[0] != '-') { if (optPtr->name == NULL) { optPtr->name = option; continue; } break; } /* * Work out which option this is. */ length = strlen(option); c = option[0]; bit = 0; currentBit = 1; for (listPtr = optionNames; *listPtr != NULL; ++listPtr) { if ((c == *listPtr[0]) && (strncmp(option, *listPtr, length) == 0)) { if (bit != 0) { bit = 0; /* An ambiguous option. */ break; } bit = currentBit; } currentBit <<= 1; } /* * If this option is not recognized and allowed, put * an error message in the interpreter and return. */ if ((allowedOptions & bit) == 0) { Tcl_AppendResult(interp, "unrecognized option \"", argv[index], "\": must be ", (char *)NULL); bit = 1; for (listPtr = optionNames; *listPtr != NULL; ++listPtr) { if ((allowedOptions & bit) != 0) { if ((allowedOptions & (bit - 1)) != 0) { Tcl_AppendResult(interp, ", ", (char *) NULL); if ((allowedOptions & ~((bit << 1) - 1)) == 0) { Tcl_AppendResult(interp, "or ", (char *) NULL); } } Tcl_AppendResult(interp, *listPtr, (char *) NULL); } bit <<= 1; } return TCL_ERROR; } /* * For the -from, -to, -zoom and -subsample options, * parse the values given. Report an error if too few * or too many values are given. */ if ((bit != OPT_SHRINK) && (bit != OPT_FORMAT)) { maxValues = ((bit == OPT_FROM) || (bit == OPT_TO))? 4: 2; argIndex = index + 1; for (numValues = 0; numValues < maxValues; ++numValues) { if ((argIndex < argc) && (isdigit(UCHAR(argv[argIndex][0])) || ((argv[argIndex][0] == '-') && (isdigit(UCHAR(argv[argIndex][1])))))) { if (Tcl_GetInt(interp, argv[argIndex], &values[numValues]) != TCL_OK) { return TCL_ERROR; } } else { break; } ++argIndex; } if (numValues == 0) { Tcl_AppendResult(interp, "the \"", argv[index], "\" option ", "requires one ", maxValues == 2? "or two": "to four", " integer values", (char *) NULL); return TCL_ERROR; } *optIndexPtr = (index += numValues); /* * Y values default to the corresponding X value if not specified. */ if (numValues == 1) { values[1] = values[0]; } if (numValues == 3) { values[3] = values[2]; } /* * Check the values given and put them in the appropriate * field of the SubcommandOptions structure. */ switch (bit) { case OPT_FROM: if ((values[0] < 0) || (values[1] < 0) || ((numValues > 2) && ((values[2] < 0) || (values[3] < 0)))) { Tcl_AppendResult(interp, "value(s) for the -from", " option must be non-negative", (char *) NULL); return TCL_ERROR; } if (numValues <= 2) { optPtr->fromX = values[0]; optPtr->fromY = values[1]; optPtr->fromX2 = -1; optPtr->fromY2 = -1; } else { optPtr->fromX = MIN(values[0], values[2]); optPtr->fromY = MIN(values[1], values[3]); optPtr->fromX2 = MAX(values[0], values[2]); optPtr->fromY2 = MAX(values[1], values[3]); } break; case OPT_SUBSAMPLE: optPtr->subsampleX = values[0]; optPtr->subsampleY = values[1]; break; case OPT_TO: if ((values[0] < 0) || (values[1] < 0) || ((numValues > 2) && ((values[2] < 0) || (values[3] < 0)))) { Tcl_AppendResult(interp, "value(s) for the -to", " option must be non-negative", (char *) NULL); return TCL_ERROR; } if (numValues <= 2) { optPtr->toX = values[0]; optPtr->toY = values[1]; optPtr->toX2 = -1; optPtr->toY2 = -1; } else { optPtr->toX = MIN(values[0], values[2]); optPtr->toY = MIN(values[1], values[3]); optPtr->toX2 = MAX(values[0], values[2]); optPtr->toY2 = MAX(values[1], values[3]); } break; case OPT_ZOOM: if ((values[0] <= 0) || (values[1] <= 0)) { Tcl_AppendResult(interp, "value(s) for the -zoom", " option must be positive", (char *) NULL); return TCL_ERROR; } optPtr->zoomX = values[0]; optPtr->zoomY = values[1]; break; } } else if (bit == OPT_FORMAT) { /* * The -format option takes a single string value. */ if (index + 1 < argc) { *optIndexPtr = ++index; optPtr->format = argv[index]; } else { Tcl_AppendResult(interp, "the \"-format\" option ", "requires a value", (char *) NULL); return TCL_ERROR; } } /* * Remember that we saw this option. */ optPtr->options |= bit; } return TCL_OK;}/* *---------------------------------------------------------------------- * * ImgPhotoConfigureMaster -- * * This procedure is called when a photo image is created or * reconfigured. It processes configuration options and resets * any instances of the image. * * Results: * A standard Tcl return value. If TCL_ERROR is returned then * an error message is left in masterPtr->interp->result. * * Side effects: * Existing instances of the image will be redisplayed to match * the new configuration options. * *---------------------------------------------------------------------- */static intImgPhotoConfigureMaster(interp, masterPtr, argc, argv, flags) Tcl_Interp *interp; /* Interpreter to use for reporting errors. */ PhotoMaster *masterPtr; /* Pointer to data structure describing * overall photo image to (re)configure. */ int argc; /* Number of entries in argv. */ char **argv; /* Pairs of configuration options for image. */ int flags; /* Flags to pass to Tk_ConfigureWidget, * such as TK_CONFIG_ARGV_ONLY. */{ PhotoInstance *instancePtr; char *oldFileString, *oldDataString, *oldPaletteString; double oldGamma; int result; Tcl_Channel chan; Tk_PhotoImageFormat *imageFormat; int imageWidth, imageHeight; /* * Save the current values for fileString and dataString, so we * can tell if the user specifies them anew. */ oldFileString = masterPtr->fileString; oldDataString = (oldFileString == NULL)? masterPtr->dataString: NULL; oldPaletteString = masterPtr->palette; oldGamma = masterPtr->gamma; /* * Process the configuration options specified. */ if (Tk_ConfigureWidget(interp, Tk_MainWindow(interp), configSpecs, argc, argv, (char *) masterPtr, flags) != TCL_OK) { return TCL_ERROR; } /* * Regard the empty string for -file, -data or -format as the null * value. */ if ((masterPtr->fileString != NULL) && (masterPtr->fileString[0] == 0)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -