/*
This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au
Copyright (C) 2018-2022 Daniel Marschall, ViaThinkSoft
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ff.h"
#include "file_compat.h"
#include "sprintf_tiny.h"
enum{ CHOPLINES = 63 };
OSErr putstr(Handle h,char *s);
OSErr putstr(Handle h,char *s){
Ptr p;
OSErr e;
size_t size, n;
if (!h) return nilHandleErr;
size = PIGETHANDLESIZE(h);
if(!(e = PISETHANDLESIZE(h,(int32)(size+n)))){
p = PILOCKHANDLE(h,false);
PIUNLOCKHANDLE(h);
}
return e;
}
OSErr saveparams_afs_pff(Handle h){
char outbuf[CHOPLINES*2+2],*q,*p,*r,*start;
size_t n, chunk, j;
int i;
OSErr e;
size_t est;
static char afs_sig[] = "%RGB-1.0\r";
if (!h) return nilHandleErr;
// do not be tempted to combine into one expression: 'est' is referenced below
est
+= strlen(afs_sig
) + est
/CHOPLINES
+ 4 + 8*6 + 64 /*slop*/ ;
PIUNLOCKHANDLE(h); // should not be necessary
if( !(e = PISETHANDLESIZE(h,(int32)(est))) && (p = start = PILOCKHANDLE(h,false)) ){
// build one long string in AFS format
p = cat(p,afs_sig); // first the header signature
/* then slider values, one per line */
for( i=0 ; i<8 ; ++i )
p
+= sprintf(p
, "%d\r", slider
[i
]);
/* expressions, broken into lines no longer than CHOPLINES characters */
for( i=0 ; i<4 ; ++i ){
if( (r = expr[i]) )
for( n
= strlen(r
) ; n
; n
-= chunk
){
chunk = n> (int)CHOPLINES ? (int)CHOPLINES : n;
for( j = chunk,q = outbuf ; j-- ; )
if(*r == CR){
*q++ = '\\';
*q++ = 'r';
++r;
}else if (*r == LF) {
// This can only happen with Windows or Linux.
// Native Linux is not supported, and Windows always combines LF with CR. So we can ignore LF.
++r;
}else
*q++ = *r++;
*q++ = CR;
*q = 0;
p = cat(p,outbuf);
}
else
p = cat(p,(char*)("(null expr)\r")); // this shouldn't happen
*p++ = CR;
}
// *p = 0; dbg(start);
PIUNLOCKHANDLE(h);
e = PISETHANDLESIZE(h,(int32)(p - start)); // could ignore this error, maybe
}
return e;
}
OSErr saveparams_picotxt(Handle h, Boolean useparm) {
extern int ctls[], maps[];
char * p, *start;
int i;
OSErr e;
size_t est;
if (!h) return nilHandleErr;
// do not be tempted to combine into one expression: 'est' is referenced below
est += 16000;
PIUNLOCKHANDLE(h); // should not be necessary
if (!(e = PISETHANDLESIZE(h, (int32)(est))) && (p = start = PILOCKHANDLE(h, false))) {
checksliders(4, ctls, maps);
// Metadata
p
+= sprintf(p
, "Category: %s\r\n", useparm
? gdata
->parm.
szCategory : "...");
p
+= sprintf(p
, "Title: %s\r\n", useparm
? gdata
->parm.
szTitle : "...");
p
+= sprintf(p
, "Copyright: %s\r\n", useparm
? gdata
->parm.
szCopyright : "...");
p
+= sprintf(p
, "Author: %s\r\n", useparm
? gdata
->parm.
szAuthor : "...");
p
+= sprintf(p
, "Filename: %s\r\n", useparm
? "Untitled.8bf" : "Untitled.8bf"); // TODO: get .txt filename and change .txt to .8bf
p
+= sprintf(p
, "R: %s\r\n", useparm
? gdata
->parm.
szFormula[0] : expr
[0]);
p
+= sprintf(p
, "G: %s\r\n", useparm
? gdata
->parm.
szFormula[1] : expr
[1]);
p
+= sprintf(p
, "B: %s\r\n", useparm
? gdata
->parm.
szFormula[2] : expr
[2]);
p
+= sprintf(p
, "A: %s\r\n", useparm
? gdata
->parm.
szFormula[3] : expr
[3]);
if (useparm) {
for (i = 0; i < 8; i++) {
if (gdata->parm.ctl_used[i]) {
p
+= sprintf(p
, "ctl[%d]: %s\r\n", i
, gdata
->parm.
szCtl[i
]);
}
}
for (i = 0; i < 4; i++) {
if (gdata->parm.map_used[i]) {
p
+= sprintf(p
, "map[%d]: %s\r\n", i
, gdata
->parm.
szMap[i
]);
}
}
for (i = 0; i < 8; i++) {
if (gdata->parm.ctl_used[i]) {
p
+= sprintf(p
, "val[%d]: %d\r\n", i
, gdata
->parm.
val[i
]);
}
}
/*
p += sprintf(p, "\r\n");
for (i = 0; i < 8; i++) {
if (gdata->parm.ctl_used[i]) {
p += sprintf(p, "def[%d]: %d\r\n", i, gdata->parm.val[i]);
}
}
*/
}
else {
for (i = 0; i < 8; i++) {
if (ctls[i]) {
p
+= sprintf(p
, "ctl[%d]: %s\r\n", i
, "...");
}
}
for (i = 0; i < 4; i++) {
if (maps[i]) {
p
+= sprintf(p
, "map[%d]: %s\r\n", i
, "...");
}
}
for (i = 0; i < 8; i++) {
if (ctls[i]) {
p
+= sprintf(p
, "val[%d]: %d\r\n", i
, slider
[i
]);
}
}
/*
p += sprintf(p, "\r\n");
for (i = 0; i < 8; i++) {
if (ctls[i]) {
p += sprintf(p, "def[%d]: %s\r\n", i, "...");
}
}
*/
}
PIUNLOCKHANDLE(h);
e = PISETHANDLESIZE(h, (int32)(p - start)); // could ignore this error, maybe
}
return e;
}
OSErr savehandleintofile(Handle h,FILEREF r){
Ptr p;
long n;
OSErr e;
if (!h) return nilHandleErr;
p = PILOCKHANDLE(h,false);
n = PIGETHANDLESIZE(h);
e = FSWrite(r,&n,p);
PIUNLOCKHANDLE(h);
return e;
}
Boolean savefile_afs_pff_picotxt(StandardFileReply *sfr){
FILEREF r;
Handle h;
Boolean res = false;
TCHAR* reasonstr = NULL;
FSpDelete(&sfr->sfFile);
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,false) || savehandleintofile(h, r));
PIDISPOSEHANDLE(h);
}
}
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;
tmp = expr[0];
expr[0] = expr[2];
expr[2] = tmp;
}
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));
PIDISPOSEHANDLE(h);
}
if (fileHasExtension(sfr, TEXT(".pff"))) {
// Swap back so that the other program stuff will work normally again
char* tmp;
tmp = expr[0];
expr[0] = expr[2];
expr[2] = tmp;
}
}
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);
}
if (reasonstr) FF_GetMsg_Free(reasonstr);
return res;
}