/trunk/BUILDING.md |
---|
108,7 → 108,7 |
For 32 bit "i686" and for 64 bit "x86_64" |
* Check if all paths inside the file "make_mingw32.bat" are valid, then run it. |
The files FilterFoundry.8bf (32 Bit) and FilterFoundry64.8bf (64 Bit) should now be generated. |
* Most recently tested with mingw64 and Adobe Photoshop SDK 2022: |
* Most recently tested with mingw64 and Adobe Photoshop SDK 2021: |
- i686-8.1.0-posix-dwarf-rt_v6-rev0 for 32 Bit |
- x86_64-8.1.0-posix-seh-rt_v6-rev0 for 64 Bit |
/trunk/CHANGELOG.md |
---|
1,5 → 1,8 |
# Changelog |
## 1.7.0.12 [Work-In-Progress] |
- Added possibility to load PluginCommander TXT files. |
## 1.7.0.11 [01-Nov-2021] |
- Tab-Order has been changed (*) |
- Fixed incompatibility with older versions of Wine (Windows emulator for Linux systems) |
/trunk/PARM.h |
---|
73,7 → 73,7 |
#else |
// Note: In Windows DLL/8BF files, the strings are C-strings, while in MAC-plugins they are Pascal-strings! |
// However, internally, we work with Pascal Strings: |
// However, internally, we work with Pascal Strings (TODO: I don't like that!): |
// readPARM() converts C to Pascal strings, and doresources() converts them back to C strings for saving. |
// formulas are never Pascal strings. |
/trunk/README.md |
---|
31,7 → 31,7 |
- Serif PhotoPlus 6 |
- PluginCommander 1.62 (Revision 2) |
- Paint.Net using [PSFilterPdn](https://github.com/0xC0000054/PSFilterPdn) to run Photoshop .8bf files |
- I.C.NET Plugin-Manager 2.x and Filters Unlimited (though these are technically emulators rather than hosts) |
- I.C.NET Plugin-Manager 2.x, Filters Unlimited and Plugin Galaxy (though these are technically emulators rather than hosts) |
Operating systems: |
/trunk/TODO.md |
---|
2,6 → 2,25 |
Wishlist/ToDo-List |
================== |
Current TODO |
------------ |
* Finish loading of TXT files: |
- txt_afs_cr.txt |
- txt_afs_crlf.txt |
- txt_afs_lf.txt |
- txt_afs_ffdcomp.txt |
- txt_afs_ffpico.txt |
* Verify that PiCo and PluginGalaxy have same TXT format |
* Saving TXT files: PluginCommander file format |
* Load/Save AFS/PFF files: Run with ApplicationVerifier |
* Document Loading/Saving file formats in documentation & add PluginGalaxy as compatible (loading) |
Known bugs |
---------- |
/trunk/ff.h |
---|
112,6 → 112,7 |
Handle readfileintohandle(FILEREF r); |
Boolean readfile_afs_pff(StandardFileReply* sfr, char** reason); |
Boolean readfile_ffx(StandardFileReply* sfr, char** reason); |
Boolean readfile_picotxt(StandardFileReply* sfr, char** reason); |
Boolean readPARM(Ptr h,PARM_T *parm,char **reasonstr,int fromwin); |
// from save.c |
/trunk/load_mac.c |
---|
84,6 → 84,11 |
gdata->parmloaded = true; |
gdata->obfusc = false; |
} // then try "PluginCommander TXT" file (TXT) |
else if( (readok = readfile_picotxt(sfr,reason)) ) { |
gdata->parmloaded = true; |
gdata->obfusc = false; |
} // then try plugin formats (Mac first, then Windows .8bf or .prm DLL) |
else if( (readok = readmacplugin(sfr,reason) || readfile_8bf(sfr,reason)) ){ |
if ((gdata->parm.cbSize != PARM_SIZE) && (gdata->parm.cbSize != PARM_SIZE_PREMIERE) && (gdata->parm.cbSize != PARM_SIG_MAC)) { |
/trunk/load_win.c |
---|
117,6 → 117,13 |
} |
} |
// Is it a "Filters Unlimited" filter? (Only partially compatible with Filter Factory!!!) |
if (!readok) { |
if (readfile_picotxt(sfr, reason)) { |
readok = gdata->parmloaded = true; |
} |
} |
// If nothing worked, we will try to find a PARM resource (MacOS plugin, or NE executable on Win64) |
if (!readok) { |
if (readfile_8bf(sfr, reason)) { |
/trunk/photoshop_sdk/DOWNLOAD.txt |
---|
8,8 → 8,8 |
3. You need to create a Adobe developer account now, |
or log in if you already have an account. |
4. Scroll down to "Photoshop" (NOT "Adobe Photoshop API (Trial)") |
and then click "View downloads". |
4. At the top, click the tab "Downloads", then scroll down and and search for "Photoshop" |
(NOT "Adobe Photoshop API (Trial)") and then click "View downloads". |
5. Download "Photoshop Plug-In and Connection SDK" for Windows. |
43,7 → 43,7 |
Compatibility: |
The source code has been built with SDK 6.0, CS2, CS3 beta, CC 2017, and 2022 |
The source code has been built with SDK 6.0, CS2, CS3 beta, CC 2017, and 2021 |
but older versions should work, too. |
(If building with SDK v4, edit 68k.r, carbon.r, classic.r, and PiMI_68k.r |
to remove references to "PIResDefines.h", "PiPL.r" and "PiMI.r" and replace |
51,7 → 51,10 |
from PiPL_common.r.) |
Additional notes: |
Additional notes in regards the SDK license: |
- The SDK contains two files names "license.html". One file in the root directory, |
which contains a clause about OpenSource software, and one file in the sub-directory |
"pluginsdk/documentation/html/" which does not mention OpenSource at all. |
- Adobe's stand in regards to using SDK to write OpenSource plugins: |
https://web.archive.org/web/20070203075622/http://blogs.adobe.com/notesfrommnr/2006/04/using_adobe_sdk.html |
So it should be fine if the SDK contents are not included in the plugin's source code and not part of the license. |
/trunk/read.c |
---|
443,6 → 443,179 |
return NULL; |
} |
Boolean _picoLineContainsKey(char* line, char** content, const char* searchkey/*=NULL*/) { |
for (size_t i = 0; i < strlen(line); i++) { |
if (line[i] == ':') { |
if ((searchkey == NULL) || (memcmp(line, searchkey, strlen(searchkey)) == 0)) { |
i++; |
while ((line[i] == ' ') || (line[i] == '\t')) i++; |
*content = line + i; |
return true; |
} |
} |
} |
*content = line; |
return false; |
} |
Boolean _picoReadProperty(char* inputFile, int maxInput, const char* property, char* outputFile, size_t maxOutput, Boolean pascalOutput) { |
char* outputwork = outputFile; |
char* sline = NULL; |
char* svalue = NULL; |
// Check parameters |
if (maxOutput <= 0) return false; |
if (inputFile == 0) return false; |
// Let input memory be read-only, +1 for terminal zero |
//char* inputwork = inputFile; |
char* inputwork = (char*)malloc(maxInput + 1); |
char* inputworkinitial = inputwork; |
if (inputwork == 0) return false; |
memcpy(inputwork, inputFile, maxInput); |
// Replace all \r and \n with \0, so that we can parse easier |
for (int i = 0; i < maxInput; i++) { |
if (inputwork[i] == 0) break; |
if (inputwork[i] == '\r') inputwork[i] = 0; |
if (inputwork[i] == '\n') inputwork[i] = 0; |
} |
// C++ wrong warning: Buffer overflow (C6386) |
// "The writeable size is "maxInput+1" Byte, but "maxInput" byte can be written". WTF? |
#pragma warning(suppress : 6386) |
inputwork[maxInput] = 0; |
// Find line that contains out key |
do { |
if (inputwork > inputworkinitial + maxInput) { |
// Key not found. Set output to empty string |
outputwork[0] = 0; |
free(inputworkinitial); |
if (pascalOutput) myc2pstr(outputFile); |
return false; |
} |
sline = inputwork; |
inputwork += strlen(sline) + 1; |
if (inputwork - 1 > inputworkinitial + maxInput) { |
// Key not found. Set output to empty string |
// TODO: will that be ever called? |
outputwork[0] = 0; |
free(inputworkinitial); |
if (pascalOutput) myc2pstr(outputFile); |
return false; |
} |
} while (!_picoLineContainsKey(sline, &svalue, property)); |
// Read line(s) until we find a line with another key, or the line end |
do { |
if (strlen(svalue) > 0) { |
if (outputwork + strlen(svalue) + 2 > outputFile + maxOutput) { |
int remaining = maxOutput - (outputwork - outputFile) - 1; |
//printf("BUFFER FULL (remaining = %d)\n", remaining); |
memcpy(outputwork, svalue, remaining); |
outputwork += remaining; |
outputwork[0] = 0; |
free(inputworkinitial); |
if (pascalOutput) myc2pstr(outputFile); |
return true; |
} |
else { |
memcpy(outputwork, svalue, strlen(svalue)); |
outputwork += strlen(svalue); |
outputwork[0] = ' '; |
outputwork++; |
} |
} |
outputwork[0] = 0; |
// Process next line |
if (inputwork > inputworkinitial + maxInput) break; |
sline = inputwork; |
inputwork += strlen(sline) + 1; |
if (inputwork - 1 > inputworkinitial + maxInput) break; |
} while (!_picoLineContainsKey(sline, &svalue, NULL)); |
// Remove trailing whitespace |
if (outputwork > outputFile) { |
outputwork -= 1; |
outputwork[0] = 0; |
} |
free(inputworkinitial); |
if (pascalOutput) myc2pstr(outputFile); |
return true; |
} |
Boolean readfile_picotxt(StandardFileReply* sfr, char** reason) { |
Handle h; |
Boolean res = false; |
FILEREF refnum; |
if (!fileHasExtension(sfr, ".txt")) return false; |
if (FSpOpenDF(&sfr->sfFile, fsRdPerm, &refnum) == noErr) { |
if ((h = readfileintohandle(refnum))) { |
FILECOUNT count = PIGETHANDLESIZE(h); |
char* q = PILOCKHANDLE(h, false); |
// TODO: Test if ffdecomp TXT file also works |
char out[256]; |
if (_picoReadProperty(q, count, "Title", out, sizeof(out), false)) { |
// Plugin infos |
_picoReadProperty(q, count, "Title", gdata->parm.title, sizeof(gdata->parm.title)-1, true); |
_picoReadProperty(q, count, "Category", gdata->parm.category, sizeof(gdata->parm.category)-1, true); |
_picoReadProperty(q, count, "Author", gdata->parm.author, sizeof(gdata->parm.author)-1, true); |
_picoReadProperty(q, count, "Copyright", gdata->parm.copyright, sizeof(gdata->parm.copyright)-1, true); |
//_picoReadProperty(q, count, "Filename", gdata->parm.xxx, sizeof(gdata->parm.xxx), false); |
// Expressions |
_picoReadProperty(q, count, "R", gdata->parm.formula[0], sizeof(gdata->parm.formula[0]), false); |
_picoReadProperty(q, count, "G", gdata->parm.formula[1], sizeof(gdata->parm.formula[1]), false); |
_picoReadProperty(q, count, "B", gdata->parm.formula[2], sizeof(gdata->parm.formula[2]), false); |
_picoReadProperty(q, count, "A", gdata->parm.formula[3], sizeof(gdata->parm.formula[3]), false); |
for (int i = 0; i < 4; i++) { |
if (expr[i]) free(expr[i]); |
expr[i] = my_strdup(gdata->parm.formula[i]); |
} |
// Slider names |
for (int i = 0; i < 8; i++) { |
char keyname[7]; |
sprintf(keyname, "ctl[%d]", i); |
_picoReadProperty(q, count, keyname, gdata->parm.ctl[i], sizeof(gdata->parm.ctl[i]), true); |
} |
// Slider values |
for (int i = 0; i < 8; i++) { |
char keyname[7], tmp[4]; |
sprintf(keyname, "val[%d]", i); |
if (!_picoReadProperty(q, count, keyname, tmp, sizeof(tmp), false)) { |
sprintf(keyname, "def[%d]", i); |
if (!_picoReadProperty(q, count, keyname, tmp, sizeof(tmp), false)) { |
tmp[0] = '0'; |
tmp[1] = 0; |
} |
} |
gdata->parm.val[i] = slider[i] = atoi(tmp); |
} |
// Map names |
for (int i = 0; i < 4; i++) { |
char keyname[7]; |
sprintf(keyname, "map[%d]", i); |
_picoReadProperty(q, count, keyname, gdata->parm.map[i], sizeof(gdata->parm.map[i]), true); |
} |
//These will be set when the expressions are evaluated: |
//gdata->parm.ctl_used[i] |
//gdata->parm.map_used[i] |
res = true; |
} |
PIUNLOCKHANDLE(h); |
PIDISPOSEHANDLE(h); |
} |
FSClose(refnum); |
} |
return res; |
} |
Boolean readfile_afs_pff(StandardFileReply *sfr,char **reason){ |
FILEREF r; |
Handle h; |
/trunk/testcases/import/txt_afs_cr.afs |
---|
/trunk/testcases/import/txt_afs_crlf.afs |
---|
0,0 → 1,18 |
%RGB-1.0 |
95 |
r |
g |
b |
a>0 ? ctl(1)<128 ? a - (256 - (2 * (ctl(1) + 1))) : a + (2 * (c |
tl(1) - 128)) : 0 |
/trunk/testcases/import/txt_afs_lf.afs |
---|
0,0 → 1,20 |
%RGB-1.0 |
95 |
r |
g |
b |
a>0 ? ctl(1)<128 ? a - (256 - (2 * (ctl(1) + 1))) : a + (2 * (c |
tl(1) - 128)) : 0 |
/trunk/testcases/import/txt_ffdcomp.TXT |
---|
0,0 → 1,43 |
Filter Factory Plugin Information: |
FILENAME: C:\WINDOWS\DESKTOP\FFDECOMP\FACTOR~1.8BF |
CATEGORY: |
Transparency |
TITLE: |
EditTransparency |
COPYRIGHT: |
Copyright © 1994 Adobe Systems, Inc. |
All Rights Reserved. |
AUTHOR: |
Ky Hopwood |
Map 0: [Map 0:] |
Map 1: [Map 1:] |
Map 2: [Map 2:] |
Map 3: [Map 3:] |
Control 0: [Control 0:] |
Control 1: [Transparency:] |
Control 2: [Control 2:] |
Control 3: [Control 3:] |
Control 4: [Control 4:] |
Control 5: [Control 5:] |
Control 6: [Control 6:] |
Control 7: [Control 7:] |
R= |
r |
G= |
g |
B= |
b |
A= |
a>0 ? ctl(1)<128 ? a - (256 - (2 * (ctl(1) + 1))) : a + (2 * (ctl(1) - 128)) : 0 |
/trunk/testcases/import/txt_pico.txt |
---|
0,0 → 1,23 |
Category: Filter Foundry |
Title: Untitled |
Copyright: |
Author: Anonymous |
Filename: xxx.8bf |
R: ctl(0) |
G: map(1,2) |
B: b |
A: a |
ctl[0]: CTL 0 |
map[1]: MAP 1 |
val[0]: 101 |
val[2]: 120 |
val[3]: 130 |
def[0]: 102 |
def[2]: 120 |
/trunk/ui.c |
---|
353,7 → 353,7 |
(StringPtr)_strdup("\026Choose filter settings"), |
#endif |
&sfr,&reply,types,2, |
"All supported files (*.afs, *.8bf, *.pff, *.prm, *.bin, *.txt; *.ffx)\0*.afs;*.8bf;*.pff;*.prm;*.bin;*.txt;*.ffx\0Filter Factory Settings (*.afs, *.txt)\0*.afs;*.txt\0Filter Factory for Windows, Standalone Filter (*.8bf)\0*.8bf\0Premiere TF/FF Settings (*.pff)\0*.pff\0Premiere TT/FF for Windows, Standalone Filter (*.prm)\0*.prm\0FilterFactory for MacOS, Standalone Filter (*.bin)\0*.bin\0\"Filters Unlimited\" filter (*.ffx)\0*.ffx\0All files (*.*)\0*.*\0\0" |
"All supported files (*.afs, *.8bf, *.pff, *.prm, *.bin, *.txt; *.ffx)\0*.afs;*.8bf;*.pff;*.prm;*.bin;*.txt;*.ffx\0Filter Factory Settings (*.afs, *.txt)\0*.afs;*.txt\0PluginCommander TXT file (*.txt)\0*.txt\0Filter Factory for Windows, Standalone Filter (*.8bf)\0*.8bf\0Premiere TF/FF Settings (*.pff)\0*.pff\0Premiere TT/FF for Windows, Standalone Filter (*.prm)\0*.prm\0FilterFactory for MacOS, Standalone Filter (*.bin)\0*.bin\0\"Filters Unlimited\" filter (*.ffx)\0*.ffx\0All files (*.*)\0*.*\0\0" |
#ifdef _WIN32 |
,gdata->hWndMainDlg |
#endif /* _WIN32 */ |
382,7 → 382,7 |
#endif |
(StringPtr)_strdup("\0"), |
TEXT_FILETYPE,SIG_SIMPLETEXT,&reply,&sfr, |
"afs","All supported files (.afs, .txt; *.pff)\0*.afs;*.txt;*.pff\0Filter Factory Settings (*.afs, *.txt)\0*.afs;*.txt\0Premiere TF/FF Settings (*.pff)\0*.pff\0All files (*.*)\0*.*\0\0",1 |
"afs","All supported files (.afs, .txt, *.pff)\0*.afs;*.txt;*.pff\0Filter Factory Settings (*.afs, *.txt)\0*.afs;*.txt\0Premiere TF/FF Settings (*.pff)\0*.pff\0All files (*.*)\0*.*\0\0",1 |
#ifdef _WIN32 |
,gdata->hWndMainDlg |
#endif /* _WIN32 */ |
/trunk/wpj/README.md |
---|
2,7 → 2,7 |
Building FilterFoundry with OpenWatcom |
====================================== |
Most recently tested with OpenWatcom 1.9 and Adobe Photoshop SDK 2022. |
Most recently tested with OpenWatcom 1.9 and Adobe Photoshop SDK 2021. |
Prerequisites |