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; |
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;
}