Subversion Repositories filter_foundry

Rev

Rev 555 | 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
 
555 daniel-mar 50
OSErr saveparams_afs_pff(Handle h, Boolean premiereOrder){
505 daniel-mar 51
        char outbuf[CHOPLINES * 2 + 2] = "";
52
        char *q, * p, * r, * start;
259 daniel-mar 53
        size_t n, chunk, j;
555 daniel-mar 54
        int i, k;
259 daniel-mar 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 */
555 daniel-mar 75
                for( k=0 ; k<4 ; ++k ){
76
                        i = k;
77
                        if (premiereOrder) {
78
                                // Premiere has the order BGRA, while Photoshop (and our internal order) is RGBA
79
                                if (k == 0) i = 2;
80
                                else if (k == 2) i = 0;
81
                        }
550 daniel-mar 82
                        if ((r = gdata->parm.szFormula[i])) {
505 daniel-mar 83
                                chunk = 0; // to avoid that compiler complains
84
                                for (n = strlen(r); n; n -= chunk) {
85
                                        chunk = n > (int)CHOPLINES ? (int)CHOPLINES : n;
86
                                        for (j = chunk, q = outbuf; j--; )
87
                                                if (*r == CR) {
259 daniel-mar 88
                                                        *q++ = '\\';
89
                                                        *q++ = 'r';
90
                                                        ++r;
505 daniel-mar 91
                                                }
92
                                                else if (*r == LF) {
393 daniel-mar 93
 
259 daniel-mar 94
                                                        // This can only happen with Windows or Linux.
369 daniel-mar 95
                                                        // Native Linux is not supported, and Windows always combines LF with CR. So we can ignore LF.
259 daniel-mar 96
                                                        ++r;
505 daniel-mar 97
                                                }
98
                                                else
259 daniel-mar 99
                                                        *q++ = *r++;
387 daniel-mar 100
                                        *q++ = CR;
259 daniel-mar 101
                                        *q = 0;
505 daniel-mar 102
                                        p = cat(p, outbuf);
259 daniel-mar 103
                                }
505 daniel-mar 104
                        }
259 daniel-mar 105
                        else
498 daniel-mar 106
                                p = cat(p,(char*)("(null expr)\r")); // this shouldn't happen
387 daniel-mar 107
                        *p++ = CR;
259 daniel-mar 108
                }
109
 
110
//              *p = 0; dbg(start);
111
 
112
                PIUNLOCKHANDLE(h);
113
                e = PISETHANDLESIZE(h,(int32)(p - start)); // could ignore this error, maybe
114
        }
115
 
116
        return e;
117
}
118
 
550 daniel-mar 119
OSErr saveparams_picotxt(Handle h) {
389 daniel-mar 120
        char * p, *start;
121
        int i;
122
        OSErr e;
123
        size_t est;
124
 
482 daniel-mar 125
        if (!h) return nilHandleErr;
389 daniel-mar 126
 
550 daniel-mar 127
        est = strlen(gdata->parm.szFormula[0]) + strlen(gdata->parm.szFormula[1]) + strlen(gdata->parm.szFormula[2]) + strlen(gdata->parm.szFormula[3]);
389 daniel-mar 128
        // do not be tempted to combine into one expression: 'est' is referenced below
129
        est += 16000;
130
 
131
        PIUNLOCKHANDLE(h); // should not be necessary
132
        if (!(e = PISETHANDLESIZE(h, (int32)(est))) && (p = start = PILOCKHANDLE(h, false))) {
550 daniel-mar 133
                checksliders(4);
389 daniel-mar 134
 
135
                // Metadata
550 daniel-mar 136
                p += sprintf(p, "Category: %s\r\n", gdata->parm.szCategory);
137
                p += sprintf(p, "Title: %s\r\n", gdata->parm.szTitle);
138
                p += sprintf(p, "Copyright: %s\r\n", gdata->parm.szCopyright);
139
                p += sprintf(p, "Author: %s\r\n", gdata->parm.szAuthor);
140
                p += sprintf(p, "Filename: %s\r\n", "Untitled.8bf"); // TODO: get .txt filename and change .txt to .8bf
389 daniel-mar 141
                p += sprintf(p, "\r\n");
550 daniel-mar 142
                p += sprintf(p, "R: %s\r\n", gdata->parm.szFormula[0]);
389 daniel-mar 143
                p += sprintf(p, "\r\n");
550 daniel-mar 144
                p += sprintf(p, "G: %s\r\n", gdata->parm.szFormula[1]);
389 daniel-mar 145
                p += sprintf(p, "\r\n");
550 daniel-mar 146
                p += sprintf(p, "B: %s\r\n", gdata->parm.szFormula[2]);
389 daniel-mar 147
                p += sprintf(p, "\r\n");
550 daniel-mar 148
                p += sprintf(p, "A: %s\r\n", gdata->parm.szFormula[3]);
389 daniel-mar 149
                p += sprintf(p, "\r\n");
550 daniel-mar 150
                for (i = 0; i < 8; i++) {
151
                        if (gdata->parm.ctl_used[i]) {
152
                                p += sprintf(p, "ctl[%d]: %s\r\n", i, gdata->parm.szCtl[i]);
389 daniel-mar 153
                        }
550 daniel-mar 154
                }
155
                for (i = 0; i < 4; i++) {
156
                        if (gdata->parm.map_used[i]) {
157
                                p += sprintf(p, "map[%d]: %s\r\n", i, gdata->parm.szMap[i]);
389 daniel-mar 158
                        }
550 daniel-mar 159
                }
160
                p += sprintf(p, "\r\n");
161
                for (i = 0; i < 8; i++) {
162
                        if (gdata->parm.ctl_used[i]) {
163
                                p += sprintf(p, "val[%d]: %d\r\n", i, gdata->parm.val[i]);
389 daniel-mar 164
                        }
165
                }
550 daniel-mar 166
                /*
167
                p += sprintf(p, "\r\n");
168
                for (i = 0; i < 8; i++) {
169
                        if (gdata->parm.ctl_used[i]) {
170
                                p += sprintf(p, "def[%d]: %d\r\n", i, gdata->parm.val[i]);
389 daniel-mar 171
                        }
172
                }
550 daniel-mar 173
                */
389 daniel-mar 174
 
175
                PIUNLOCKHANDLE(h);
176
                e = PISETHANDLESIZE(h, (int32)(p - start)); // could ignore this error, maybe
177
        }
178
 
179
        return e;
180
}
181
 
550 daniel-mar 182
OSErr saveparams_guf(Handle h) {
539 daniel-mar 183
        char* p, * start;
184
        int i;
185
        OSErr e;
186
        size_t est;
187
 
188
        if (!h) return nilHandleErr;
189
 
550 daniel-mar 190
        est = strlen(gdata->parm.szFormula[0]) + strlen(gdata->parm.szFormula[1]) + strlen(gdata->parm.szFormula[2]) + strlen(gdata->parm.szFormula[3]);
539 daniel-mar 191
        // do not be tempted to combine into one expression: 'est' is referenced below
192
        est += 16000;
193
 
194
        // TODO: Encode the file in UTF-8! (German Umlauts, etc.)
195
 
196
        PIUNLOCKHANDLE(h); // should not be necessary
197
        if (!(e = PISETHANDLESIZE(h, (int32)(est))) && (p = start = PILOCKHANDLE(h, false))) {
198
                char strBuildDate[11/*strlen("0000-00-00") + 1*/];
199
                time_t iBuildDate = time(0);
541 daniel-mar 200
                strftime(strBuildDate, 11, "%Y-%m-%d", localtime(&iBuildDate));
539 daniel-mar 201
 
550 daniel-mar 202
                checksliders(4);
539 daniel-mar 203
 
204
                // Metadata
205
                p += sprintf(p, "# Created with Filter Foundry %s\r\n", VERSION_STR);
206
                p += sprintf(p, "\r\n");
207
                p += sprintf(p, "[GUF]\r\n");
208
                p += sprintf(p, "Protocol=1\r\n");
209
                p += sprintf(p, "\r\n");
210
                p += sprintf(p, "[Info]\r\n");
550 daniel-mar 211
                p += sprintf(p, "Category=<Image>/Filter Factory/%s\r\n", gdata->parm.szCategory);
212
                p += sprintf(p, "Title=%s\r\n", gdata->parm.szTitle);
213
                p += sprintf(p, "Copyright=%s\r\n", gdata->parm.szCopyright);
214
                p += sprintf(p, "Author=%s\r\n", gdata->parm.szAuthor);
539 daniel-mar 215
                p += sprintf(p, "\r\n");
216
                p += sprintf(p, "[Version]\r\n");
217
                p += sprintf(p, "Major=1\r\n");
218
                p += sprintf(p, "Minor=0\r\n");
219
                p += sprintf(p, "Micro=0\r\n");
220
                p += sprintf(p, "\r\n");
221
                p += sprintf(p, "[Filter Factory]\r\n");
550 daniel-mar 222
                p += sprintf(p, "8bf=%s\r\n", "Untitled.8bf"); // TODO: get .guf filename and change .guf to .8bf
539 daniel-mar 223
                p += sprintf(p, "\r\n");
224
                p += sprintf(p, "[Gimp]\r\n");
225
                p += sprintf(p, "Registered=false\r\n");
550 daniel-mar 226
                p += sprintf(p, "Description=%s\r\n", gdata->parm.szTitle);
539 daniel-mar 227
                p += sprintf(p, "EdgeMode=2\r\n");
228
                p += sprintf(p, "Date=%s\r\n", strBuildDate);
229
                p += sprintf(p, "\r\n");
230
 
550 daniel-mar 231
                for (i = 0; i < 8; i++) {
232
                        p += sprintf(p, "[Control %d]\r\n", i);
233
                        p += sprintf(p, "Enabled=%s\r\n", gdata->parm.ctl_used[i] ? "true" : "false");
234
                        p += sprintf(p, "Label=%s\r\n", gdata->parm.szCtl[i]);
235
                        p += sprintf(p, "Preset=%d\r\n", gdata->parm.val[i]);
236
                        p += sprintf(p, "Step=1\r\n");
237
                        p += sprintf(p, "\r\n");
539 daniel-mar 238
                }
550 daniel-mar 239
                for (i = 0; i < 4; i++) {
240
                        p += sprintf(p, "[Map %d]\r\n", i);
241
                        p += sprintf(p, "Enabled=%s\r\n", gdata->parm.map_used[i] ? "true" : "false");
242
                        p += sprintf(p, "Label=%s\r\n", gdata->parm.szMap[i]);
243
                        p += sprintf(p, "\r\n");
539 daniel-mar 244
                }
245
 
246
                p += sprintf(p, "[Code]\r\n");
550 daniel-mar 247
                p += sprintf(p, "R=%s\r\n", gdata->parm.szFormula[0]);
248
                p += sprintf(p, "G=%s\r\n", gdata->parm.szFormula[1]);
249
                p += sprintf(p, "B=%s\r\n", gdata->parm.szFormula[2]);
250
                p += sprintf(p, "A=%s\r\n", gdata->parm.szFormula[3]);
539 daniel-mar 251
 
252
                PIUNLOCKHANDLE(h);
253
                e = PISETHANDLESIZE(h, (int32)(p - start)); // could ignore this error, maybe
254
        }
255
 
256
        return e;
537 daniel-mar 257
}
258
 
259 daniel-mar 259
OSErr savehandleintofile(Handle h,FILEREF r){
482 daniel-mar 260
        Ptr p;
505 daniel-mar 261
        FILECOUNT n;
482 daniel-mar 262
        OSErr e;
263
 
264
        if (!h) return nilHandleErr;
265
        p = PILOCKHANDLE(h,false);
505 daniel-mar 266
        n = (FILECOUNT)PIGETHANDLESIZE(h);
482 daniel-mar 267
        e = FSWrite(r,&n,p);
259 daniel-mar 268
        PIUNLOCKHANDLE(h);
269
        return e;
270
}
271
 
555 daniel-mar 272
FFSavingResult savefile_afs_pff_picotxt_guf(StandardFileReply *sfr){
259 daniel-mar 273
        FILEREF r;
274
        Handle h;
555 daniel-mar 275
        Boolean bres = false;
557 daniel-mar 276
        FFSavingResult res = SAVING_OK;
259 daniel-mar 277
 
278
        FSpDelete(&sfr->sfFile);
555 daniel-mar 279
        if (FSpCreate(&sfr->sfFile, SIG_SIMPLETEXT, TEXT_FILETYPE, sfr->sfScript) == noErr) {
280
                if (FSpOpenDF(&sfr->sfFile, fsWrPerm, &r) == noErr) {
259 daniel-mar 281
 
444 daniel-mar 282
                        if (fileHasExtension(sfr, TEXT(".txt"))) {
389 daniel-mar 283
                                // PluginCommander .txt
284
                                if ((h = PINEWHANDLE(1))) { // don't set initial size to 0, since some hosts (e.g. GIMP/PSPI) are incompatible with that.
555 daniel-mar 285
                                        bres = !(saveparams_picotxt(h) || savehandleintofile(h, r));
286
                                        if (!bres) res = MSG_ERROR_GENERATING_DATA_ID;
389 daniel-mar 287
                                        PIDISPOSEHANDLE(h);
288
                                }
555 daniel-mar 289
                                else res = MSG_OUT_OF_MEMORY_ID;
369 daniel-mar 290
                        }
555 daniel-mar 291
                        else if (fileHasExtension(sfr, TEXT(".guf"))) {
537 daniel-mar 292
                                // GIMP UserFilter file
293
                                if ((h = PINEWHANDLE(1))) { // don't set initial size to 0, since some hosts (e.g. GIMP/PSPI) are incompatible with that.
555 daniel-mar 294
                                        bres = !(saveparams_guf(h) || savehandleintofile(h, r));
295
                                        if (!bres) res = MSG_ERROR_GENERATING_DATA_ID;
537 daniel-mar 296
                                        PIDISPOSEHANDLE(h);
297
                                }
555 daniel-mar 298
                                else res = MSG_OUT_OF_MEMORY_ID;
537 daniel-mar 299
                        }
555 daniel-mar 300
                        else if ((fileHasExtension(sfr, TEXT(".afs"))) || (fileHasExtension(sfr, TEXT(".pff")))) {
389 daniel-mar 301
                                if ((h = PINEWHANDLE(1))) { // don't set initial size to 0, since some hosts (e.g. GIMP/PSPI) are incompatible with that.
555 daniel-mar 302
                                        bres = !(saveparams_afs_pff(h, fileHasExtension(sfr, TEXT(".pff"))) || savehandleintofile(h, r));
303
                                        if (!bres) res = MSG_ERROR_GENERATING_DATA_ID;
389 daniel-mar 304
                                        PIDISPOSEHANDLE(h);
305
                                }
555 daniel-mar 306
                                else res = MSG_OUT_OF_MEMORY_ID;
369 daniel-mar 307
                        }
555 daniel-mar 308
                        else {
309
                                res = MSG_UNSUPPORTED_FILE_FORMAT_ID;
310
                        }
369 daniel-mar 311
 
259 daniel-mar 312
                        FSClose(r);
555 daniel-mar 313
                }
314
                else res = MSG_CANNOT_OPEN_FILE_ID;
444 daniel-mar 315
        }
555 daniel-mar 316
        else res = MSG_CANNOT_CREATE_FILE_ID;
259 daniel-mar 317
 
318
        return res;
319
}