summaryrefslogtreecommitdiffstats
path: root/tkimg/base/tkimgPPB.c
blob: 4575854e3bca219cb4ddfe920aaeaf1dd1fca568 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*

 * tkimgPPB.tcl

 */

#include <string.h>

#include "tkimg.h"


/*

 * Make sure that all Tk's stub entries are available, no matter what

 * Tcl version we compile against.

 */
#undef Tk_PhotoPutBlock /* 266 */

#define Tk_PhotoPutBlock ((int (*)(Tcl_Interp *, Tk_PhotoHandle, Tk_PhotoImageBlock *, int, int, int, int, int)) *((&tkStubsPtr->tk_MainLoop)+266))

#undef Tk_PhotoPutBlock_Panic /* 246 */

#define Tk_PhotoPutBlock_Panic ((void (*)(Tk_PhotoHandle, Tk_PhotoImageBlock *, int, int, int, int, int)) *((&tkStubsPtr->tk_MainLoop)+246))

#undef Tk_PhotoPutBlock_NoComposite /* 144 */

#define Tk_PhotoPutBlock_NoComposite ((void (*)(Tk_PhotoHandle, Tk_PhotoImageBlock *, int, int, int, int)) *((&tkStubsPtr->tk_MainLoop)+144))

#undef Tk_PhotoExpand /* 265 */

#define Tk_PhotoExpand ((int (*)(Tcl_Interp *, Tk_PhotoHandle, int, int)) *((&tkStubsPtr->tk_MainLoop)+265))

#undef Tk_PhotoExpand_Panic /* 148 */

#define Tk_PhotoExpand_Panic ((void (*)(Tk_PhotoHandle, int, int)) *((&tkStubsPtr->tk_MainLoop)+148))

#undef Tk_PhotoSetSize /* 268 */

#define Tk_PhotoSetSize ((int (*)(Tcl_Interp *, Tk_PhotoHandle, int, int)) *((&tkStubsPtr->tk_MainLoop)+268))

#undef Tk_PhotoSetSize_Panic /* 150 */

#define Tk_PhotoSetSize_Panic ((int (*)(Tk_PhotoHandle, int, int)) *((&tkStubsPtr->tk_MainLoop)+150))


/*

 *----------------------------------------------------------------------

 *

 * tkimg_PhotoPutBlock --

 *

 *  This procedure is called to put image data into a photo image.

 *  The difference with Tk_PhotoPutBlock is that it handles the

 *  transparency information as well.

 *

 * Results:

 *  None.

 *

 * Side effects:

 *  The image data is stored.  The image may be expanded.

 *  The Tk image code is informed that the image has changed.

 *

 *----------------------------------------------------------------------

 */

int tkimg_PhotoPutBlock(
	Tcl_Interp *interp, /* Interpreter for error-reporting. */
	Tk_PhotoHandle handle, /* Opaque handle for the photo image to be updated. */
	Tk_PhotoImageBlock *blockPtr, /* Pointer to a structure describing the

	 * pixel data to be copied into the image. */
	int x, /* Coordinates of the top-left pixel to */
	int y, /* be updated in the image. */
	int width, /* Dimensions of the area of the image */
	int height,/* to be updated. */
	int flags /* TK_PHOTO_COMPOSITE_OVERLAY or TK_PHOTO_COMPOSITE_SET */
) {
	if (tkimg_initialized & IMG_NOPANIC) {
		return Tk_PhotoPutBlock(interp, handle, blockPtr, x, y, width, height, flags);
	}
	if (tkimg_initialized & IMG_COMPOSITE) {
		Tk_PhotoPutBlock_Panic(handle, blockPtr, x, y, width, height, flags);
		return TCL_OK;
	}
	if (0 && (flags == TK_PHOTO_COMPOSITE_OVERLAY)) {
		int alphaOffset = blockPtr->offset[3];
		if ((alphaOffset< 0) || (alphaOffset>= blockPtr->pixelSize)) {
			alphaOffset = blockPtr->offset[0];
			if (alphaOffset < blockPtr->offset[1]) {
				alphaOffset = blockPtr->offset[1];
			}
			if (alphaOffset < blockPtr->offset[2]) {
				alphaOffset = blockPtr->offset[2];
			}
			if (++alphaOffset >= blockPtr->pixelSize) {
				alphaOffset = blockPtr->offset[0];
			}
		} else {
			if ((alphaOffset == blockPtr->offset[1]) ||
				(alphaOffset == blockPtr->offset[2])) {
				alphaOffset = blockPtr->offset[0];
			}
		}
		if (alphaOffset != blockPtr->offset[0]) {
			int X, Y, end;
			unsigned char *pixelPtr, *imagePtr, *rowPtr;
			rowPtr = imagePtr = blockPtr->pixelPtr;
			for (Y = 0; Y < height; Y++) {
				X = 0;
				pixelPtr = rowPtr + alphaOffset;
				while (X < width) {
					/* search for first non-transparent pixel */
					while ((X < width) && !(*pixelPtr)) {
						X++; pixelPtr += blockPtr->pixelSize;
					}
					end = X;
					/* search for first transparent pixel */
					while ((end < width) && *pixelPtr) {
						end++; pixelPtr += blockPtr->pixelSize;
					}
					if (end > X) {
						blockPtr->pixelPtr = rowPtr + blockPtr->pixelSize * X;
						Tk_PhotoPutBlock_NoComposite(handle, blockPtr, x+X, y+Y, end-X, 1);
					}
					X = end;
				}
				rowPtr += blockPtr->pitch;
			}
			blockPtr->pixelPtr = imagePtr;
			return TCL_OK;
		}
	}
	Tk_PhotoPutBlock_NoComposite(handle, blockPtr, x, y, width, height);
	return TCL_OK;
}

int tkimg_PhotoExpand(
	Tcl_Interp *interp, /* Interpreter for error-reporting. */
	Tk_PhotoHandle handle, /* Opaque handle for the photo image

	 * to be updated. */
	int width, /* Dimensions of the area of the image */
	int height /* to be updated. */
) {
	if (tkimg_initialized & IMG_NOPANIC) {
		return Tk_PhotoExpand(interp, handle, width, height);
	}
	Tk_PhotoExpand_Panic(handle, width, height);
	return TCL_OK;
}

int tkimg_PhotoSetSize(
	Tcl_Interp *interp, /* Interpreter for error-reporting. */
	Tk_PhotoHandle handle, /* Opaque handle for the photo image

	 * to be updated. */
	int width, /* Dimensions of the area of the image */
	int height /* to be updated. */
) {
	if (tkimg_initialized & IMG_NOPANIC) {
		return Tk_PhotoSetSize(interp, handle, width, height);
	}
	Tk_PhotoSetSize_Panic(handle, width, height);
	return TCL_OK;
}