void camltk_setimgdata_native (value imgname, value pixmap, value x, value y, value w, value h) /* ML */ { Tk_PhotoHandle ph; Tk_PhotoImageBlock pib; int code; #if (TK_MAJOR_VERSION < 8) if (NULL == (ph = Tk_FindPhoto(String_val(imgname)))) tk_error("no such image"); #else if (NULL == (ph = Tk_FindPhoto(cltclinterp, String_val(imgname)))) tk_error("no such image"); #endif pib.pixelPtr = String_val(pixmap); pib.width = Int_val(w); pib.height = Int_val(h); pib.pitch = pib.width * 3; pib.pixelSize = 3; pib.offset[0] = 0; pib.offset[1] = 1; pib.offset[2] = 2; Tk_PhotoPutBlock( #if (TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION >= 5 || TK_MAJOR_VERSION > 8) NULL, #endif ph,&pib,Int_val(x),Int_val(y),Int_val(w),Int_val(h) #if (TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION >= 4 || TK_MAJOR_VERSION > 8) , TK_PHOTO_COMPOSITE_SET #endif ); }
/* *--------------------------------------------------------------------------- * * photoputblock -- * * This is a wrapper around Tk_PhotoPutBlock(). In tk 8.5, the 'interp' * argument was added to the Tk_PhotoPutBlock() signature. This * function deals with this API change. * * Later: The trick is to define USE_COMPOSITELESS_PHOTO_PUT_BLOCK, * which is now done in html.h. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static void photoputblock( Tcl_Interp *interp, Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule ) { Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height); }
static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp* interp, int argc, char **argv) { Tk_PhotoHandle photo; Tk_PhotoImageBlock block; PyObject* aggo; // vars for blitting PyObject* bboxo; Bbox* bbox; agg::int8u *destbuffer; double l,b,r,t; int destx, desty, destwidth, destheight, deststride; long mode; long nval; if (argc != 5) { Tcl_AppendResult(interp, "usage: ", argv[0], " destPhoto srcImage", (char *) NULL); return TCL_ERROR; } /* get Tcl PhotoImage handle */ photo = Tk_FindPhoto(interp, argv[1]); if (photo == NULL) { Tcl_AppendResult(interp, "destination photo must exist", (char *) NULL); return TCL_ERROR; } /* get array (or object that can be converted to array) pointer */ aggo = (PyObject*)atol(argv[2]); RendererAgg *aggRenderer = (RendererAgg *)aggo; int srcheight = (int)aggRenderer->get_height(); /* XXX insert aggRenderer type check */ /* get array mode (0=mono, 1=rgb, 2=rgba) */ mode = atol(argv[3]); if ((mode != 0) && (mode != 1) && (mode != 2)) { Tcl_AppendResult(interp, "illegal image mode", (char *) NULL); return TCL_ERROR; } /* check for bbox/blitting */ bboxo = (PyObject*)atol(argv[4]); if (bboxo != Py_None) { bbox = (Bbox*)bboxo; l = bbox->ll_api()->x_api()->val(); b = bbox->ll_api()->y_api()->val(); r = bbox->ur_api()->x_api()->val(); t = bbox->ur_api()->y_api()->val(); destx = (int)l; desty = srcheight-(int)t; destwidth = (int)(r-l); destheight = (int)(t-b); deststride = 4*destwidth; destbuffer = new agg::int8u[deststride*destheight]; if (destbuffer == NULL) { throw Py::MemoryError("_tkagg could not allocate memory for destbuffer"); } agg::rendering_buffer destrbuf; destrbuf.attach(destbuffer, destwidth, destheight, deststride); pixfmt destpf(destrbuf); renderer_base destrb(destpf); agg::rect_base<int> region(destx, desty, (int)r, srcheight-(int)b); destrb.copy_from(*aggRenderer->renderingBuffer, ®ion, -destx, -desty); } else { bbox = NULL; destbuffer = NULL; destx = desty = destwidth = destheight = deststride = 0; } /* setup tkblock */ block.pixelSize = 1; if (mode == 0) { block.offset[0]= block.offset[1] = block.offset[2] =0; nval = 1; } else { block.offset[0] = 0; block.offset[1] = 1; block.offset[2] = 2; if (mode == 1) { block.offset[3] = 0; block.pixelSize = 3; nval = 3; } else { block.offset[3] = 3; block.pixelSize = 4; nval = 4; } } if (bbox) { block.width = destwidth; block.height = destheight; block.pitch = deststride; block.pixelPtr = destbuffer; Tk_PhotoPutBlock(photo, &block, destx, desty, destwidth, destheight); delete [] destbuffer; } else { block.width = aggRenderer->get_width(); block.height = aggRenderer->get_height(); block.pitch = block.width * nval; block.pixelPtr = aggRenderer->pixBuffer; /* Clear current contents */ Tk_PhotoBlank(photo); /* Copy opaque block to photo image, and leave the rest to TK */ Tk_PhotoPutBlock(photo, &block, 0, 0, block.width, block.height); } return TCL_OK; }
static int PyImagingPhotoPut(ClientData clientdata, Tcl_Interp* interp, int argc, char **argv) { Imaging im; Tk_PhotoHandle photo; Tk_PhotoImageBlock block; if (argc != 3) { Tcl_AppendResult(interp, "usage: ", argv[0], " destPhoto srcImage", (char *) NULL); return TCL_ERROR; } /* get Tcl PhotoImage handle */ photo = Tk_FindPhoto(interp, argv[1]); if (photo == NULL) { Tcl_AppendResult( interp, "destination photo must exist", (char *) NULL ); return TCL_ERROR; } /* get PIL Image handle */ im = ImagingFind(argv[2]); if (!im) { Tcl_AppendResult(interp, "bad name", (char*) NULL); return TCL_ERROR; } if (!im->block) { Tcl_AppendResult(interp, "bad display memory", (char*) NULL); return TCL_ERROR; } /* Active region */ #if 0 if (src_xoffset + xsize > im->xsize) xsize = im->xsize - src_xoffset; if (src_yoffset + ysize > im->ysize) ysize = im->ysize - src_yoffset; if (xsize < 0 || ysize < 0 || src_xoffset >= im->xsize || src_yoffset >= im->ysize) return TCL_OK; #endif /* Mode */ if (strcmp(im->mode, "1") == 0 || strcmp(im->mode, "L") == 0) { block.pixelSize = 1; block.offset[0] = block.offset[1] = block.offset[2] = 0; } else if (strncmp(im->mode, "RGB", 3) == 0) { block.pixelSize = 4; block.offset[0] = 0; block.offset[1] = 1; block.offset[2] = 2; if (strcmp(im->mode, "RGBA") == 0) block.offset[3] = 3; /* alpha (or reserved, under 8.2) */ else block.offset[3] = 0; /* no alpha */ } else { Tcl_AppendResult(interp, "Bad mode", (char*) NULL); return TCL_ERROR; } block.width = im->xsize; block.height = im->ysize; block.pitch = im->linesize; block.pixelPtr = (unsigned char*) im->block; #if 0 block.pixelPtr = (unsigned char*) im->block + src_yoffset * im->linesize + src_xoffset * im->pixelsize; #endif #if TK < 84 /* < 8.4.0 */ if (strcmp(im->mode, "RGBA") == 0) { /* Copy non-transparent pixels to photo image */ int x, y; Tk_PhotoImageBlock run; /* Clear current contents */ Tk_PhotoBlank(photo); /* Setup run descriptor */ run.height = 1; run.pitch = block.pitch; run.pixelSize = block.pixelSize; run.offset[0] = 0; run.offset[1] = 1; run.offset[2] = 2; run.offset[3] = 0; /* no alpha (or reserved, under 8.2) */ /* Copy opaque runs to photo image */ for (y = 0; y < block.height; y++) { unsigned char* p = block.pixelPtr + y*block.pitch; unsigned char* s = p; int w = 0; for (x = 0; x < block.width; x++) { if (p[3]) { /* opaque: add pixel to current run */ if (w == 0) s = p; w = w + 1; } else if (s) { /* copy run to photo image */ if (w > 0) { run.width = w; run.pixelPtr = s; Tk_PhotoPutBlock(photo, &run, x-w, y, run.width, 1); } w = 0; } p += block.pixelSize; } if (w > 0) { /* copy final run, if any */ run.width = w; run.pixelPtr = s; Tk_PhotoPutBlock(photo, &run, x-w, y, run.width, 1); } } } else /* Copy opaque block to photo image, and leave the rest to TK */ Tk_PhotoPutBlock(photo, &block, 0, 0, block.width, block.height); #else /* Tk 8.4 and newer */ #if TK < 85 /* Tk 8.4 */ Tk_PhotoPutBlock(photo, &block, 0, 0, block.width, block.height, TK_PHOTO_COMPOSITE_SET); if (strcmp(im->mode, "RGBA") == 0) /* Tk workaround: we need apply ToggleComplexAlphaIfNeeded */ /* (fixed in Tk 8.5a3) */ Tk_PhotoSetSize(photo, block.width, block.height); #else /* Tk 8.5 */ Tk_PhotoPutBlock(interp, photo, &block, 0, 0, block.width, block.height, TK_PHOTO_COMPOSITE_SET); #endif #endif return TCL_OK; }
int FileReadTIF(Tcl_Interp *interp, Tcl_Channel chan, CONST char *fileName, Tcl_Obj *format, Tk_PhotoHandle imageHandle, int destX, int destY, int width, int height, int srcX, int srcY) { int nBytes, h; int nLines; /* actual number of scan lines read * for each image block pointed at * by pixelPtr */ int nDefBlockLines; /* default number of scan lines to be read * for each image block pointed at * by pixelPtr */ unsigned char *pixelPtr; Tk_PhotoImageBlock block; unsigned long fileImgHeight, fileImgWidth; unsigned short bitspersample; unsigned short photometrictype; short n; unsigned long row; unsigned long startrow; unsigned long pixelPtrIndex; TIFF *tif; TIFFErrorHandler prev_handler; /* Current TIFF error handler */ static TIFFErrorHandler temp_handler = tkTIFFErrorHandler; /* Temporary TIFF error handler (is used to avoid output of libtiff error messages to stderr) */ prev_handler = TIFFSetErrorHandler(temp_handler); tif = TIFFOpen(fileName, "r"); if (tif == NULL) { printf("FileReadTIF: Problem reading TIF file !"); Tcl_AppendResult(interp, "couldn't read TIF header from file \"", fileName, "\"", NULL); TIFFSetErrorHandler(prev_handler); return TCL_ERROR; } /* test entry !!! */ /* printf("\nFileReadTIF: file name = %s", fileName); printf("\nFileReadTIF: height = %d", height); printf("\nFileReadTIF: width = %d", width); */ /* obtain dimensions of (first) image in TIFF file */ TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &fileImgHeight); TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &fileImgWidth); /* test entry !!! */ /* printf("\nFileReadTIF: image height = %d", fileImgHeight); printf("\nFileReadTIF: image width = %d\n", fileImgWidth); */ if ((fileImgWidth <= 0) || (fileImgHeight <= 0)) { Tcl_AppendResult(interp, "TIF image file \"", fileName, "\" has dimension(s) <= 0", (char *) NULL); return TCL_ERROR; } if ((srcX + width) > (int)fileImgWidth) { width = fileImgWidth - srcX; } if ((srcY + height) > (int)fileImgHeight) { height = fileImgHeight - srcY; } if ((width <= 0) || (height <= 0) || (srcX >= (int)fileImgWidth) || (srcY >= (int)fileImgHeight)) { return TCL_OK; } /* determine type of TIFF image: PhotometricInterpretation WhiteIsZero => 0 (bw or grayscale image) BlackIsZero => 1 (bw or grayscale image) RGB Model => 2 (RGB full color model) Color Palette => 3 Transparency Mask => 4 */ TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometrictype); /* test entry !!! */ if ((photometrictype == 0) || (photometrictype == 1) || (photometrictype == 3)) { /* bw or grayscale image */ TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample); /* test entry !!! */ /* printf("\nFileReadTIF: bits / sample = %d", bitspersample); */ block.pixelSize = 1; block.offset[0] = 0; block.offset[1] = 0; block.offset[2] = 0; } else if (photometrictype == 2) { /* RGB full color image note: - bitspersample is always = 8 - there is no color map */ block.pixelSize = 3; block.offset[0] = 0; block.offset[1] = 1; block.offset[2] = 2; } else { Tcl_AppendResult(interp, "photometric interpretation >2 ", "(palette color and transparency mask) ", "not yet supported", NULL); TIFFSetErrorHandler(prev_handler); return TCL_ERROR; } /* block.width = width; */ height = fileImgHeight; width = fileImgWidth; block.width = fileImgWidth; block.pitch = block.pixelSize * fileImgWidth; /* test entry !!! */ /* printf("\nFileReadTIF: height = %d", height); printf("\nFileReadTIF: width = %d", width); printf("\nFileReadTIF: fileImgWidth = %d", fileImgWidth); */ /* the following two values should be identical */ /* printf("\nFileReadTIF: block.pitch = %d", block.pitch); printf("\nFileReadTIF: block.pixelSize = %d", block.pixelSize); printf("\nFileReadTIF: scanline size = %d", TIFFScanlineSize(tif)); */ Tk_PhotoExpand(imageHandle, destX + width, destY + height); /* if (srcY > 0) { fseek(f, (long) (srcY * block.pitch), SEEK_CUR); } */ nDefBlockLines = (MAX_MEMORY + block.pitch - 1) / block.pitch; nLines = nDefBlockLines; nLines = height; if (nLines > height) { nLines = height; } if (nLines <= 0) { nLines = 1; } /* determine the required buffer size by calling TIFFScanlineSize */ nBytes = nLines * block.pitch; /* printf("\nFileReadTIF: nLines = %d", nLines); printf("\nFileReadTIF: nBytes = %d", nBytes); */ pixelPtr = (unsigned char *) ckalloc((unsigned)nBytes); block.pixelPtr = pixelPtr + srcX * block.pixelSize; n = 0; for (h = height; h > 0; h -= nLines) { n++; startrow = (n-1) * nLines; if (nLines > h) { nLines = h; nBytes = nLines * block.pitch; } for (row = startrow; row < (startrow + nLines); row++) { /* read the data for the spezified row into the buffer */ pixelPtrIndex = row*block.pitch - (n-1)*nDefBlockLines*block.pitch; /* test entry !!! */ /* printf("\nFileReadTIF: pixelPtr_Indx = %d", pixelPtrIndex); */ TIFFReadScanline(tif, &(pixelPtr[pixelPtrIndex]), row, 1); } block.height = nLines; Tk_PhotoPutBlock(imageHandle, &block, destX, destY, width, nLines, TK_PHOTO_COMPOSITE_SET); destY += nLines; } ckfree((char *) pixelPtr); TIFFClose(tif); /* test entry !!! */ /* printf("\nFileReadTIF: TIF file closed !"); */ TIFFSetErrorHandler(prev_handler); return TCL_OK; }
static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int argc, char **argv) { Tk_PhotoHandle photo; Tk_PhotoImageBlock block; PyObject *aggo; // vars for blitting PyObject *bboxo; size_t aggl, bboxl; bool has_bbox; agg::int8u *destbuffer; int destx, desty, destwidth, destheight, deststride; //unsigned long tmp_ptr; long mode; long nval; if (Tk_MainWindow(interp) == NULL) { // Will throw a _tkinter.TclError with "this isn't a Tk application" return TCL_ERROR; } if (argc != 5) { Tcl_AppendResult(interp, "usage: ", argv[0], " destPhoto srcImage", (char *)NULL); return TCL_ERROR; } /* get Tcl PhotoImage handle */ photo = Tk_FindPhoto(interp, argv[1]); if (photo == NULL) { Tcl_AppendResult(interp, "destination photo must exist", (char *)NULL); return TCL_ERROR; } /* get array (or object that can be converted to array) pointer */ if (sscanf(argv[2], SIZE_T_FORMAT, &aggl) != 1) { Tcl_AppendResult(interp, "error casting pointer", (char *)NULL); return TCL_ERROR; } aggo = (PyObject *)aggl; // TODO: This is really brittle and will break when RendererAgg // comes in multiple flavors RendererAgg *aggRenderer = ((PyRendererAgg *)(aggo))->x; int srcheight = (int)aggRenderer->get_height(); /* XXX insert aggRenderer type check */ /* get array mode (0=mono, 1=rgb, 2=rgba) */ mode = atol(argv[3]); if ((mode != 0) && (mode != 1) && (mode != 2)) { Tcl_AppendResult(interp, "illegal image mode", (char *)NULL); return TCL_ERROR; } /* check for bbox/blitting */ if (sscanf(argv[4], SIZE_T_FORMAT, &bboxl) != 1) { Tcl_AppendResult(interp, "error casting pointer", (char *)NULL); return TCL_ERROR; } bboxo = (PyObject *)bboxl; if (bboxo != NULL && bboxo != Py_None) { agg::rect_d rect; if (!convert_rect(bboxo, &rect)) { return TCL_ERROR; } has_bbox = true; destx = (int)rect.x1; desty = srcheight - (int)rect.y2; destwidth = (int)(rect.x2 - rect.x1); destheight = (int)(rect.y2 - rect.y1); deststride = 4 * destwidth; destbuffer = new agg::int8u[deststride * destheight]; if (destbuffer == NULL) { Tcl_AppendResult(interp, "could not allocate memory", (char *)NULL); return TCL_ERROR; } agg::rendering_buffer destrbuf; destrbuf.attach(destbuffer, destwidth, destheight, deststride); pixfmt destpf(destrbuf); renderer_base destrb(destpf); agg::rect_base<int> region(destx, desty, (int)rect.x2, srcheight - (int)rect.y1); destrb.copy_from(aggRenderer->renderingBuffer, ®ion, -destx, -desty); } else { has_bbox = false; destbuffer = NULL; destx = desty = destwidth = destheight = deststride = 0; } /* setup tkblock */ block.pixelSize = 1; if (mode == 0) { block.offset[0] = block.offset[1] = block.offset[2] = 0; nval = 1; } else { block.offset[0] = 0; block.offset[1] = 1; block.offset[2] = 2; if (mode == 1) { block.offset[3] = 0; block.pixelSize = 3; nval = 3; } else { block.offset[3] = 3; block.pixelSize = 4; nval = 4; } } if (has_bbox) { block.width = destwidth; block.height = destheight; block.pitch = deststride; block.pixelPtr = destbuffer; Tk_PhotoPutBlock(photo, &block, destx, desty, destwidth, destheight); delete[] destbuffer; } else { block.width = aggRenderer->get_width(); block.height = aggRenderer->get_height(); block.pitch = (int)block.width * nval; block.pixelPtr = aggRenderer->pixBuffer; /* Clear current contents */ Tk_PhotoBlank(photo); /* Copy opaque block to photo image, and leave the rest to TK */ Tk_PhotoPutBlock(photo, &block, 0, 0, block.width, block.height); } return TCL_OK; }
static int RasterizeSVG( Tcl_Interp *interp, Tk_PhotoHandle imageHandle, NSVGimage *nsvgImage, int destX, int destY, int width, int height, int srcX, int srcY, RastOpts *ropts) { int w, h, c; NSVGrasterizer *rast; unsigned char *imgData; Tk_PhotoImageBlock svgblock; w = (int) ceil(nsvgImage->width * ropts->scale); h = (int) ceil(nsvgImage->height * ropts->scale); rast = nsvgCreateRasterizer(); if (rast == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot initialize rasterizer", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "RASTERIZER_ERROR", NULL); goto cleanAST; } imgData = attemptckalloc(w * h *4); if (imgData == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot alloc image buffer", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "OUT_OF_MEMORY", NULL); goto cleanRAST; } nsvgRasterize(rast, nsvgImage, (float) ropts->x, (float) ropts->y, (float) ropts->scale, imgData, w, h, w * 4); /* transfer the data to a photo block */ svgblock.pixelPtr = imgData; svgblock.width = w; svgblock.height = h; svgblock.pitch = w * 4; svgblock.pixelSize = 4; for (c = 0; c <= 3; c++) { svgblock.offset[c] = c; } if (Tk_PhotoExpand(interp, imageHandle, destX + width, destY + height) != TCL_OK) { goto cleanRAST; } if (Tk_PhotoPutBlock(interp, imageHandle, &svgblock, destX, destY, width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) { goto cleanimg; } ckfree(imgData); nsvgDeleteRasterizer(rast); nsvgDelete(nsvgImage); return TCL_OK; cleanimg: ckfree(imgData); cleanRAST: nsvgDeleteRasterizer(rast); cleanAST: nsvgDelete(nsvgImage); return TCL_ERROR; }
static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp* interp, int argc, char **argv) { Tk_PhotoHandle photo; Tk_PhotoImageBlock block; PyObject* aggo; // vars for blitting PyObject* bboxo; unsigned long aggl, bboxl; bool has_bbox; agg::int8u *destbuffer; double l, b, r, t; int destx, desty, destwidth, destheight, deststride; //unsigned long tmp_ptr; long mode; long nval; if (Tk_MainWindow(interp) == NULL) { // Will throw a _tkinter.TclError with "this isn't a Tk application" return TCL_ERROR; } if (argc != 5) { Tcl_AppendResult(interp, "usage: ", argv[0], " destPhoto srcImage", (char *) NULL); return TCL_ERROR; } /* get Tcl PhotoImage handle */ photo = Tk_FindPhoto(interp, argv[1]); if (photo == NULL) { Tcl_AppendResult(interp, "destination photo must exist", (char *) NULL); return TCL_ERROR; } /* get array (or object that can be converted to array) pointer */ if (sscanf(argv[2], "%lu", &aggl) != 1) { Tcl_AppendResult(interp, "error casting pointer", (char *) NULL); return TCL_ERROR; } aggo = (PyObject*)aggl; //aggo = (PyObject*)atol(argv[2]); //std::stringstream agg_ptr_ss; //agg_ptr_ss.str(argv[2]); //agg_ptr_ss >> tmp_ptr; //aggo = (PyObject*)tmp_ptr; RendererAgg *aggRenderer = (RendererAgg *)aggo; int srcheight = (int)aggRenderer->get_height(); /* XXX insert aggRenderer type check */ /* get array mode (0=mono, 1=rgb, 2=rgba) */ mode = atol(argv[3]); if ((mode != 0) && (mode != 1) && (mode != 2)) { Tcl_AppendResult(interp, "illegal image mode", (char *) NULL); return TCL_ERROR; } /* check for bbox/blitting */ if (sscanf(argv[4], "%lu", &bboxl) != 1) { Tcl_AppendResult(interp, "error casting pointer", (char *) NULL); return TCL_ERROR; } bboxo = (PyObject*)bboxl; //bboxo = (PyObject*)atol(argv[4]); //std::stringstream bbox_ptr_ss; //bbox_ptr_ss.str(argv[4]); //bbox_ptr_ss >> tmp_ptr; //bboxo = (PyObject*)tmp_ptr; if (py_convert_bbox(bboxo, l, b, r, t)) { has_bbox = true; destx = (int)l; desty = srcheight - (int)t; destwidth = (int)(r - l); destheight = (int)(t - b); deststride = 4 * destwidth; destbuffer = new agg::int8u[deststride*destheight]; if (destbuffer == NULL) { throw Py::MemoryError("_tkagg could not allocate memory for destbuffer"); } agg::rendering_buffer destrbuf; destrbuf.attach(destbuffer, destwidth, destheight, deststride); pixfmt destpf(destrbuf); renderer_base destrb(destpf); agg::rect_base<int> region(destx, desty, (int)r, srcheight - (int)b); destrb.copy_from(aggRenderer->renderingBuffer, ®ion, -destx, -desty); } else { has_bbox = false; destbuffer = NULL; destx = desty = destwidth = destheight = deststride = 0; } /* setup tkblock */ block.pixelSize = 1; if (mode == 0) { block.offset[0] = block.offset[1] = block.offset[2] = 0; nval = 1; } else { block.offset[0] = 0; block.offset[1] = 1; block.offset[2] = 2; if (mode == 1) { block.offset[3] = 0; block.pixelSize = 3; nval = 3; } else { block.offset[3] = 3; block.pixelSize = 4; nval = 4; } } if (has_bbox) { block.width = destwidth; block.height = destheight; block.pitch = deststride; block.pixelPtr = destbuffer; Tk_PhotoPutBlock(photo, &block, destx, desty, destwidth, destheight); delete [] destbuffer; } else { block.width = aggRenderer->get_width(); block.height = aggRenderer->get_height(); block.pitch = block.width * nval; block.pixelPtr = aggRenderer->pixBuffer; /* Clear current contents */ Tk_PhotoBlank(photo); /* Copy opaque block to photo image, and leave the rest to TK */ Tk_PhotoPutBlock(photo, &block, 0, 0, block.width, block.height); } return TCL_OK; }
static int PyImagingPhotoPut(ClientData clientdata, Tcl_Interp* interp, int argc, char **argv) { Imaging im; Tk_PhotoHandle photo; Tk_PhotoImageBlock block; if (argc != 3) { Tcl_AppendResult(interp, "usage: ", argv[0], " destPhoto srcImage", (char *) NULL); return TCL_ERROR; } /* get Tcl PhotoImage handle */ photo = Tk_FindPhoto(interp, argv[1]); if (photo == NULL) { Tcl_AppendResult( interp, "destination photo must exist", (char *) NULL ); return TCL_ERROR; } /* get PIL Image handle */ im = ImagingFind(argv[2]); if (!im) { Tcl_AppendResult(interp, "bad name", (char*) NULL); return TCL_ERROR; } if (!im->block) { Tcl_AppendResult(interp, "bad display memory", (char*) NULL); return TCL_ERROR; } /* Active region */ #if 0 if (src_xoffset + xsize > im->xsize) xsize = im->xsize - src_xoffset; if (src_yoffset + ysize > im->ysize) ysize = im->ysize - src_yoffset; if (xsize < 0 || ysize < 0 || src_xoffset >= im->xsize || src_yoffset >= im->ysize) return TCL_OK; #endif /* Mode */ if (strcmp(im->mode, "1") == 0 || strcmp(im->mode, "L") == 0) { block.pixelSize = 1; block.offset[0] = block.offset[1] = block.offset[2] = 0; } else if (strncmp(im->mode, "RGB", 3) == 0) { block.pixelSize = 4; block.offset[0] = 0; block.offset[1] = 1; block.offset[2] = 2; if (strcmp(im->mode, "RGBA") == 0) block.offset[3] = 3; /* alpha (or reserved, under 8.2) */ else block.offset[3] = 0; /* no alpha */ } else { Tcl_AppendResult(interp, "Bad mode", (char*) NULL); return TCL_ERROR; } block.width = im->xsize; block.height = im->ysize; block.pitch = im->linesize; block.pixelPtr = (unsigned char*) im->block; #if 0 block.pixelPtr = (unsigned char*) im->block + src_yoffset * im->linesize + src_xoffset * im->pixelsize; #endif #if TK < 85 /* Tk 8.4 */ Tk_PhotoPutBlock(photo, &block, 0, 0, block.width, block.height, TK_PHOTO_COMPOSITE_SET); if (strcmp(im->mode, "RGBA") == 0) /* Tk workaround: we need apply ToggleComplexAlphaIfNeeded */ /* (fixed in Tk 8.5a3) */ Tk_PhotoSetSize(photo, block.width, block.height); #else /* Tk 8.5 */ Tk_PhotoPutBlock(interp, photo, &block, 0, 0, block.width, block.height, TK_PHOTO_COMPOSITE_SET); #endif return TCL_OK; }
static int StringReadNAO( Tcl_Interp *interp, Tcl_Obj *nap_expr, /* string containing NAP expression */ Tcl_Obj *format, /* format string not used */ Tk_PhotoHandle imageHandle, int destX, int destY, int width, int height, int srcX, int srcY) { int naoWidth; int naoHeight; int naoDepth; Nap_NAO *naoPtr; Nap_NAO *naoPtr0; int rank; Tk_PhotoImageBlock block; NapClientData *nap_cd = Nap_GetClientData(interp); naoPtr0 = Nap_GetNaoFromObj(nap_cd, nap_expr); CHECK2(naoPtr0, "StringReadNAO: error calling Nap_GetNaoFromObj"); Nap_IncrRefCount(nap_cd, naoPtr0); naoPtr = Nap_CastNAO(nap_cd, naoPtr0, NAP_U8); Nap_IncrRefCount(nap_cd, naoPtr); Nap_DecrRefCount(nap_cd, naoPtr0); rank = naoPtr->rank; switch (rank) { case 2: naoWidth = naoPtr->shape[1]; naoHeight = naoPtr->shape[0]; break; case 3: naoWidth = naoPtr->shape[2]; naoHeight = naoPtr->shape[1]; naoDepth = naoPtr->shape[0]; break; default: CHECK2(0, "StringReadNAO: Rank is not 1 or 2"); } /* * Setup the dimensions for the display */ if ((srcX + width) > naoWidth) { width = naoWidth - srcX; } if ((srcY + height) > naoHeight) { height = naoHeight - srcY; } if ((width <= 0) || (height <= 0) || (srcX >= naoWidth) || (srcY >= naoHeight)) { return TCL_OK; } /* * Get the output window open to the correct size */ Tk_PhotoExpand(imageHandle, destX + width, destY + height); /* * setup the supporting image data structure */ block.width = naoWidth; block.height = naoHeight; block.pitch = naoWidth; /* Address difference between corresponding * pixels in successive lines */ block.pixelSize = 1; /* Address difference successive pixels * in the same line */ /* Address differences between the red, green * and blue components of the pixel and the * pixel as a whole. */ block.offset[0] = 0; block.offset[1] = 0; block.offset[2] = 0; if (rank == 3) { if(naoDepth >= 3) { block.offset[1] = naoHeight*naoWidth; block.offset[2] = 2 * naoWidth*naoHeight; } else if(naoDepth == 2) { block.offset[2] = naoWidth*naoHeight; } } /* Pointer to the first part of the first pixel */ block.pixelPtr = (unsigned char *) naoPtr->data.U8; Tk_PhotoPutBlock(imageHandle, &block, destX, destY, naoWidth, naoHeight, TK_PHOTO_COMPOSITE_OVERLAY); Nap_DecrRefCount(nap_cd, naoPtr); return TCL_OK; }
static int StringReadPPM( Tcl_Interp *interp, /* Interpreter to use for reporting errors. */ Tcl_Obj *dataObj, /* The image data. */ Tcl_Obj *format, /* User-specified format string, or NULL. */ Tk_PhotoHandle imageHandle, /* The photo image to write into. */ int destX, int destY, /* Coordinates of top-left pixel in photo * image to be written to. */ int width, int height, /* Dimensions of block of photo image to be * written to. */ int srcX, int srcY) /* Coordinates of top-left pixel to be used in * image being read. */ { int fileWidth, fileHeight, maxIntensity; int nLines, nBytes, h, type, count, dataSize; unsigned char *pixelPtr, *dataBuffer; Tk_PhotoImageBlock block; type = ReadPPMStringHeader(dataObj, &fileWidth, &fileHeight, &maxIntensity, &dataBuffer, &dataSize); if (type == 0) { Tcl_AppendResult(interp, "couldn't read raw PPM header from string", NULL); return TCL_ERROR; } if ((fileWidth <= 0) || (fileHeight <= 0)) { Tcl_AppendResult(interp, "PPM image data has dimension(s) <= 0", NULL); return TCL_ERROR; } if ((maxIntensity <= 0) || (maxIntensity >= 256)) { char buffer[TCL_INTEGER_SPACE]; sprintf(buffer, "%d", maxIntensity); Tcl_AppendResult(interp, "PPM image data has bad maximum intensity value ", buffer, NULL); return TCL_ERROR; } if ((srcX + width) > fileWidth) { width = fileWidth - srcX; } if ((srcY + height) > fileHeight) { height = fileHeight - srcY; } if ((width <= 0) || (height <= 0) || (srcX >= fileWidth) || (srcY >= fileHeight)) { return TCL_OK; } if (type == PGM) { block.pixelSize = 1; block.offset[0] = 0; block.offset[1] = 0; block.offset[2] = 0; } else { block.pixelSize = 3; block.offset[0] = 0; block.offset[1] = 1; block.offset[2] = 2; } block.offset[3] = 0; block.width = width; block.pitch = block.pixelSize * fileWidth; if (srcY > 0) { dataBuffer += srcY * block.pitch; dataSize -= srcY * block.pitch; } if (maxIntensity == 255) { /* * We have all the data in memory, so write everything in one go. */ if (block.pitch*height > dataSize) { Tcl_AppendResult(interp, "truncated PPM data", NULL); return TCL_ERROR; } block.pixelPtr = dataBuffer + srcX * block.pixelSize; block.height = height; return Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY, width, height, TK_PHOTO_COMPOSITE_SET); } if (Tk_PhotoExpand(interp, imageHandle, destX + width, destY + height) != TCL_OK) { return TCL_ERROR; } nLines = (MAX_MEMORY + block.pitch - 1) / block.pitch; if (nLines > height) { nLines = height; } if (nLines <= 0) { nLines = 1; } nBytes = nLines * block.pitch; pixelPtr = (unsigned char *) ckalloc((unsigned) nBytes); block.pixelPtr = pixelPtr + srcX * block.pixelSize; for (h = height; h > 0; h -= nLines) { unsigned char *p; if (nLines > h) { nLines = h; nBytes = nLines * block.pitch; } if (dataSize < nBytes) { ckfree((char *) pixelPtr); Tcl_AppendResult(interp, "truncated PPM data", NULL); return TCL_ERROR; } for (p=pixelPtr,count=nBytes ; count>0 ; count--,p++,dataBuffer++) { *p = (((int) *dataBuffer) * 255)/maxIntensity; } dataSize -= nBytes; block.height = nLines; if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY, width, nLines, TK_PHOTO_COMPOSITE_SET) != TCL_OK) { ckfree((char *) pixelPtr); return TCL_ERROR; } destY += nLines; } ckfree((char *) pixelPtr); return TCL_OK; }
static int FileReadPPM( Tcl_Interp *interp, /* Interpreter to use for reporting errors. */ Tcl_Channel chan, /* The image file, open for reading. */ CONST char *fileName, /* The name of the image file. */ Tcl_Obj *format, /* User-specified format string, or NULL. */ Tk_PhotoHandle imageHandle, /* The photo image to write into. */ int destX, int destY, /* Coordinates of top-left pixel in photo * image to be written to. */ int width, int height, /* Dimensions of block of photo image to be * written to. */ int srcX, int srcY) /* Coordinates of top-left pixel to be used in * image being read. */ { int fileWidth, fileHeight, maxIntensity; int nLines, nBytes, h, type, count; unsigned char *pixelPtr; Tk_PhotoImageBlock block; type = ReadPPMFileHeader(chan, &fileWidth, &fileHeight, &maxIntensity); if (type == 0) { Tcl_AppendResult(interp, "couldn't read raw PPM header from file \"", fileName, "\"", NULL); return TCL_ERROR; } if ((fileWidth <= 0) || (fileHeight <= 0)) { Tcl_AppendResult(interp, "PPM image file \"", fileName, "\" has dimension(s) <= 0", NULL); return TCL_ERROR; } if ((maxIntensity <= 0) || (maxIntensity >= 256)) { char buffer[TCL_INTEGER_SPACE]; sprintf(buffer, "%d", maxIntensity); Tcl_AppendResult(interp, "PPM image file \"", fileName, "\" has bad maximum intensity value ", buffer, NULL); return TCL_ERROR; } if ((srcX + width) > fileWidth) { width = fileWidth - srcX; } if ((srcY + height) > fileHeight) { height = fileHeight - srcY; } if ((width <= 0) || (height <= 0) || (srcX >= fileWidth) || (srcY >= fileHeight)) { return TCL_OK; } if (type == PGM) { block.pixelSize = 1; block.offset[0] = 0; block.offset[1] = 0; block.offset[2] = 0; } else { block.pixelSize = 3; block.offset[0] = 0; block.offset[1] = 1; block.offset[2] = 2; } block.offset[3] = 0; block.width = width; block.pitch = block.pixelSize * fileWidth; if (Tk_PhotoExpand(interp, imageHandle, destX + width, destY + height) != TCL_OK) { return TCL_ERROR; } if (srcY > 0) { Tcl_Seek(chan, (Tcl_WideInt)(srcY * block.pitch), SEEK_CUR); } nLines = (MAX_MEMORY + block.pitch - 1) / block.pitch; if (nLines > height) { nLines = height; } if (nLines <= 0) { nLines = 1; } nBytes = nLines * block.pitch; pixelPtr = (unsigned char *) ckalloc((unsigned) nBytes); block.pixelPtr = pixelPtr + srcX * block.pixelSize; for (h = height; h > 0; h -= nLines) { if (nLines > h) { nLines = h; nBytes = nLines * block.pitch; } count = Tcl_Read(chan, (char *) pixelPtr, nBytes); if (count != nBytes) { Tcl_AppendResult(interp, "error reading PPM image file \"", fileName, "\": ", Tcl_Eof(chan) ? "not enough data" : Tcl_PosixError(interp), NULL); ckfree((char *) pixelPtr); return TCL_ERROR; } if (maxIntensity != 255) { unsigned char *p; for (p = pixelPtr; count > 0; count--, p++) { *p = (((int) *p) * 255)/maxIntensity; } } block.height = nLines; if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY, width, nLines, TK_PHOTO_COMPOSITE_SET) != TCL_OK) { ckfree((char *) pixelPtr); return TCL_ERROR; } destY += nLines; } ckfree((char *) pixelPtr); return TCL_OK; }