FilterFactory - Symbol "d"

Back to function listing

Direction (angle) of the current pixel from the center of the image, where d is an integer between -512 and 512, inclusive.

Note: FilterFactory defines c2d(x,y) := atan2(y,x), but d := atan2(-y,-x)

Errors in the Filter Factory manuals

The manual of Filter Factory for Photoshop states the range as -511 and 512, inclusive, which is wrong for both implementations (Windows and MacOS).
The correct range is -512 and 512, inclusive.

The manual of Filter Factory for Premiere states the range as 0 and 1024, which is also not true.
At least for the Windows implementation, the range seems to be approx. -512 till 512, but I could not detect the exact range (so it could also be 511 instead of 512).

Another mistake in the Filter Factory manuals is the orientation:
The Filter Factory manual writes:

d=0 corresponds to the 3 o’clock position
d=256 to the 6 o’clock position
d=512 to the 9 o’clock position
d=768 to the 12 o’clock position
d=1024 to the full rotation back to the 3 o’clock position

But this does neither match the Windows implementation of Filter Factory nor its Mac OS implementation! In the original Windows & Mac OS Filter Factory implementations we can observe:

d=-512 is at 9 o’clock position
d=-256 is at 12 o’clock position
d=0 is at 3 o’clock position
d=256 is at 6 o’clock position
d=512 is the full rotation back to the 9 o’clock position

Syntax

d

Synonyms

d0
d1

Original Machine Code (in OPER resource) of Filter Factory 3.0 and 3.0.4 for Photoshop/Win32

8B 47 54 mov eax,[edi+$54] (Y) .
8B 5F 48 mov ebx,[edi+$48] (X) .
2B 47 50 sub eax,[edi+$50] (ymin) .
2B 5F 44 sub ebx,[edi+$44] (xmin) .
D1 E8 shr eax,1 .
D1 EB shr ebx,1 .
F7 D8 neg eax eax = -(Y - ymin)/2;
F7 DB neg ebx ebx = -(X - xmin)/2;
33 C9 xor ecx,ecx ecx = 0;
03 47 4C add eax,[edi+$4c] (y) eax += y;
79 05 jns +$05 (@@1) if (eax >= 0) goto @@1;
F7 D8 neg eax eax = -eax;
80 C9 04 or cl,$04 (4) ecx |= 4;
@@1: @@1:
03 5F 40 add ebx,[edi+$40] (x) ebx += x;
79 05 jns +$05 (@@2) if (ebx >= 0) goto @@2;
F7 DB neg ebx ebx = -ebx;
80 C9 03 or cl,$03 (3) ecx |= 3;
@@2: @@2:
3B C3 cmp eax,ebx .
7E 04 jle +$04 (@@3) if (eax <= ebx) goto @@3;
80 F1 01 xor cl,$01 (1) ecx ^= 1;
93 xchg eax,ebx swp = ebx; ebx = eax; eax = swp;
@@3: @@3:
0B C0 or eax,eax .
7E 1B jle +$1b (@@4) if (eax <= 0) goto @@4;
C1 E0 0A shl eax,$0a (10) eax = eax << $0a; // eax *= $400;
99 cdq edx = signbit(eax);
F7 F3 div ebx eax /= ebx;
74 13 jz +$13 (@@4) if (eax == 0) goto @@4; // C2D_LOOKUP[-1] will never be called. Good!
66 8B 84 47 76 0D 00 00 mov ax,[edi+eax*2+$00000d76] (C2D_LOOKUP-$2) ax = C2D_LOOKUP[eax-1];
C1 E0 09 shl eax,$09 (9) eax = eax << $09; // eax *= $200;
99 cdq edx = signbit(eax);
BB 40 24 03 00 mov ebx,$00032440 (205888) ebx = $32440;
F7 FB idiv ebx eax /= ebx;
@@4: @@4:
66 0F BA E1 00 bt cx,$00 (0) bit 0 set?
73 07 jnb +$07 (@@5) if ((ecx & 0b1) != 0) goto @@5;
F7 D8 neg eax eax = -eax;
05 00 01 00 00 add eax,$00000100 (256) eax += $100;
@@5: @@5:
66 0F BA E1 01 bt cx,$01 (1) bit 1 set?
73 05 jnb +$05 (@@6) if ((ecx & 0b10) != 0) goto @@6;
05 00 01 00 00 add eax,$00000100 (256) eax += $100;
@@6: @@6:
66 0F BA E1 02 bt cx,$02 (2) bit 2 set?
73 02 jnb +$02 (@@7) if ((ecx & 0b100) != 0) goto @@7;
F7 D8 neg eax eax = -eax;
@@7: @@7:
50 push eax return eax;

C++ code

int Y, ymin, X, xmin;

int factory_d() {
	int eax, ebx, ecx;

	eax = -(Y - ymin) / 2;
	ebx = -(X - xmin) / 2;
	ecx = 0;
	eax += y;
	if (eax < 0) {
		eax = -eax;
		ecx |= 0b0100;
	}
	ebx += x;
	if (ebx < 0) {
		ebx = -ebx;
		ecx |= 0b0011;
	}
	if (eax > ebx) {
		ecx ^= 0b0001;
		int xxx = eax;
		eax = ebx;
		ebx = xxx;
	}
	if (eax > 0) {
		eax = eax << 10;
		eax /= ebx;
		if (eax != 0) { // C2D_LOOKUP[-1] will never be called. Good!
			eax = (eax & 0xFFFF0000) + (C2D_LOOKUP[eax-1] & 0xFFFF);
			eax = eax << 9;
			ebx = 205888; // 205888/65536 == pi
			eax /= ebx;
		}
	}
	if ((ecx & 0b0001) != 0) {
		eax = -eax;
		eax += 256;
	}
	if ((ecx & 0b0010) != 0) {
		eax += 256;
	}
	if ((ecx & 0b0100) != 0) {
		eax = -eax;
	}
	return eax;
}