Subversion Repositories filter_foundry

Rev

Rev 541 | Rev 555 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
259 daniel-mar 1
/*
2
    This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
536 daniel-mar 3
    Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.net
541 daniel-mar 4
    Copyright (C) 2018-2023 Daniel Marschall, ViaThinkSoft
259 daniel-mar 5
 
6
    This program is free software; you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation; either version 2 of the License, or
9
    (at your option) any later version.
10
 
11
    This program is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with this program; if not, write to the Free Software
18
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
*/
20
 
21
#include "ff.h"
22
 
539 daniel-mar 23
#include "version.h"
24
#include "time.h"
259 daniel-mar 25
#include "file_compat.h"
26
#include "sprintf_tiny.h"
27
 
518 daniel-mar 28
#define CHOPLINES 63
259 daniel-mar 29
 
30
OSErr putstr(Handle h,char *s);
31
 
32
OSErr putstr(Handle h,char *s){
33
        Ptr p;
34
        OSErr e;
482 daniel-mar 35
        size_t size, n;
259 daniel-mar 36
 
482 daniel-mar 37
        if (!h) return nilHandleErr;
38
 
39
        size = PIGETHANDLESIZE(h);
40
        n = strlen(s);
41
 
259 daniel-mar 42
        if(!(e = PISETHANDLESIZE(h,(int32)(size+n)))){
43
                p = PILOCKHANDLE(h,false);
44
                memcpy(p+size,s,n);
45
                PIUNLOCKHANDLE(h);
46
        }
47
        return e;
48
}
49
 
389 daniel-mar 50
OSErr saveparams_afs_pff(Handle h){
505 daniel-mar 51
        char outbuf[CHOPLINES * 2 + 2] = "";
52
        char *q, * p, * r, * start;
259 daniel-mar 53
        size_t n, chunk, j;
54
        int i;
55
        OSErr e;
56
        size_t est;
57
        static char afs_sig[] = "%RGB-1.0\r";
58
 
482 daniel-mar 59
        if (!h) return nilHandleErr;
259 daniel-mar 60
 
550 daniel-mar 61
        est = strlen(gdata->parm.szFormula[0]) + strlen(gdata->parm.szFormula[1]) + strlen(gdata->parm.szFormula[2]) + strlen(gdata->parm.szFormula[3]);
259 daniel-mar 62
        // do not be tempted to combine into one expression: 'est' is referenced below
63
        est += strlen(afs_sig) + est/CHOPLINES + 4 + 8*6 + 64 /*slop*/ ;
64
 
65
        PIUNLOCKHANDLE(h); // should not be necessary
66
        if( !(e = PISETHANDLESIZE(h,(int32)(est))) && (p = start = PILOCKHANDLE(h,false)) ){
67
                // build one long string in AFS format
68
                p = cat(p,afs_sig); // first the header signature
69
 
70
                /* then slider values, one per line */
71
                for( i=0 ; i<8 ; ++i )
550 daniel-mar 72
                        p += sprintf(p, "%d\r", gdata->parm.val[i]);
259 daniel-mar 73
 
74
                /* expressions, broken into lines no longer than CHOPLINES characters */
75
                for( i=0 ; i<4 ; ++i ){
550 daniel-mar 76
                        if ((r = gdata->parm.szFormula[i])) {
505 daniel-mar 77
                                chunk = 0; // to avoid that compiler complains
78
                                for (n = strlen(r); n; n -= chunk) {
79
                                        chunk = n > (int)CHOPLINES ? (int)CHOPLINES : n;
80
                                        for (j = chunk, q = outbuf; j--; )
81
                                                if (*r == CR) {
259 daniel-mar 82
                                                        *q++ = '\\';
83
                                                        *q++ = 'r';
84
                                                        ++r;
505 daniel-mar 85
                                                }
86
                                                else if (*r == LF) {
393 daniel-mar 87
 
259 daniel-mar 88
                                                        // This can only happen with Windows or Linux.
369 daniel-mar 89
                                                        // Native Linux is not supported, and Windows always combines LF with CR. So we can ignore LF.
259 daniel-mar 90
                                                        ++r;
505 daniel-mar 91
                                                }
92
                                                else
259 daniel-mar 93
                                                        *q++ = *r++;
387 daniel-mar 94
                                        *q++ = CR;
259 daniel-mar 95
                                        *q = 0;
505 daniel-mar 96
                                        p = cat(p, outbuf);
259 daniel-mar 97
                                }
505 daniel-mar 98
                        }
259 daniel-mar 99
                        else
498 daniel-mar 100
                                p = cat(p,(char*)("(null expr)\r")); // this shouldn't happen
387 daniel-mar 101
                        *p++ = CR;
259 daniel-mar 102
                }
103
 
104
//              *p = 0; dbg(start);
105
 
106
                PIUNLOCKHANDLE(h);
107
                e = PISETHANDLESIZE(h,(int32)(p - start)); // could ignore this error, maybe
108
        }
109
 
110
        return e;
111
}
112
 
550 daniel-mar 113
OSErr saveparams_picotxt(Handle h) {
389 daniel-mar 114
        char * p, *start;
115
        int i;
116
        OSErr e;
117
        size_t est;
118
 
482 daniel-mar 119
        if (!h) return nilHandleErr;
389 daniel-mar 120
 
550 daniel-mar 121
        est = strlen(gdata->parm.szFormula[0]) + strlen(gdata->parm.szFormula[1]) + strlen(gdata->parm.szFormula[2]) + strlen(gdata->parm.szFormula[3]);
389 daniel-mar 122
        // do not be tempted to combine into one expression: 'est' is referenced below
123
        est += 16000;
124
 
125
        PIUNLOCKHANDLE(h); // should not be necessary
126
        if (!(e = PISETHANDLESIZE(h, (int32)(est))) && (p = start = PILOCKHANDLE(h, false))) {
550 daniel-mar 127
                checksliders(4);
389 daniel-mar 128
 
129
                // Metadata
550 daniel-mar 130
                p += sprintf(p, "Category: %s\r\n", gdata->parm.szCategory);
131
                p += sprintf(p, "Title: %s\r\n", gdata->parm.szTitle);
132
                p += sprintf(p, "Copyright: %s\r\n", gdata->parm.szCopyright);
133
                p += sprintf(p, "Author: %s\r\n", gdata->parm.szAuthor);
134
                p += sprintf(p, "Filename: %s\r\n", "Untitled.8bf"); // TODO: get .txt filename and change .txt to .8bf
389 daniel-mar 135
                p += sprintf(p, "\r\n");
550 daniel-mar 136
                p += sprintf(p, "R: %s\r\n", gdata->parm.szFormula[0]);
389 daniel-mar 137
                p += sprintf(p, "\r\n");
550 daniel-mar 138
                p += sprintf(p, "G: %s\r\n", gdata->parm.szFormula[1]);
389 daniel-mar 139
                p += sprintf(p, "\r\n");
550 daniel-mar 140
                p += sprintf(p, "B: %s\r\n", gdata->parm.szFormula[2]);
389 daniel-mar 141
                p += sprintf(p, "\r\n");
550 daniel-mar 142
                p += sprintf(p, "A: %s\r\n", gdata->parm.szFormula[3]);
389 daniel-mar 143
                p += sprintf(p, "\r\n");
550 daniel-mar 144
                for (i = 0; i < 8; i++) {
145
                        if (gdata->parm.ctl_used[i]) {
146
                                p += sprintf(p, "ctl[%d]: %s\r\n", i, gdata->parm.szCtl[i]);
389 daniel-mar 147
                        }
550 daniel-mar 148
                }
149
                for (i = 0; i < 4; i++) {
150
                        if (gdata->parm.map_used[i]) {
151
                                p += sprintf(p, "map[%d]: %s\r\n", i, gdata->parm.szMap[i]);
389 daniel-mar 152
                        }
550 daniel-mar 153
                }
154
                p += sprintf(p, "\r\n");
155
                for (i = 0; i < 8; i++) {
156
                        if (gdata->parm.ctl_used[i]) {
157
                                p += sprintf(p, "val[%d]: %d\r\n", i, gdata->parm.val[i]);
389 daniel-mar 158
                        }
159
                }
550 daniel-mar 160
                /*
161
                p += sprintf(p, "\r\n");
162
                for (i = 0; i < 8; i++) {
163
                        if (gdata->parm.ctl_used[i]) {
164
                                p += sprintf(p, "def[%d]: %d\r\n", i, gdata->parm.val[i]);
389 daniel-mar 165
                        }
166
                }
550 daniel-mar 167
                */
389 daniel-mar 168
 
169
                PIUNLOCKHANDLE(h);
170
                e = PISETHANDLESIZE(h, (int32)(p - start)); // could ignore this error, maybe
171
        }
172
 
173
        return e;
174
}
175
 
550 daniel-mar 176
OSErr saveparams_guf(Handle h) {
539 daniel-mar 177
        char* p, * start;
178
        int i;
179
        OSErr e;
180
        size_t est;
181
 
182
        if (!h) return nilHandleErr;
183
 
550 daniel-mar 184
        est = strlen(gdata->parm.szFormula[0]) + strlen(gdata->parm.szFormula[1]) + strlen(gdata->parm.szFormula[2]) + strlen(gdata->parm.szFormula[3]);
539 daniel-mar 185
        // do not be tempted to combine into one expression: 'est' is referenced below
186
        est += 16000;
187
 
188
        // TODO: Encode the file in UTF-8! (German Umlauts, etc.)
189
 
190
        PIUNLOCKHANDLE(h); // should not be necessary
191
        if (!(e = PISETHANDLESIZE(h, (int32)(est))) && (p = start = PILOCKHANDLE(h, false))) {
192
                char strBuildDate[11/*strlen("0000-00-00") + 1*/];
193
                time_t iBuildDate = time(0);
541 daniel-mar 194
                strftime(strBuildDate, 11, "%Y-%m-%d", localtime(&iBuildDate));
539 daniel-mar 195
 
550 daniel-mar 196
                checksliders(4);
539 daniel-mar 197
 
198
                // Metadata
199
                p += sprintf(p, "# Created with Filter Foundry %s\r\n", VERSION_STR);
200
                p += sprintf(p, "\r\n");
201
                p += sprintf(p, "[GUF]\r\n");
202
                p += sprintf(p, "Protocol=1\r\n");
203
                p += sprintf(p, "\r\n");
204
                p += sprintf(p, "[Info]\r\n");
550 daniel-mar 205
                p += sprintf(p, "Category=<Image>/Filter Factory/%s\r\n", gdata->parm.szCategory);
206
                p += sprintf(p, "Title=%s\r\n", gdata->parm.szTitle);
207
                p += sprintf(p, "Copyright=%s\r\n", gdata->parm.szCopyright);
208
                p += sprintf(p, "Author=%s\r\n", gdata->parm.szAuthor);
539 daniel-mar 209
                p += sprintf(p, "\r\n");
210
                p += sprintf(p, "[Version]\r\n");
211
                p += sprintf(p, "Major=1\r\n");
212
                p += sprintf(p, "Minor=0\r\n");
213
                p += sprintf(p, "Micro=0\r\n");
214
                p += sprintf(p, "\r\n");
215
                p += sprintf(p, "[Filter Factory]\r\n");
550 daniel-mar 216
                p += sprintf(p, "8bf=%s\r\n", "Untitled.8bf"); // TODO: get .guf filename and change .guf to .8bf
539 daniel-mar 217
                p += sprintf(p, "\r\n");
218
                p += sprintf(p, "[Gimp]\r\n");
219
                p += sprintf(p, "Registered=false\r\n");
550 daniel-mar 220
                p += sprintf(p, "Description=%s\r\n", gdata->parm.szTitle);
539 daniel-mar 221
                p += sprintf(p, "EdgeMode=2\r\n");
222
                p += sprintf(p, "Date=%s\r\n", strBuildDate);
223
                p += sprintf(p, "\r\n");
224
 
550 daniel-mar 225
                for (i = 0; i < 8; i++) {
226
                        p += sprintf(p, "[Control %d]\r\n", i);
227
                        p += sprintf(p, "Enabled=%s\r\n", gdata->parm.ctl_used[i] ? "true" : "false");
228
                        p += sprintf(p, "Label=%s\r\n", gdata->parm.szCtl[i]);
229
                        p += sprintf(p, "Preset=%d\r\n", gdata->parm.val[i]);
230
                        p += sprintf(p, "Step=1\r\n");
231
                        p += sprintf(p, "\r\n");
539 daniel-mar 232
                }
550 daniel-mar 233
                for (i = 0; i < 4; i++) {
234
                        p += sprintf(p, "[Map %d]\r\n", i);
235
                        p += sprintf(p, "Enabled=%s\r\n", gdata->parm.map_used[i] ? "true" : "false");
236
                        p += sprintf(p, "Label=%s\r\n", gdata->parm.szMap[i]);
237
                        p += sprintf(p, "\r\n");
539 daniel-mar 238
                }
239
 
240
                p += sprintf(p, "[Code]\r\n");
550 daniel-mar 241
                p += sprintf(p, "R=%s\r\n", gdata->parm.szFormula[0]);
242
                p += sprintf(p, "G=%s\r\n", gdata->parm.szFormula[1]);
243
                p += sprintf(p, "B=%s\r\n", gdata->parm.szFormula[2]);
244
                p += sprintf(p, "A=%s\r\n", gdata->parm.szFormula[3]);
539 daniel-mar 245
 
246
                PIUNLOCKHANDLE(h);
247
                e = PISETHANDLESIZE(h, (int32)(p - start)); // could ignore this error, maybe
248
        }
249
 
250
        return e;
537 daniel-mar 251
}
252
 
259 daniel-mar 253
OSErr savehandleintofile(Handle h,FILEREF r){
482 daniel-mar 254
        Ptr p;
505 daniel-mar 255
        FILECOUNT n;
482 daniel-mar 256
        OSErr e;
257
 
258
        if (!h) return nilHandleErr;
259
        p = PILOCKHANDLE(h,false);
505 daniel-mar 260
        n = (FILECOUNT)PIGETHANDLESIZE(h);
482 daniel-mar 261
        e = FSWrite(r,&n,p);
259 daniel-mar 262
        PIUNLOCKHANDLE(h);
263
        return e;
264
}
265
 
537 daniel-mar 266
Boolean savefile_afs_pff_picotxt_guf(StandardFileReply *sfr){
259 daniel-mar 267
        FILEREF r;
268
        Handle h;
269
        Boolean res = false;
498 daniel-mar 270
        TCHAR* reasonstr = NULL;
259 daniel-mar 271
 
272
        FSpDelete(&sfr->sfFile);
273
        if(FSpCreate(&sfr->sfFile,SIG_SIMPLETEXT,TEXT_FILETYPE,sfr->sfScript) == noErr)
274
                if(FSpOpenDF(&sfr->sfFile,fsWrPerm,&r) == noErr){
275
 
444 daniel-mar 276
                        if (fileHasExtension(sfr, TEXT(".txt"))) {
389 daniel-mar 277
                                // PluginCommander .txt
278
                                if ((h = PINEWHANDLE(1))) { // don't set initial size to 0, since some hosts (e.g. GIMP/PSPI) are incompatible with that.
550 daniel-mar 279
                                        res = !(saveparams_picotxt(h) || savehandleintofile(h, r));
389 daniel-mar 280
                                        PIDISPOSEHANDLE(h);
281
                                }
369 daniel-mar 282
                        }
283
 
537 daniel-mar 284
                        if (fileHasExtension(sfr, TEXT(".guf"))) {
285
                                // GIMP UserFilter file
286
                                if ((h = PINEWHANDLE(1))) { // don't set initial size to 0, since some hosts (e.g. GIMP/PSPI) are incompatible with that.
550 daniel-mar 287
                                        res = !(saveparams_guf(h) || savehandleintofile(h, r));
537 daniel-mar 288
                                        PIDISPOSEHANDLE(h);
289
                                }
290
                        }
291
 
444 daniel-mar 292
                        if ((fileHasExtension(sfr, TEXT(".afs"))) || (fileHasExtension(sfr, TEXT(".pff")))) {
293
                                if (fileHasExtension(sfr, TEXT(".pff"))) {
389 daniel-mar 294
                                        // If it is a Premiere settings file, we need to swap the channels red and blue
295
                                        // We just swap the pointers!
550 daniel-mar 296
                                        char tmp[MAXEXPR];
297
                                        strcpy(tmp, gdata->parm.szFormula[0]);
298
                                        strcpy(gdata->parm.szFormula[0], gdata->parm.szFormula[2]);
299
                                        strcpy(gdata->parm.szFormula[2], tmp);
389 daniel-mar 300
                                }
259 daniel-mar 301
 
389 daniel-mar 302
                                if ((h = PINEWHANDLE(1))) { // don't set initial size to 0, since some hosts (e.g. GIMP/PSPI) are incompatible with that.
303
                                        res = !(saveparams_afs_pff(h) || savehandleintofile(h, r));
304
                                        PIDISPOSEHANDLE(h);
305
                                }
306
 
444 daniel-mar 307
                                if (fileHasExtension(sfr, TEXT(".pff"))) {
389 daniel-mar 308
                                        // Swap back so that the other program stuff will work normally again
550 daniel-mar 309
                                        char tmp[MAXEXPR];
310
                                        strcpy(tmp, gdata->parm.szFormula[0]);
311
                                        strcpy(gdata->parm.szFormula[0], gdata->parm.szFormula[2]);
312
                                        strcpy(gdata->parm.szFormula[2], tmp);
389 daniel-mar 313
                                }
369 daniel-mar 314
                        }
315
 
259 daniel-mar 316
                        FSClose(r);
498 daniel-mar 317
                }else reasonstr = FF_GetMsg_Cpy(MSG_CANNOT_OPEN_FILE_ID);
318
        else reasonstr = FF_GetMsg_Cpy(MSG_CANNOT_CREATE_FILE_ID);
259 daniel-mar 319
 
444 daniel-mar 320
        if (!res) {
492 daniel-mar 321
                alertuser_id(MSG_CANNOT_SAVE_SETTINGS_ID, reasonstr);
444 daniel-mar 322
        }
259 daniel-mar 323
 
498 daniel-mar 324
        if (reasonstr) FF_GetMsg_Free(reasonstr);
325
 
259 daniel-mar 326
        return res;
327
}