Subversion Repositories filter_foundry

Rev

Rev 537 | Rev 541 | 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
503 daniel-mar 4
    Copyright (C) 2018-2022 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
 
61
        est = strlen(expr[0]) + strlen(expr[1]) + strlen(expr[2]) + strlen(expr[3]);
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 )
301 daniel-mar 72
                        p += sprintf(p, "%d\r", slider[i]);
259 daniel-mar 73
 
74
                /* expressions, broken into lines no longer than CHOPLINES characters */
75
                for( i=0 ; i<4 ; ++i ){
505 daniel-mar 76
                        if ((r = expr[i])) {
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
 
389 daniel-mar 113
OSErr saveparams_picotxt(Handle h, Boolean useparm) {
114
        extern int ctls[], maps[];
115
 
116
        char * p, *start;
117
        int i;
118
        OSErr e;
119
        size_t est;
120
 
482 daniel-mar 121
        if (!h) return nilHandleErr;
389 daniel-mar 122
 
123
        est = strlen(expr[0]) + strlen(expr[1]) + strlen(expr[2]) + strlen(expr[3]);
124
        // do not be tempted to combine into one expression: 'est' is referenced below
125
        est += 16000;
126
 
127
        PIUNLOCKHANDLE(h); // should not be necessary
128
        if (!(e = PISETHANDLESIZE(h, (int32)(est))) && (p = start = PILOCKHANDLE(h, false))) {
129
                checksliders(4, ctls, maps);
130
 
131
                // Metadata
393 daniel-mar 132
                p += sprintf(p, "Category: %s\r\n", useparm ? gdata->parm.szCategory : "...");
133
                p += sprintf(p, "Title: %s\r\n", useparm ? gdata->parm.szTitle : "...");
134
                p += sprintf(p, "Copyright: %s\r\n", useparm ? gdata->parm.szCopyright : "...");
135
                p += sprintf(p, "Author: %s\r\n", useparm ? gdata->parm.szAuthor : "...");
389 daniel-mar 136
                p += sprintf(p, "Filename: %s\r\n", useparm ? "Untitled.8bf" : "Untitled.8bf"); // TODO: get .txt filename and change .txt to .8bf
137
                p += sprintf(p, "\r\n");
393 daniel-mar 138
                p += sprintf(p, "R: %s\r\n", useparm ? gdata->parm.szFormula[0] : expr[0]);
389 daniel-mar 139
                p += sprintf(p, "\r\n");
393 daniel-mar 140
                p += sprintf(p, "G: %s\r\n", useparm ? gdata->parm.szFormula[1] : expr[1]);
389 daniel-mar 141
                p += sprintf(p, "\r\n");
393 daniel-mar 142
                p += sprintf(p, "B: %s\r\n", useparm ? gdata->parm.szFormula[2] : expr[2]);
389 daniel-mar 143
                p += sprintf(p, "\r\n");
393 daniel-mar 144
                p += sprintf(p, "A: %s\r\n", useparm ? gdata->parm.szFormula[3] : expr[3]);
389 daniel-mar 145
                p += sprintf(p, "\r\n");
146
                if (useparm) {
147
                        for (i = 0; i < 8; i++) {
148
                                if (gdata->parm.ctl_used[i]) {
393 daniel-mar 149
                                        p += sprintf(p, "ctl[%d]: %s\r\n", i, gdata->parm.szCtl[i]);
389 daniel-mar 150
                                }
151
                        }
152
                        for (i = 0; i < 4; i++) {
153
                                if (gdata->parm.map_used[i]) {
393 daniel-mar 154
                                        p += sprintf(p, "map[%d]: %s\r\n", i, gdata->parm.szMap[i]);
389 daniel-mar 155
                                }
156
                        }
157
                        p += sprintf(p, "\r\n");
158
                        for (i = 0; i < 8; i++) {
159
                                if (gdata->parm.ctl_used[i]) {
160
                                        p += sprintf(p, "val[%d]: %d\r\n", i, gdata->parm.val[i]);
161
                                }
162
                        }
163
                        /*
164
                        p += sprintf(p, "\r\n");
165
                        for (i = 0; i < 8; i++) {
166
                                if (gdata->parm.ctl_used[i]) {
167
                                        p += sprintf(p, "def[%d]: %d\r\n", i, gdata->parm.val[i]);
168
                                }
169
                        }
170
                        */
171
                }
172
                else {
173
                        for (i = 0; i < 8; i++) {
174
                                if (ctls[i]) {
175
                                        p += sprintf(p, "ctl[%d]: %s\r\n", i, "...");
176
                                }
177
                        }
178
                        for (i = 0; i < 4; i++) {
179
                                if (maps[i]) {
180
                                        p += sprintf(p, "map[%d]: %s\r\n", i, "...");
181
                                }
182
                        }
183
                        p += sprintf(p, "\r\n");
184
                        for (i = 0; i < 8; i++) {
185
                                if (ctls[i]) {
186
                                        p += sprintf(p, "val[%d]: %d\r\n", i, slider[i]);
187
                                }
188
                        }
189
                        /*
190
                        p += sprintf(p, "\r\n");
191
                        for (i = 0; i < 8; i++) {
192
                                if (ctls[i]) {
193
                                        p += sprintf(p, "def[%d]: %s\r\n", i, "...");
194
                                }
195
                        }
196
                        */
197
                }
198
 
199
                PIUNLOCKHANDLE(h);
200
                e = PISETHANDLESIZE(h, (int32)(p - start)); // could ignore this error, maybe
201
        }
202
 
203
        return e;
204
}
205
 
537 daniel-mar 206
OSErr saveparams_guf(Handle h, Boolean useparm) {
539 daniel-mar 207
        extern int ctls[], maps[];
208
 
209
        char* p, * start;
210
        int i;
211
        OSErr e;
212
        size_t est;
213
 
214
        if (!h) return nilHandleErr;
215
 
216
        est = strlen(expr[0]) + strlen(expr[1]) + strlen(expr[2]) + strlen(expr[3]);
217
        // do not be tempted to combine into one expression: 'est' is referenced below
218
        est += 16000;
219
 
220
        // TODO: Encode the file in UTF-8! (German Umlauts, etc.)
221
 
222
        PIUNLOCKHANDLE(h); // should not be necessary
223
        if (!(e = PISETHANDLESIZE(h, (int32)(est))) && (p = start = PILOCKHANDLE(h, false))) {
224
                char strBuildDate[11/*strlen("0000-00-00") + 1*/];
225
                time_t iBuildDate = time(0);
226
                strftime(strBuildDate, 100, "%Y-%m-%d", localtime(&iBuildDate));
227
 
228
                checksliders(4, ctls, maps);
229
 
230
                // Metadata
231
                p += sprintf(p, "# Created with Filter Foundry %s\r\n", VERSION_STR);
232
                p += sprintf(p, "\r\n");
233
                p += sprintf(p, "[GUF]\r\n");
234
                p += sprintf(p, "Protocol=1\r\n");
235
                p += sprintf(p, "\r\n");
236
                p += sprintf(p, "[Info]\r\n");
237
                p += sprintf(p, "Category=<Image>/Filter Factory/%s\r\n", useparm ? gdata->parm.szCategory : "...");
238
                p += sprintf(p, "Title=%s\r\n", useparm ? gdata->parm.szTitle : "...");
239
                p += sprintf(p, "Copyright=%s\r\n", useparm ? gdata->parm.szCopyright : "...");
240
                p += sprintf(p, "Author=%s\r\n", useparm ? gdata->parm.szAuthor : "...");
241
                p += sprintf(p, "\r\n");
242
                p += sprintf(p, "[Version]\r\n");
243
                p += sprintf(p, "Major=1\r\n");
244
                p += sprintf(p, "Minor=0\r\n");
245
                p += sprintf(p, "Micro=0\r\n");
246
                p += sprintf(p, "\r\n");
247
                p += sprintf(p, "[Filter Factory]\r\n");
248
                p += sprintf(p, "8bf=%s\r\n", useparm ? "Untitled.8bf" : "Untitled.8bf"); // TODO: get .guf filename and change .guf to .8bf
249
                p += sprintf(p, "\r\n");
250
                p += sprintf(p, "[Gimp]\r\n");
251
                p += sprintf(p, "Registered=false\r\n");
252
                p += sprintf(p, "Description=%s\r\n", useparm ? gdata->parm.szTitle : "...");
253
                p += sprintf(p, "EdgeMode=2\r\n");
254
                p += sprintf(p, "Date=%s\r\n", strBuildDate);
255
                p += sprintf(p, "\r\n");
256
 
257
                if (useparm) {
258
                        for (i = 0; i < 8; i++) {
259
                                p += sprintf(p, "[Control %d]\r\n", i);
260
                                p += sprintf(p, "Enabled=%s\r\n", gdata->parm.ctl_used[i] ? "true" : "false");
261
                                p += sprintf(p, "Label=%s\r\n", gdata->parm.szCtl[i]);
262
                                p += sprintf(p, "Preset=%d\r\n", gdata->parm.val[i]);
263
                                p += sprintf(p, "Step=1\r\n");
264
                                p += sprintf(p, "\r\n");
265
                        }
266
                        for (i = 0; i < 4; i++) {
267
                                p += sprintf(p, "[Map %d]\r\n", i);
268
                                p += sprintf(p, "Enabled=%s\r\n", gdata->parm.map_used[i] ? "true" : "false");
269
                                p += sprintf(p, "Label=%s\r\n", gdata->parm.szMap[i]);
270
                                p += sprintf(p, "\r\n");
271
                        }
272
                }
273
                else {
274
                        for (i = 0; i < 8; i++) {
275
                                p += sprintf(p, "[Control %d]\r\n", i);
276
                                p += sprintf(p, "Enabled=%s\r\n", ctls[i] ? "true" : "false");
277
                                p += sprintf(p, "Label=%s\r\n", "...");
278
                                p += sprintf(p, "Preset=%d\r\n", slider[i]);
279
                                p += sprintf(p, "Step=1\r\n");
280
                                p += sprintf(p, "\r\n");
281
                        }
282
                        for (i = 0; i < 4; i++) {
283
                                p += sprintf(p, "[Map %d]\r\n", i);
284
                                p += sprintf(p, "Enabled=%s\r\n", maps[i] ? "true" : "false");
285
                                p += sprintf(p, "Label=%s\r\n", "...");
286
                                p += sprintf(p, "\r\n");
287
                        }
288
                }
289
 
290
                p += sprintf(p, "[Code]\r\n");
291
                p += sprintf(p, "R=%s\r\n", useparm ? gdata->parm.szFormula[0] : expr[0]);
292
                p += sprintf(p, "G=%s\r\n", useparm ? gdata->parm.szFormula[1] : expr[1]);
293
                p += sprintf(p, "B=%s\r\n", useparm ? gdata->parm.szFormula[2] : expr[2]);
294
                p += sprintf(p, "A=%s\r\n", useparm ? gdata->parm.szFormula[3] : expr[3]);
295
 
296
                PIUNLOCKHANDLE(h);
297
                e = PISETHANDLESIZE(h, (int32)(p - start)); // could ignore this error, maybe
298
        }
299
 
300
        return e;
537 daniel-mar 301
}
302
 
259 daniel-mar 303
OSErr savehandleintofile(Handle h,FILEREF r){
482 daniel-mar 304
        Ptr p;
505 daniel-mar 305
        FILECOUNT n;
482 daniel-mar 306
        OSErr e;
307
 
308
        if (!h) return nilHandleErr;
309
        p = PILOCKHANDLE(h,false);
505 daniel-mar 310
        n = (FILECOUNT)PIGETHANDLESIZE(h);
482 daniel-mar 311
        e = FSWrite(r,&n,p);
259 daniel-mar 312
        PIUNLOCKHANDLE(h);
313
        return e;
314
}
315
 
537 daniel-mar 316
Boolean savefile_afs_pff_picotxt_guf(StandardFileReply *sfr){
259 daniel-mar 317
        FILEREF r;
318
        Handle h;
319
        Boolean res = false;
498 daniel-mar 320
        TCHAR* reasonstr = NULL;
259 daniel-mar 321
 
322
        FSpDelete(&sfr->sfFile);
323
        if(FSpCreate(&sfr->sfFile,SIG_SIMPLETEXT,TEXT_FILETYPE,sfr->sfScript) == noErr)
324
                if(FSpOpenDF(&sfr->sfFile,fsWrPerm,&r) == noErr){
325
 
444 daniel-mar 326
                        if (fileHasExtension(sfr, TEXT(".txt"))) {
389 daniel-mar 327
                                // PluginCommander .txt
328
                                if ((h = PINEWHANDLE(1))) { // don't set initial size to 0, since some hosts (e.g. GIMP/PSPI) are incompatible with that.
537 daniel-mar 329
                                        res = !(saveparams_picotxt(h, false) || savehandleintofile(h, r));
389 daniel-mar 330
                                        PIDISPOSEHANDLE(h);
331
                                }
369 daniel-mar 332
                        }
333
 
537 daniel-mar 334
                        if (fileHasExtension(sfr, TEXT(".guf"))) {
335
                                // GIMP UserFilter file
336
                                if ((h = PINEWHANDLE(1))) { // don't set initial size to 0, since some hosts (e.g. GIMP/PSPI) are incompatible with that.
337
                                        res = !(saveparams_guf(h, false) || savehandleintofile(h, r));
338
                                        PIDISPOSEHANDLE(h);
339
                                }
340
                        }
341
 
444 daniel-mar 342
                        if ((fileHasExtension(sfr, TEXT(".afs"))) || (fileHasExtension(sfr, TEXT(".pff")))) {
343
                                if (fileHasExtension(sfr, TEXT(".pff"))) {
389 daniel-mar 344
                                        // If it is a Premiere settings file, we need to swap the channels red and blue
345
                                        // We just swap the pointers!
346
                                        char* tmp;
347
                                        tmp = expr[0];
348
                                        expr[0] = expr[2];
349
                                        expr[2] = tmp;
350
                                }
259 daniel-mar 351
 
389 daniel-mar 352
                                if ((h = PINEWHANDLE(1))) { // don't set initial size to 0, since some hosts (e.g. GIMP/PSPI) are incompatible with that.
353
                                        res = !(saveparams_afs_pff(h) || savehandleintofile(h, r));
354
                                        PIDISPOSEHANDLE(h);
355
                                }
356
 
444 daniel-mar 357
                                if (fileHasExtension(sfr, TEXT(".pff"))) {
389 daniel-mar 358
                                        // Swap back so that the other program stuff will work normally again
359
                                        char* tmp;
360
                                        tmp = expr[0];
361
                                        expr[0] = expr[2];
362
                                        expr[2] = tmp;
363
                                }
369 daniel-mar 364
                        }
365
 
259 daniel-mar 366
                        FSClose(r);
498 daniel-mar 367
                }else reasonstr = FF_GetMsg_Cpy(MSG_CANNOT_OPEN_FILE_ID);
368
        else reasonstr = FF_GetMsg_Cpy(MSG_CANNOT_CREATE_FILE_ID);
259 daniel-mar 369
 
444 daniel-mar 370
        if (!res) {
492 daniel-mar 371
                alertuser_id(MSG_CANNOT_SAVE_SETTINGS_ID, reasonstr);
444 daniel-mar 372
        }
259 daniel-mar 373
 
498 daniel-mar 374
        if (reasonstr) FF_GetMsg_Free(reasonstr);
375
 
259 daniel-mar 376
        return res;
377
}