/trunk/CHANGELOG.md |
---|
3,8 → 3,8 |
## 1.7.0.22 [Work-In-Progress] |
- Simplified source code: |
* expressions, slider names, etc. are now loaded directly in the PARM resource). |
* Load-methods don't return boolean and a reason string. Instead they return 0 (success) or a error message ID otherwise. |
- As side effect: The slider positions will be preserved when a filter is made |
* Load-methods and Save-methods don't return boolean and a reason string. Instead they return 0 (success) or a error message ID otherwise. |
- The slider positions will be preserved when a filter is made |
## 1.7.0.21 [23-Nov-2023] |
- Read FFX file: Fixed buffer overflow when some strings (Title,Category,Author,Copyright,SliderNames) are too long |
/trunk/TODO.md |
---|
5,9 → 5,11 |
ToDo for the next release |
------------------------- |
None |
* VERY carefully test all the save-file and load-file procedures, because the code has been changed |
* FFX decoder: "<ffxname>__0001_<8bfname>.txt" filenames |
Known problems |
-------------- |
/trunk/ff.h |
---|
112,7 → 112,10 |
extern int tokpos,tokstart,varused[]; |
extern TCHAR *errstr; |
// FFLoadingResult = 0 : Success |
// FFLoadingResult > 0 : Error, message ID as described in language.h |
typedef int FFLoadingResult; |
typedef int FFSavingResult; |
//#define DEBUG |
146,10 → 149,10 |
FFLoadingResult readPARM(PARM_T* parm,Ptr h); |
// from save.c |
OSErr saveparams_afs_pff(Handle h); |
OSErr saveparams_afs_pff(Handle h, Boolean premiereOrder); |
OSErr saveparams_picotxt(Handle h); |
OSErr savehandleintofile(Handle h,FILEREF r); |
Boolean savefile_afs_pff_picotxt_guf(StandardFileReply *sfr); |
FFSavingResult savefile_afs_pff_picotxt_guf(StandardFileReply *sfr); |
// from make_*.c |
OSErr make_standalone(StandardFileReply *sfr); |
/trunk/language.h |
---|
23,7 → 23,10 |
// Attention: Please save this file as UTF-8 without BOM! |
// Also, if you extend this, please also extend language_win.rc and language_mac.r! |
// The ID numbers must be continuous, otherwise the MAC stringlist (*r) does not work |
// TODO: Name the constants MSGID_* and not MSG_*_ID |
#define MSG_PREMIERE_COMPAT_ID 1 |
#define MSG_PREMIERE_COMPAT_ENUS "This version of Filter Foundry is not compatible with Adobe Premiere!"; |
#define MSG_PREMIERE_COMPAT_DEDE "Diese Version von Filter Foundry ist mit Adobe Premiere nicht kompatibel!" |
76,9 → 79,9 |
#define MSG_EXPRESSION1024_FOUND_ENUS "Found an expression longer than 1024 characters." |
#define MSG_EXPRESSION1024_FOUND_DEDE "Es wurde eine Formel gefunden, die länger als 1024 Zeichen ist." |
#define MSG_EXPRESSION_OOM_ID 14 |
#define MSG_EXPRESSION_OOM_ENUS "Could not get memory for expression." |
#define MSG_EXPRESSION_OOM_DEDE "Kann nicht genügend Speicher für die Formel erhalten." |
#define MSG_OUT_OF_MEMORY_ID 14 |
#define MSG_OUT_OF_MEMORY_ENUS "Not enough free memory to continue." |
#define MSG_OUT_OF_MEMORY_DEDE "Nicht genügend Arbeitsspeicher zum Ausführen der Aktion." |
#define MSG_FILTERS_UNLIMITED_WARNING_ID 15 |
#define MSG_FILTERS_UNLIMITED_WARNING_ENUS "Attention! You are loading a ""Filters Unlimited"" file. Please note that Filter Foundry only implements the basic Filter Factory functions. Therefore, most ""Filters Unlimited"" filters won't work with Filter Foundry." |
269,14 → 272,25 |
#define MSG_OPEN_FFL_DEDE "Filter Bibliothek" |
#define MSG_FFL_CONVERTED_ID 62 |
#define MSG_FFL_CONVERTED_ENUS "FFL file converted to TXT files. You can now open these TXT files." |
#define MSG_FFL_CONVERTED_DEDE "FFL Datei wurde in TXT Dateien extrahiert. Sie können diese TXT Dateien nun öffnen." |
#define MSG_FFL_CONVERTED_ENUS "The FFL file was split to single TXT files. You can now open these TXT files." |
#define MSG_FFL_CONVERTED_DEDE "Die FFL Datei wurde in einzelne TXT Dateien aufgesplitet. Sie können diese TXT Dateien nun öffnen." |
// TODO: Give own IDs and Translate |
#define MSG_OUT_OF_MEMORY_ID 14 |
#define MSG_INVALID_FILE_SIGNATURE_ID 6 |
#define MSG_FFL_NO_FILTERS_DETECTED_ID 6 |
#define MSG_INVALID_FILE_SIGNATURE_ID 63 |
#define MSG_INVALID_FILE_SIGNATURE_ENUS "Invalid file signature" |
#define MSG_INVALID_FILE_SIGNATURE_DEDE "Ungültiger Dateianfang" |
#define MSG_FFL_NO_FILTERS_DETECTED_ID 64 |
#define MSG_FFL_NO_FILTERS_DETECTED_DEDE "In this FFL file there are no filters" |
#define MSG_FFL_NO_FILTERS_DETECTED_ENUS "In dieser FFL Datei befinden sich keine Filter" |
#define MSG_ERROR_GENERATING_DATA_ID 65 |
#define MSG_ERROR_GENERATING_DATA_ENUS "Error generating the file contents" |
#define MSG_ERROR_GENERATING_DATA_DEDE "Fehler beim Erstellen der Datei-Inhalte" |
#define MSG_UNSUPPORTED_FILE_FORMAT_ID 66 |
#define MSG_UNSUPPORTED_FILE_FORMAT_DEDE "Not supported file format. Please take care to choose a valid filename extension" |
#define MSG_UNSUPPORTED_FILE_FORMAT_ENUS "Nicht unterstütztes Dateiformat. Bitte achten Sie auf die korrekte Dateinamens-Erweiterung" |
void strcpy_advance_id(TCHAR** str, int msgid); |
int FF_GetMsg(TCHAR* ret, int MsgId); |
TCHAR* FF_GetMsg_Cpy(int MsgId); |
/trunk/language_mac.r |
---|
29,7 → 29,7 |
MSG_FILTER_PROTECTED_ENUS, |
MSG_LOADFILE_UNKNOWN_FORMAT_ENUS, |
MSG_INVALID_PARAMETER_DATA_ENUS, |
MSG_CANNOT_ZOOM_ENUS, |
MSG_OUT_OF_MEMORY_ENUS, |
MSG_CANNOT_ZOOM_MEMFULL_ENUS, |
MSG_BUILT32_ENUS, |
MSG_BUILT64_ENUS, |
100,6 → 100,10 |
MSG_SAVE_GUF_ENUS, |
MSG_INCOMPATIBLE_GUF_FILE_ENUS, |
MSG_OPEN_FFL_ENUS, |
MSG_FFL_CONVERTED_ENUS |
MSG_FFL_CONVERTED_ENUS, |
MSG_INVALID_FILE_SIGNATURE_ENUS, |
MSG_FFL_NO_FILTERS_DETECTED_ENUS, |
MSG_ERROR_GENERATING_DATA_ENUS, |
MSG_UNSUPPORTED_FILE_FORMAT_ENUS |
} |
} |
/trunk/language_win.rc |
---|
38,7 → 38,7 |
MSG_CANNOT_OPEN_FILE_ID, MSG_CANNOT_OPEN_FILE_ENUS |
MSG_CANNOT_CREATE_FILE_ID, MSG_CANNOT_CREATE_FILE_ENUS |
MSG_EXPRESSION1024_FOUND_ID, MSG_EXPRESSION1024_FOUND_ENUS |
MSG_EXPRESSION_OOM_ID, MSG_EXPRESSION_OOM_ENUS |
MSG_OUT_OF_MEMORY_ID, MSG_OUT_OF_MEMORY_ENUS |
MSG_FILTERS_UNLIMITED_WARNING_ID, MSG_FILTERS_UNLIMITED_WARNING_ENUS |
MSG_FORMULA_IR_1023_TRUNCATED_ID, MSG_FORMULA_IR_1023_TRUNCATED_ENUS |
MSG_FORMULA_R_1023_TRUNCATED_ID, MSG_FORMULA_R_1023_TRUNCATED_ENUS |
87,7 → 87,12 |
MSG_INCOMPATIBLE_GUF_FILE_ID, MSG_INCOMPATIBLE_GUF_FILE_ENUS |
MSG_OPEN_FFL_ID, MSG_OPEN_FFL_ENUS |
MSG_FFL_CONVERTED_ID, MSG_FFL_CONVERTED_ENUS |
MSG_INVALID_FILE_SIGNATURE_ID, MSG_INVALID_FILE_SIGNATURE_ENUS |
MSG_FFL_NO_FILTERS_DETECTED_ID, MSG_FFL_NO_FILTERS_DETECTED_ENUS |
MSG_ERROR_GENERATING_DATA_ID, MSG_ERROR_GENERATING_DATA_ENUS |
MSG_UNSUPPORTED_FILE_FORMAT_ID, MSG_UNSUPPORTED_FILE_FORMAT_ENUS |
} |
LANGUAGE LANG_GERMAN, SUBLANG_GERMAN |
108,7 → 113,7 |
MSG_CANNOT_OPEN_FILE_ID, MSG_CANNOT_OPEN_FILE_DEDE |
MSG_CANNOT_CREATE_FILE_ID, MSG_CANNOT_CREATE_FILE_DEDE |
MSG_EXPRESSION1024_FOUND_ID, MSG_EXPRESSION1024_FOUND_DEDE |
MSG_EXPRESSION_OOM_ID, MSG_EXPRESSION_OOM_DEDE |
MSG_OUT_OF_MEMORY_ID, MSG_OUT_OF_MEMORY_DEDE |
MSG_FILTERS_UNLIMITED_WARNING_ID, MSG_FILTERS_UNLIMITED_WARNING_DEDE |
MSG_FORMULA_IR_1023_TRUNCATED_ID, MSG_FORMULA_IR_1023_TRUNCATED_DEDE |
MSG_FORMULA_R_1023_TRUNCATED_ID, MSG_FORMULA_R_1023_TRUNCATED_DEDE |
157,5 → 162,9 |
MSG_INCOMPATIBLE_GUF_FILE_ID, MSG_INCOMPATIBLE_GUF_FILE_DEDE |
MSG_OPEN_FFL_ID, MSG_OPEN_FFL_DEDE |
MSG_FFL_CONVERTED_ID, MSG_FFL_CONVERTED_DEDE |
MSG_INVALID_FILE_SIGNATURE_ID, MSG_INVALID_FILE_SIGNATURE_DEDE |
MSG_FFL_NO_FILTERS_DETECTED_ID, MSG_FFL_NO_FILTERS_DETECTED_DEDE |
MSG_ERROR_GENERATING_DATA_ID, MSG_ERROR_GENERATING_DATA_DEDE |
MSG_UNSUPPORTED_FILE_FORMAT_ID, MSG_UNSUPPORTED_FILE_FORMAT_DEDE |
} |
/trunk/main.c |
---|
394,6 → 394,7 |
TCHAR outfilename[MAX_PATH + 1]; |
StandardFileReply sfr; |
InternalState tmpState; |
FFSavingResult saveres; |
sfr.sfGood = true; |
sfr.sfReplacing = true; |
415,16 → 416,23 |
parm_reset(false, false, false, true); |
} |
savefile_afs_pff_picotxt_guf(&sfr); |
saveres = savefile_afs_pff_picotxt_guf(&sfr); |
if (gdata->parm.standalone) { |
restoreInternalState(tmpState); |
} |
if (saveres != 0) { |
TCHAR* reason = FF_GetMsg_Cpy(saveres); |
alertuser_id(MSG_CANNOT_SAVE_SETTINGS_ID, reason); |
FF_GetMsg_Free(reason); |
*result = filterBadParameters; |
} |
} |
else { |
/* update stored parameters from new user settings */ |
if (pb->parameters) |
saveparams_afs_pff(pb->parameters); |
saveparams_afs_pff(pb->parameters, false); |
} |
} |
else |
649,7 → 657,7 |
break; |
} |
if (params) saveparams_afs_pff(params); |
if (params) saveparams_afs_pff(params, false); |
return showdialog; |
} |
/trunk/read.c |
---|
1081,7 → 1081,7 |
est = 16000; |
FSpDelete(&sfrTmp.sfFile); |
if (FSpCreate(&sfrTmp.sfFile, SIG_SIMPLETEXT, TEXT_FILETYPE, sfr->sfScript) == noErr) |
if (FSpCreate(&sfrTmp.sfFile, SIG_SIMPLETEXT, TEXT_FILETYPE, sfr->sfScript) == noErr) { |
if (FSpOpenDF(&sfrTmp.sfFile, fsWrPerm, &rTmp) == noErr) { |
if ((hTmp = PINEWHANDLE(1))) { // don't set initial size to 0, since some hosts (e.g. GIMP/PSPI) are incompatible with that. |
PIUNLOCKHANDLE(hTmp); // should not be necessary |
1134,8 → 1134,12 |
savehandleintofile(hTmp, rTmp); |
PIDISPOSEHANDLE(hTmp); |
} |
else res = MSG_OUT_OF_MEMORY_ID; |
FSClose(rTmp); |
} |
else res = MSG_CANNOT_OPEN_FILE_ID; |
} |
else res = MSG_CANNOT_CREATE_FILE_ID; |
free(curFileNameOrig); |
for (i = 0; i < 29; i++) { |
/trunk/save.c |
---|
47,11 → 47,11 |
return e; |
} |
OSErr saveparams_afs_pff(Handle h){ |
OSErr saveparams_afs_pff(Handle h, Boolean premiereOrder){ |
char outbuf[CHOPLINES * 2 + 2] = ""; |
char *q, * p, * r, * start; |
size_t n, chunk, j; |
int i; |
int i, k; |
OSErr e; |
size_t est; |
static char afs_sig[] = "%RGB-1.0\r"; |
72,7 → 72,13 |
p += sprintf(p, "%d\r", gdata->parm.val[i]); |
/* expressions, broken into lines no longer than CHOPLINES characters */ |
for( i=0 ; i<4 ; ++i ){ |
for( k=0 ; k<4 ; ++k ){ |
i = k; |
if (premiereOrder) { |
// Premiere has the order BGRA, while Photoshop (and our internal order) is RGBA |
if (k == 0) i = 2; |
else if (k == 2) i = 0; |
} |
if ((r = gdata->parm.szFormula[i])) { |
chunk = 0; // to avoid that compiler complains |
for (n = strlen(r); n; n -= chunk) { |
263,65 → 269,51 |
return e; |
} |
Boolean savefile_afs_pff_picotxt_guf(StandardFileReply *sfr){ |
FFSavingResult savefile_afs_pff_picotxt_guf(StandardFileReply *sfr){ |
FILEREF r; |
Handle h; |
Boolean res = false; |
TCHAR* reasonstr = NULL; |
Boolean bres = false; |
FFSavingResult res = 0; |
FSpDelete(&sfr->sfFile); |
if(FSpCreate(&sfr->sfFile,SIG_SIMPLETEXT,TEXT_FILETYPE,sfr->sfScript) == noErr) |
if (FSpCreate(&sfr->sfFile, SIG_SIMPLETEXT, TEXT_FILETYPE, sfr->sfScript) == noErr) { |
if(FSpOpenDF(&sfr->sfFile,fsWrPerm,&r) == noErr){ |
if (fileHasExtension(sfr, TEXT(".txt"))) { |
// PluginCommander .txt |
if ((h = PINEWHANDLE(1))) { // don't set initial size to 0, since some hosts (e.g. GIMP/PSPI) are incompatible with that. |
res = !(saveparams_picotxt(h) || savehandleintofile(h, r)); |
bres = !(saveparams_picotxt(h) || savehandleintofile(h, r)); |
if (!bres) res = MSG_ERROR_GENERATING_DATA_ID; |
PIDISPOSEHANDLE(h); |
} |
else res = MSG_OUT_OF_MEMORY_ID; |
} |
if (fileHasExtension(sfr, TEXT(".guf"))) { |
else if (fileHasExtension(sfr, TEXT(".guf"))) { |
// GIMP UserFilter file |
if ((h = PINEWHANDLE(1))) { // don't set initial size to 0, since some hosts (e.g. GIMP/PSPI) are incompatible with that. |
res = !(saveparams_guf(h) || savehandleintofile(h, r)); |
bres = !(saveparams_guf(h) || savehandleintofile(h, r)); |
if (!bres) res = MSG_ERROR_GENERATING_DATA_ID; |
PIDISPOSEHANDLE(h); |
} |
else res = MSG_OUT_OF_MEMORY_ID; |
} |
if ((fileHasExtension(sfr, TEXT(".afs"))) || (fileHasExtension(sfr, TEXT(".pff")))) { |
if (fileHasExtension(sfr, TEXT(".pff"))) { |
// If it is a Premiere settings file, we need to swap the channels red and blue |
// We just swap the pointers! |
char tmp[MAXEXPR]; |
strcpy(tmp, gdata->parm.szFormula[0]); |
strcpy(gdata->parm.szFormula[0], gdata->parm.szFormula[2]); |
strcpy(gdata->parm.szFormula[2], tmp); |
} |
else if ((fileHasExtension(sfr, TEXT(".afs"))) || (fileHasExtension(sfr, TEXT(".pff")))) { |
if ((h = PINEWHANDLE(1))) { // don't set initial size to 0, since some hosts (e.g. GIMP/PSPI) are incompatible with that. |
res = !(saveparams_afs_pff(h) || savehandleintofile(h, r)); |
bres = !(saveparams_afs_pff(h, fileHasExtension(sfr, TEXT(".pff"))) || savehandleintofile(h, r)); |
if (!bres) res = MSG_ERROR_GENERATING_DATA_ID; |
PIDISPOSEHANDLE(h); |
} |
if (fileHasExtension(sfr, TEXT(".pff"))) { |
// Swap back so that the other program stuff will work normally again |
char tmp[MAXEXPR]; |
strcpy(tmp, gdata->parm.szFormula[0]); |
strcpy(gdata->parm.szFormula[0], gdata->parm.szFormula[2]); |
strcpy(gdata->parm.szFormula[2], tmp); |
else res = MSG_OUT_OF_MEMORY_ID; |
} |
else { |
res = MSG_UNSUPPORTED_FILE_FORMAT_ID; |
} |
FSClose(r); |
}else reasonstr = FF_GetMsg_Cpy(MSG_CANNOT_OPEN_FILE_ID); |
else reasonstr = FF_GetMsg_Cpy(MSG_CANNOT_CREATE_FILE_ID); |
if (!res) { |
alertuser_id(MSG_CANNOT_SAVE_SETTINGS_ID, reasonstr); |
} |
else res = MSG_CANNOT_OPEN_FILE_ID; |
} |
else res = MSG_CANNOT_CREATE_FILE_ID; |
if (reasonstr) FF_GetMsg_Free(reasonstr); |
return res; |
} |
/trunk/ui.c |
---|
499,7 → 499,13 |
free(title); |
if (saveDlgRet) { |
if (savefile_afs_pff_picotxt_guf(&sfr)) { |
FFSavingResult saveres = savefile_afs_pff_picotxt_guf(&sfr); |
if (saveres != 0) { |
TCHAR* reason = FF_GetMsg_Cpy(saveres); |
alertuser_id(MSG_CANNOT_SAVE_SETTINGS_ID, reason); |
FF_GetMsg_Free(reason); |
} |
else { |
completesave(&reply); |
if (fileHasExtension(&sfr, TEXT(".txt"))) { |