1/*
2 * tkimgPPB.tcl
3 */
4
5#include <string.h>
6#include "tkimg.h"
7
8/*
9 * Make sure that all Tk's stub entries are available, no matter what
10 * Tcl version we compile against.
11 */
12#undef Tk_PhotoPutBlock /* 266 */
13#define Tk_PhotoPutBlock ((int (*)(Tcl_Interp *, Tk_PhotoHandle, Tk_PhotoImageBlock *, int, int, int, int, int)) *((&tkStubsPtr->tk_MainLoop)+266))
14#undef Tk_PhotoPutBlock_Panic /* 246 */
15#define Tk_PhotoPutBlock_Panic ((void (*)(Tk_PhotoHandle, Tk_PhotoImageBlock *, int, int, int, int, int)) *((&tkStubsPtr->tk_MainLoop)+246))
16#undef Tk_PhotoPutBlock_NoComposite /* 144 */
17#define Tk_PhotoPutBlock_NoComposite ((void (*)(Tk_PhotoHandle, Tk_PhotoImageBlock *, int, int, int, int)) *((&tkStubsPtr->tk_MainLoop)+144))
18#undef Tk_PhotoExpand /* 265 */
19#define Tk_PhotoExpand ((int (*)(Tcl_Interp *, Tk_PhotoHandle, int, int)) *((&tkStubsPtr->tk_MainLoop)+265))
20#undef Tk_PhotoExpand_Panic /* 148 */
21#define Tk_PhotoExpand_Panic ((void (*)(Tk_PhotoHandle, int, int)) *((&tkStubsPtr->tk_MainLoop)+148))
22#undef Tk_PhotoSetSize /* 268 */
23#define Tk_PhotoSetSize ((int (*)(Tcl_Interp *, Tk_PhotoHandle, int, int)) *((&tkStubsPtr->tk_MainLoop)+268))
24#undef Tk_PhotoSetSize_Panic /* 150 */
25#define Tk_PhotoSetSize_Panic ((int (*)(Tk_PhotoHandle, int, int)) *((&tkStubsPtr->tk_MainLoop)+150))
26
27/*
28 *----------------------------------------------------------------------
29 *
30 * tkimg_PhotoPutBlock --
31 *
32 *  This procedure is called to put image data into a photo image.
33 *  The difference with Tk_PhotoPutBlock is that it handles the
34 *  transparency information as well.
35 *
36 * Results:
37 *  None.
38 *
39 * Side effects:
40 *  The image data is stored.  The image may be expanded.
41 *  The Tk image code is informed that the image has changed.
42 *
43 *----------------------------------------------------------------------
44 */
45
46int tkimg_PhotoPutBlock(
47	Tcl_Interp *interp, /* Interpreter for error-reporting. */
48	Tk_PhotoHandle handle, /* Opaque handle for the photo image to be updated. */
49	Tk_PhotoImageBlock *blockPtr, /* Pointer to a structure describing the
50	 * pixel data to be copied into the image. */
51	int x, /* Coordinates of the top-left pixel to */
52	int y, /* be updated in the image. */
53	int width, /* Dimensions of the area of the image */
54	int height,/* to be updated. */
55	int flags /* TK_PHOTO_COMPOSITE_OVERLAY or TK_PHOTO_COMPOSITE_SET */
56) {
57	if (tkimg_initialized & IMG_NOPANIC) {
58		return Tk_PhotoPutBlock(interp, handle, blockPtr, x, y, width, height, flags);
59	}
60	if (tkimg_initialized & IMG_COMPOSITE) {
61		Tk_PhotoPutBlock_Panic(handle, blockPtr, x, y, width, height, flags);
62		return TCL_OK;
63	}
64	if (0 && (flags == TK_PHOTO_COMPOSITE_OVERLAY)) {
65		int alphaOffset = blockPtr->offset[3];
66		if ((alphaOffset< 0) || (alphaOffset>= blockPtr->pixelSize)) {
67			alphaOffset = blockPtr->offset[0];
68			if (alphaOffset < blockPtr->offset[1]) {
69				alphaOffset = blockPtr->offset[1];
70			}
71			if (alphaOffset < blockPtr->offset[2]) {
72				alphaOffset = blockPtr->offset[2];
73			}
74			if (++alphaOffset >= blockPtr->pixelSize) {
75				alphaOffset = blockPtr->offset[0];
76			}
77		} else {
78			if ((alphaOffset == blockPtr->offset[1]) ||
79				(alphaOffset == blockPtr->offset[2])) {
80				alphaOffset = blockPtr->offset[0];
81			}
82		}
83		if (alphaOffset != blockPtr->offset[0]) {
84			int X, Y, end;
85			unsigned char *pixelPtr, *imagePtr, *rowPtr;
86			rowPtr = imagePtr = blockPtr->pixelPtr;
87			for (Y = 0; Y < height; Y++) {
88				X = 0;
89				pixelPtr = rowPtr + alphaOffset;
90				while (X < width) {
91					/* search for first non-transparent pixel */
92					while ((X < width) && !(*pixelPtr)) {
93						X++; pixelPtr += blockPtr->pixelSize;
94					}
95					end = X;
96					/* search for first transparent pixel */
97					while ((end < width) && *pixelPtr) {
98						end++; pixelPtr += blockPtr->pixelSize;
99					}
100					if (end > X) {
101						blockPtr->pixelPtr = rowPtr + blockPtr->pixelSize * X;
102						Tk_PhotoPutBlock_NoComposite(handle, blockPtr, x+X, y+Y, end-X, 1);
103					}
104					X = end;
105				}
106				rowPtr += blockPtr->pitch;
107			}
108			blockPtr->pixelPtr = imagePtr;
109			return TCL_OK;
110		}
111	}
112	Tk_PhotoPutBlock_NoComposite(handle, blockPtr, x, y, width, height);
113	return TCL_OK;
114}
115
116int tkimg_PhotoExpand(
117	Tcl_Interp *interp, /* Interpreter for error-reporting. */
118	Tk_PhotoHandle handle, /* Opaque handle for the photo image
119	 * to be updated. */
120	int width, /* Dimensions of the area of the image */
121	int height /* to be updated. */
122) {
123	if (tkimg_initialized & IMG_NOPANIC) {
124		return Tk_PhotoExpand(interp, handle, width, height);
125	}
126	Tk_PhotoExpand_Panic(handle, width, height);
127	return TCL_OK;
128}
129
130int tkimg_PhotoSetSize(
131	Tcl_Interp *interp, /* Interpreter for error-reporting. */
132	Tk_PhotoHandle handle, /* Opaque handle for the photo image
133	 * to be updated. */
134	int width, /* Dimensions of the area of the image */
135	int height /* to be updated. */
136) {
137	if (tkimg_initialized & IMG_NOPANIC) {
138		return Tk_PhotoSetSize(interp, handle, width, height);
139	}
140	Tk_PhotoSetSize_Panic(handle, width, height);
141	return TCL_OK;
142}
143