Subversion Repositories filter_foundry

Rev

Rev 433 | Rev 453 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 433 Rev 444
1
/*
1
/*
2
    This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
2
    This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
3
    Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au
3
    Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au
4
    Copyright (C) 2018-2021 Daniel Marschall, ViaThinkSoft
4
    Copyright (C) 2018-2021 Daniel Marschall, ViaThinkSoft
5
 
5
 
6
    This program is free software; you can redistribute it and/or modify
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
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
8
    the Free Software Foundation; either version 2 of the License, or
9
    (at your option) any later version.
9
    (at your option) any later version.
10
 
10
 
11
    This program is distributed in the hope that it will be useful,
11
    This program is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
14
    GNU General Public License for more details.
15
 
15
 
16
    You should have received a copy of the GNU General Public License
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
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
18
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
*/
19
*/
20
 
20
 
21
#include "ff.h"
21
#include "ff.h"
22
 
22
 
23
#include "file_compat.h"
23
#include "file_compat.h"
24
 
24
 
25
#ifdef MAC_ENV
25
#ifdef MAC_ENV
26
#include <Endian.h>
26
#include <Endian.h>
27
#else
27
#else
28
int EndianS32_LtoN(int num) {
28
int EndianS32_LtoN(int num) {
29
        return ((num>>24)&0xff) +      // move byte 3 to byte 0
29
        return ((num>>24)&0xff) +      // move byte 3 to byte 0
30
               ((num<<8)&0xff0000) +   // move byte 1 to byte 2
30
               ((num<<8)&0xff0000) +   // move byte 1 to byte 2
31
               ((num>>8)&0xff00) +     // move byte 2 to byte 1
31
               ((num>>8)&0xff00) +     // move byte 2 to byte 1
32
               ((num<<24)&0xff000000); // byte 0 to byte 3
32
               ((num<<24)&0xff000000); // byte 0 to byte 3
33
}
33
}
34
#endif
34
#endif
35
 
35
 
36
enum{
36
enum{
37
        BUFSIZE = 4L<<10,
37
        BUFSIZE = 4L<<10,
38
        MAXLINE = 0x200,
38
        MAXLINE = 0x200,
39
};
39
};
40
 
40
 
41
Boolean readparams_afs_pff(Handle h,char **reason){
41
Boolean readparams_afs_pff(Handle h,char **reason){
42
        Boolean res = false;
42
        Boolean res = false;
43
        char linebuf[MAXLINE+1],curexpr[MAXEXPR+1],*p,*dataend,*q;
43
        char linebuf[MAXLINE+1],curexpr[MAXEXPR+1],*p,*dataend,*q;
44
        char c;
44
        char c;
45
        int linecnt, lineptr, exprcnt;
45
        int linecnt, lineptr, exprcnt;
46
 
46
 
47
        if(!h){
47
        if(!h){
48
                *reason = _strdup("readparams: Null parameter handle.");
48
                *reason = _strdup("readparams: Null parameter handle.");
49
                return false;
49
                return false;
50
        }
50
        }
51
 
51
 
52
        p = PILOCKHANDLE(h,false);
52
        p = PILOCKHANDLE(h,false);
53
        dataend = p + PIGETHANDLESIZE(h);
53
        dataend = p + PIGETHANDLESIZE(h);
54
 
54
 
55
        q = curexpr;
55
        q = curexpr;
56
        linecnt = exprcnt = lineptr = 0;
56
        linecnt = exprcnt = lineptr = 0;
57
 
57
 
58
        //*reason = _strdup("File was too short.");
58
        //*reason = _strdup("File was too short.");
59
        while(p < dataend){
59
        while(p < dataend){
60
 
60
 
61
                c = *p++;
61
                c = *p++;
62
 
62
 
63
                if(c==CR || c==LF){ /* detected end of line */
63
                if(c==CR || c==LF){ /* detected end of line */
64
 
64
 
65
                        /* look ahead to see if we need to skip a line feed (DOS CRLF EOL convention) */
65
                        /* look ahead to see if we need to skip a line feed (DOS CRLF EOL convention) */
66
                        if(p < dataend && c == CR && *p == LF)
66
                        if(p < dataend && c == CR && *p == LF)
67
                                ++p;
67
                                ++p;
68
 
68
 
69
                        linebuf[lineptr] = 0; /* add terminating NUL to line buffer */
69
                        linebuf[lineptr] = 0; /* add terminating NUL to line buffer */
70
 
70
 
71
                        /* process complete line */
71
                        /* process complete line */
72
                        if(linecnt==0){
72
                        if(linecnt==0){
73
                                if(strcmp(linebuf,"%RGB-1.0")){
73
                                if(strcmp(linebuf,"%RGB-1.0")){
74
                                        // *reason = _strdup("This doesn't look like a Filter Factory file (first line is not \"%RGB-1.0\").");
74
                                        // *reason = _strdup("This doesn't look like a Filter Factory file (first line is not \"%RGB-1.0\").");
75
                                        break;
75
                                        break;
76
                                }
76
                                }
77
                        }else if(linecnt<=8){
77
                        }else if(linecnt<=8){
78
                                slider[linecnt-1] = atoi(linebuf);
78
                                slider[linecnt-1] = atoi(linebuf);
79
                        }else{
79
                        }else{
80
                                if(lineptr){
80
                                if(lineptr){
81
                                        /* it's not an empty line; append it to current expr string */
81
                                        /* it's not an empty line; append it to current expr string */
82
                                        if( q+lineptr > curexpr+MAXEXPR ){
82
                                        if( q+lineptr > curexpr+MAXEXPR ){
83
                                                *reason = _strdup("Found an expression longer than 1024 characters.");
83
                                                *reason = _strdup("Found an expression longer than 1024 characters.");
84
                                                break;
84
                                                break;
85
                                        }
85
                                        }
86
                                        q = cat(q,linebuf);
86
                                        q = cat(q,linebuf);
87
                                }else{
87
                                }else{
88
                                        /* it's an empty line: we've completed the expr string */
88
                                        /* it's an empty line: we've completed the expr string */
89
                                        if(expr[exprcnt])
89
                                        if(expr[exprcnt])
90
                                                free(expr[exprcnt]);
90
                                                free(expr[exprcnt]);
91
                                        *q = 0;
91
                                        *q = 0;
92
                                        if(!(expr[exprcnt] = my_strdup(curexpr))){
92
                                        if(!(expr[exprcnt] = my_strdup(curexpr))){
93
                                                *reason = _strdup("Could not get memory for expression.");
93
                                                *reason = _strdup("Could not get memory for expression.");
94
                                                break;
94
                                                break;
95
                                        }
95
                                        }
96
 
96
 
97
                                        if(++exprcnt == 4){
97
                                        if(++exprcnt == 4){
98
                                                res = true;
98
                                                res = true;
99
                                                break; /* got everything we want */
99
                                                break; /* got everything we want */
100
                                        }
100
                                        }
101
 
101
 
102
                                        q = curexpr; /* empty current expr, ready for next one */
102
                                        q = curexpr; /* empty current expr, ready for next one */
103
                                }
103
                                }
104
                        }
104
                        }
105
 
105
 
106
                        ++linecnt;
106
                        ++linecnt;
107
                        lineptr = 0;
107
                        lineptr = 0;
108
                }else{
108
                }else{
109
                        /* store character */
109
                        /* store character */
110
                        if(c=='\\'){ /* escape sequence */
110
                        if(c=='\\'){ /* escape sequence */
111
                                if(p < dataend){
111
                                if(p < dataend){
112
                                        c = *p++;
112
                                        c = *p++;
113
                                        switch(c){
113
                                        switch(c){
114
                                        case 'r':
114
                                        case 'r':
115
                                                #if WIN_ENV
115
                                                #if WIN_ENV
116
                                                c = CR;
116
                                                c = CR;
117
                                                if (lineptr < MAXLINE)
117
                                                if (lineptr < MAXLINE)
118
                                                        linebuf[lineptr++] = c;
118
                                                        linebuf[lineptr++] = c;
119
                                                c = LF;
119
                                                c = LF;
120
                                                #else
120
                                                #else
121
                                                c = CR;
121
                                                c = CR;
122
                                                #endif
122
                                                #endif
123
                                                break;
123
                                                break;
124
                                        case '\\': break;
124
                                        case '\\': break;
125
                                        //default:
125
                                        //default:
126
                                        //      if(alerts) alertuser(_strdup("Warning:"),_strdup("Unknown escape sequence in input."));
126
                                        //      if(alerts) alertuser((TCHAR*)TEXT("Warning:"),TEXT("Unknown escape sequence in input."));
127
                                        }
127
                                        }
128
                                }//else if(alerts) alertuser(_strdup("Warning:"),_strdup("truncated escape sequence ends input"));
128
                                }//else if(alerts) alertuser((TCHAR*)TEXT("Warning:"),TEXT("truncated escape sequence ends input"));
129
                        }
129
                        }
130
 
130
 
131
                        if(lineptr < MAXLINE)
131
                        if(lineptr < MAXLINE)
132
                                linebuf[lineptr++] = c;
132
                                linebuf[lineptr++] = c;
133
                }
133
                }
134
        }
134
        }
135
 
135
 
136
        PIUNLOCKHANDLE(h);
136
        PIUNLOCKHANDLE(h);
137
 
137
 
138
        return res;
138
        return res;
139
}
139
}
140
 
140
 
141
void convert_premiere_to_photoshop(PARM_T* photoshop, PARM_T_PREMIERE* premiere) {
141
void convert_premiere_to_photoshop(PARM_T* photoshop, PARM_T_PREMIERE* premiere) {
142
        int i;
142
        int i;
143
 
143
 
144
        photoshop->cbSize = sizeof(PARM_T);
144
        photoshop->cbSize = sizeof(PARM_T);
145
        photoshop->standalone = premiere->standalone;
145
        photoshop->standalone = premiere->standalone;
146
        for (i=0;i<8;++i)
146
        for (i=0;i<8;++i)
147
                photoshop->val[i] = premiere->val[i];
147
                photoshop->val[i] = premiere->val[i];
148
        photoshop->popDialog = premiere->popDialog;
148
        photoshop->popDialog = premiere->popDialog;
149
        photoshop->unknown1 = premiere->unknown1;
149
        photoshop->unknown1 = premiere->unknown1;
150
        photoshop->unknown2 = premiere->unknown2;
150
        photoshop->unknown2 = premiere->unknown2;
151
        photoshop->unknown3 = premiere->unknown3;
151
        photoshop->unknown3 = premiere->unknown3;
152
        for (i=0;i<4;++i)
152
        for (i=0;i<4;++i)
153
                photoshop->map_used[i] = premiere->map_used[i];
153
                photoshop->map_used[i] = premiere->map_used[i];
154
        for (i=0;i<8;++i)
154
        for (i=0;i<8;++i)
155
                photoshop->ctl_used[i] = premiere->ctl_used[i];
155
                photoshop->ctl_used[i] = premiere->ctl_used[i];
156
        sprintf(photoshop->szCategory, "Filter Factory"); // Premiere plugins do not have a category attribute
156
        sprintf(photoshop->szCategory, "Filter Factory"); // Premiere plugins do not have a category attribute
157
        photoshop->iProtected = 0; // Premiere plugins do not have a protect flag
157
        photoshop->iProtected = 0; // Premiere plugins do not have a protect flag
158
        memcpy((void*)photoshop->szTitle, (void*)premiere->szTitle, sizeof(photoshop->szTitle));
158
        memcpy((void*)photoshop->szTitle, (void*)premiere->szTitle, sizeof(photoshop->szTitle));
159
        memcpy((void*)photoshop->szCopyright, (void*)premiere->szCopyright, sizeof(photoshop->szCopyright));
159
        memcpy((void*)photoshop->szCopyright, (void*)premiere->szCopyright, sizeof(photoshop->szCopyright));
160
        memcpy((void*)photoshop->szAuthor, (void*)premiere->szAuthor, sizeof(photoshop->szAuthor));
160
        memcpy((void*)photoshop->szAuthor, (void*)premiere->szAuthor, sizeof(photoshop->szAuthor));
161
        for (i=0;i<4;++i)
161
        for (i=0;i<4;++i)
162
                memcpy((void*)photoshop->szMap[i], (void*)premiere->szMap[i], sizeof(photoshop->szMap[i]));
162
                memcpy((void*)photoshop->szMap[i], (void*)premiere->szMap[i], sizeof(photoshop->szMap[i]));
163
        for (i=0;i<8;++i)
163
        for (i=0;i<8;++i)
164
                memcpy((void*)photoshop->szCtl[i], (void*)premiere->szCtl[i], sizeof(photoshop->szCtl[i]));
164
                memcpy((void*)photoshop->szCtl[i], (void*)premiere->szCtl[i], sizeof(photoshop->szCtl[i]));
165
 
165
 
166
        if (premiere->singleExpression) {
166
        if (premiere->singleExpression) {
167
                memcpy((void*)photoshop->szFormula[0], (void*)premiere->szFormula[3], sizeof(photoshop->szFormula[3]));
167
                memcpy((void*)photoshop->szFormula[0], (void*)premiere->szFormula[3], sizeof(photoshop->szFormula[3]));
168
                memcpy((void*)photoshop->szFormula[1], (void*)premiere->szFormula[3], sizeof(photoshop->szFormula[3]));
168
                memcpy((void*)photoshop->szFormula[1], (void*)premiere->szFormula[3], sizeof(photoshop->szFormula[3]));
169
                memcpy((void*)photoshop->szFormula[2], (void*)premiere->szFormula[3], sizeof(photoshop->szFormula[3]));
169
                memcpy((void*)photoshop->szFormula[2], (void*)premiere->szFormula[3], sizeof(photoshop->szFormula[3]));
170
                memcpy((void*)photoshop->szFormula[3], (void*)premiere->szFormula[3], sizeof(photoshop->szFormula[3]));
170
                memcpy((void*)photoshop->szFormula[3], (void*)premiere->szFormula[3], sizeof(photoshop->szFormula[3]));
171
        } else {
171
        } else {
172
                memcpy((void*)photoshop->szFormula[0], (void*)premiere->szFormula[2], sizeof(photoshop->szFormula[2]));
172
                memcpy((void*)photoshop->szFormula[0], (void*)premiere->szFormula[2], sizeof(photoshop->szFormula[2]));
173
                memcpy((void*)photoshop->szFormula[1], (void*)premiere->szFormula[1], sizeof(photoshop->szFormula[1]));
173
                memcpy((void*)photoshop->szFormula[1], (void*)premiere->szFormula[1], sizeof(photoshop->szFormula[1]));
174
                memcpy((void*)photoshop->szFormula[2], (void*)premiere->szFormula[0], sizeof(photoshop->szFormula[0]));
174
                memcpy((void*)photoshop->szFormula[2], (void*)premiere->szFormula[0], sizeof(photoshop->szFormula[0]));
175
                memcpy((void*)photoshop->szFormula[3], (void*)premiere->szFormula[3], sizeof(photoshop->szFormula[3]));
175
                memcpy((void*)photoshop->szFormula[3], (void*)premiere->szFormula[3], sizeof(photoshop->szFormula[3]));
176
        }
176
        }
177
}
177
}
178
 
178
 
179
char* _ffx_read_str(char** q) {
179
char* _ffx_read_str(char** q) {
180
        uint32_t len;
180
        uint32_t len;
181
        char* val;
181
        char* val;
182
 
182
 
183
        len = *((uint32_t*)*q);
183
        len = *((uint32_t*)*q);
184
        *q += sizeof(uint32_t);
184
        *q += sizeof(uint32_t);
185
        val = (char*)malloc(len + 1);
185
        val = (char*)malloc(len + 1);
186
        if (val != NULL) {
186
        if (val != NULL) {
187
                memcpy(val, (char*)*q, len);
187
                memcpy(val, (char*)*q, len);
188
                val[len] = 0;
188
                val[len] = 0;
189
        }
189
        }
190
        *q += len;
190
        *q += len;
191
        return val;
191
        return val;
192
}
192
}
193
 
193
 
194
Boolean readfile_ffx(StandardFileReply* sfr, char** reason) {
194
Boolean readfile_ffx(StandardFileReply* sfr, char** reason) {
195
        Handle h;
195
        Handle h;
196
        Boolean res = false;
196
        Boolean res = false;
197
        FILEREF refnum;
197
        FILEREF refnum;
198
        uint32_t len;
198
        uint32_t len;
199
        char* val;
199
        char* val;
200
        int format_version = -1;
200
        int format_version = -1;
201
        int i;
201
        int i;
202
 
202
 
203
        UNREFERENCED_PARAMETER(reason);
203
        UNREFERENCED_PARAMETER(reason);
204
 
204
 
205
        if (FSpOpenDF(&sfr->sfFile, fsRdPerm, &refnum) == noErr) {
205
        if (FSpOpenDF(&sfr->sfFile, fsRdPerm, &refnum) == noErr) {
206
                if ((h = readfileintohandle(refnum))) {
206
                if ((h = readfileintohandle(refnum))) {
207
                        char* q = (char*)PILOCKHANDLE(h, false);
207
                        char* q = (char*)PILOCKHANDLE(h, false);
208
 
208
 
209
                        len = *((uint32_t*)q);
209
                        len = *((uint32_t*)q);
210
                        if (len == 6) {
210
                        if (len == 6) {
211
                                val = _ffx_read_str(&q);
211
                                val = _ffx_read_str(&q);
212
                                if (strcmp(val, "FFX1.0") == 0) format_version = 10;
212
                                if (strcmp(val, "FFX1.0") == 0) format_version = 10;
213
                                else if (strcmp(val, "FFX1.1") == 0) format_version = 11;
213
                                else if (strcmp(val, "FFX1.1") == 0) format_version = 11;
214
                                else if (strcmp(val, "FFX1.2") == 0) format_version = 12;
214
                                else if (strcmp(val, "FFX1.2") == 0) format_version = 12;
215
                                free(val);
215
                                free(val);
216
                                if (format_version > 0) {
216
                                if (format_version > 0) {
217
                                        simplewarning(_strdup("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."));
217
                                        simplewarning((TCHAR*)TEXT("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."));
218
 
218
 
219
                                        val = _ffx_read_str(&q);
219
                                        val = _ffx_read_str(&q);
220
                                        strcpy(gdata->parm.szTitle, val);
220
                                        strcpy(gdata->parm.szTitle, val);
221
                                        free(val);
221
                                        free(val);
222
 
222
 
223
                                        val = _ffx_read_str(&q);
223
                                        val = _ffx_read_str(&q);
224
                                        strcpy(gdata->parm.szCategory, val);
224
                                        strcpy(gdata->parm.szCategory, val);
225
                                        free(val);
225
                                        free(val);
226
 
226
 
227
                                        val = _ffx_read_str(&q);
227
                                        val = _ffx_read_str(&q);
228
                                        strcpy(gdata->parm.szAuthor, val);
228
                                        strcpy(gdata->parm.szAuthor, val);
229
                                        free(val);
229
                                        free(val);
230
 
230
 
231
                                        val = _ffx_read_str(&q);
231
                                        val = _ffx_read_str(&q);
232
                                        strcpy(gdata->parm.szCopyright, val);
232
                                        strcpy(gdata->parm.szCopyright, val);
233
                                        free(val);
233
                                        free(val);
234
 
234
 
235
                                        // Channels I, R, G, B, A
235
                                        // Channels I, R, G, B, A
236
                                        for (i = 0; i < 4; i++) {
236
                                        for (i = 0; i < 4; i++) {
237
                                                val = _ffx_read_str(&q);
237
                                                val = _ffx_read_str(&q);
238
                                                if (i == 0) {
238
                                                if (i == 0) {
239
                                                        char* val2 = _ffx_read_str(&q);
239
                                                        char* val2 = _ffx_read_str(&q);
240
                                                        if (strcmp(val, "0") != 0) {
240
                                                        if (strcmp(val, "0") != 0) {
241
                                                                // "Intro channel" existing
241
                                                                // "Intro channel" existing
242
                                                                // C++ wrong warning: Using uninitialized memory "val2" (C6001)
242
                                                                // C++ wrong warning: Using uninitialized memory "val2" (C6001)
243
                                                                #pragma warning(suppress : 6001)
243
                                                                #pragma warning(suppress : 6001)
244
                                                                char* combined = (char*)malloc(strlen(val) + strlen(",") + strlen(val2) + 1);
244
                                                                char* combined = (char*)malloc(strlen(val) + strlen(",") + strlen(val2) + 1);
245
                                                                if (combined != NULL) {
245
                                                                if (combined != NULL) {
246
                                                                        sprintf(combined, "%s,%s", val, val2);
246
                                                                        sprintf(combined, "%s,%s", val, val2);
247
                                                                        free(val);
247
                                                                        free(val);
248
                                                                        free(val2);
248
                                                                        free(val2);
249
                                                                        val = combined;
249
                                                                        val = combined;
250
                                                                }
250
                                                                }
251
                                                        }
251
                                                        }
252
                                                        else {
252
                                                        else {
253
                                                                free(val);
253
                                                                free(val);
254
                                                                val = val2;
254
                                                                val = val2;
255
                                                        }
255
                                                        }
256
                                                }
256
                                                }
257
                                                if (strlen(val) >= sizeof(gdata->parm.szFormula[i])) {
257
                                                if (strlen(val) >= sizeof(gdata->parm.szFormula[i])) {
258
                                                        if (i == 0) {
258
                                                        if (i == 0) {
259
                                                                simplealert(_strdup("Attention! The formula for channel I/R was too long (longer than 1023 characters) and was truncated."));
259
                                                                simplealert((TCHAR*)TEXT("Attention! The formula for channel I/R was too long (longer than 1023 characters) and was truncated."));
260
                                                        }
260
                                                        }
261
                                                        else if (i == 1) {
261
                                                        else if (i == 1) {
262
                                                                simplealert(_strdup("Attention! The formula for channel G was too long (longer than 1023 characters) and was truncated."));
262
                                                                simplealert((TCHAR*)TEXT("Attention! The formula for channel G was too long (longer than 1023 characters) and was truncated."));
263
                                                        }
263
                                                        }
264
                                                        else if (i == 2) {
264
                                                        else if (i == 2) {
265
                                                                simplealert(_strdup("Attention! The formula for channel B was too long (longer than 1023 characters) and was truncated."));
265
                                                                simplealert((TCHAR*)TEXT("Attention! The formula for channel B was too long (longer than 1023 characters) and was truncated."));
266
                                                        }
266
                                                        }
267
                                                        else if (i == 3) {
267
                                                        else if (i == 3) {
268
                                                                simplealert(_strdup("Attention! The formula for channel A was too long (longer than 1023 characters) and was truncated."));
268
                                                                simplealert((TCHAR*)TEXT("Attention! The formula for channel A was too long (longer than 1023 characters) and was truncated."));
269
                                                        }
269
                                                        }
270
                                                        // C++ wrong warning: Buffer overflow (C6386)
270
                                                        // C++ wrong warning: Buffer overflow (C6386)
271
                                                        #pragma warning(suppress : 6386)
271
                                                        #pragma warning(suppress : 6386)
272
                                                        val[sizeof(gdata->parm.szFormula[i]) - 1] = '\0';
272
                                                        val[sizeof(gdata->parm.szFormula[i]) - 1] = '\0';
273
                                                }
273
                                                }
274
                                                if (expr[i]) free(expr[i]);
274
                                                if (expr[i]) free(expr[i]);
275
                                                expr[i] = my_strdup(val);
275
                                                expr[i] = my_strdup(val);
276
                                                strcpy(gdata->parm.szFormula[i], val);
276
                                                strcpy(gdata->parm.szFormula[i], val);
277
                                                free(val);
277
                                                free(val);
278
                                        }
278
                                        }
279
 
279
 
280
                                        // Sliders
280
                                        // Sliders
281
                                        for (i = 0; i < 8; i++) {
281
                                        for (i = 0; i < 8; i++) {
282
                                                char* sliderName;
282
                                                char* sliderName;
283
                                                val = _ffx_read_str(&q);
283
                                                val = _ffx_read_str(&q);
284
                                                sliderName = val;
284
                                                sliderName = val;
285
                                                if (format_version >= 12) {
285
                                                if (format_version >= 12) {
286
                                                        // Format FFX1.2 has prefixes {S} = Slider, {C} = Checkbox, none = Slider
286
                                                        // Format FFX1.2 has prefixes {S} = Slider, {C} = Checkbox, none = Slider
287
                                                        if ((sliderName[0] == '{') && (sliderName[1] == 'S') && (sliderName[2] == '}')) sliderName += 3;
287
                                                        if ((sliderName[0] == '{') && (sliderName[1] == 'S') && (sliderName[2] == '}')) sliderName += 3;
288
                                                        else if ((sliderName[0] == '{') && (sliderName[1] == 'C') && (sliderName[2] == '}')) sliderName += 3;
288
                                                        else if ((sliderName[0] == '{') && (sliderName[1] == 'C') && (sliderName[2] == '}')) sliderName += 3;
289
                                                }
289
                                                }
290
                                                strcpy(gdata->parm.szCtl[i], sliderName);
290
                                                strcpy(gdata->parm.szCtl[i], sliderName);
291
                                                free(val);
291
                                                free(val);
292
                                                gdata->parm.ctl_used[i] = (bool32_t)*((byte*)q);
292
                                                gdata->parm.ctl_used[i] = (bool32_t)*((byte*)q);
293
                                                q += sizeof(byte);
293
                                                q += sizeof(byte);
294
                                                gdata->parm.val[i] = *((uint32_t*)q);
294
                                                gdata->parm.val[i] = *((uint32_t*)q);
295
                                                slider[i] = *((uint32_t*)q);
295
                                                slider[i] = *((uint32_t*)q);
296
                                                q += sizeof(uint32_t);
296
                                                q += sizeof(uint32_t);
297
                                        }
297
                                        }
298
 
298
 
299
                                        // Maps (are not part of the format!)
299
                                        // Maps (are not part of the format!)
300
                                        strcpy(gdata->parm.szMap[0], "Map 0:");
300
                                        strcpy(gdata->parm.szMap[0], "Map 0:");
301
                                        strcpy(gdata->parm.szMap[1], "Map 1:");
301
                                        strcpy(gdata->parm.szMap[1], "Map 1:");
302
                                        strcpy(gdata->parm.szMap[2], "Map 2:");
302
                                        strcpy(gdata->parm.szMap[2], "Map 2:");
303
                                        strcpy(gdata->parm.szMap[3], "Map 3:");
303
                                        strcpy(gdata->parm.szMap[3], "Map 3:");
304
 
304
 
305
                                        res = true;
305
                                        res = true;
306
                                }
306
                                }
307
                        }
307
                        }
308
                        PIDISPOSEHANDLE(h);
308
                        PIDISPOSEHANDLE(h);
309
                }
309
                }
310
                FSClose(refnum);
310
                FSClose(refnum);
311
        }
311
        }
312
 
312
 
313
        if (res) gdata->obfusc = false;
313
        if (res) gdata->obfusc = false;
314
        return res;
314
        return res;
315
}
315
}
316
 
316
 
317
Boolean readfile_8bf(StandardFileReply *sfr,char **reason){
317
Boolean readfile_8bf(StandardFileReply *sfr,char **reason){
318
        unsigned char magic[2];
318
        unsigned char magic[2];
319
        FILECOUNT count;
319
        FILECOUNT count;
320
        Handle h;
320
        Handle h;
321
        Boolean res = false;
321
        Boolean res = false;
322
        FILEREF refnum;
322
        FILEREF refnum;
323
 
323
 
324
        if(FSpOpenDF(&sfr->sfFile,fsRdPerm,&refnum) == noErr){
324
        if(FSpOpenDF(&sfr->sfFile,fsRdPerm,&refnum) == noErr){
325
                // check DOS EXE magic number
325
                // check DOS EXE magic number
326
                count = 2;
326
                count = 2;
327
                if(FSRead(refnum,&count,magic) == noErr /*&& magic[0]=='M' && magic[1]=='Z'*/){
327
                if(FSRead(refnum,&count,magic) == noErr /*&& magic[0]=='M' && magic[1]=='Z'*/){
328
                        if(GetEOF(refnum,(FILEPOS*)&count) == noErr && count < 4096L<<10){ // sanity check file size < 4MiB (note that "Debug" builds can have approx 700 KiB while "Release" builds have approx 300 KiB)
328
                        if(GetEOF(refnum,(FILEPOS*)&count) == noErr && count < 4096L<<10){ // sanity check file size < 4MiB (note that "Debug" builds can have approx 700 KiB while "Release" builds have approx 300 KiB)
329
                                if( (h = readfileintohandle(refnum)) ){
329
                                if( (h = readfileintohandle(refnum)) ){
330
                                        long *q = (long*)PILOCKHANDLE(h,false);
330
                                        long *q = (long*)PILOCKHANDLE(h,false);
331
 
331
 
332
                                        // look for signature at start of valid PARM resource
332
                                        // look for signature at start of valid PARM resource
333
                                        // This signature is observed in Filter Factory standalones.
333
                                        // This signature is observed in Filter Factory standalones.
334
                                        for( count /= 4 ; count >= PARM_SIZE/4 ; --count, ++q )
334
                                        for( count /= 4 ; count >= PARM_SIZE/4 ; --count, ++q )
335
                                        {
335
                                        {
336
                                                res = readPARM(&gdata->parm, (Ptr)q);
336
                                                res = readPARM(&gdata->parm, (Ptr)q);
337
                                                if (res) break;
337
                                                if (res) break;
338
                                        }
338
                                        }
339
 
339
 
340
                                        PIDISPOSEHANDLE(h);
340
                                        PIDISPOSEHANDLE(h);
341
                                }
341
                                }
342
                        }
342
                        }
343
                } // else no point in proceeding
343
                } // else no point in proceeding
344
                FSClose(refnum);
344
                FSClose(refnum);
345
        }else
345
        }else
346
                *reason = _strdup("Could not open file.");
346
                *reason = _strdup("Could not open file.");
347
 
347
 
348
        if (res) gdata->obfusc = false;
348
        if (res) gdata->obfusc = false;
349
        return res;
349
        return res;
350
}
350
}
351
 
351
 
352
Boolean readPARM(PARM_T* pparm, Ptr p){
352
Boolean readPARM(PARM_T* pparm, Ptr p){
353
        int i;
353
        int i;
354
        Boolean towin, tomac, fromwin, frommac;
354
        Boolean towin, tomac, fromwin, frommac;
355
        unsigned int signature = *((unsigned int*)p);
355
        unsigned int signature = *((unsigned int*)p);
356
        unsigned int standalone = *((unsigned int*)p+1);
356
        unsigned int standalone = *((unsigned int*)p+1);
357
 
357
 
358
        // Find out our OS ("reader") the OS of the plugin ("source")
358
        // Find out our OS ("reader") the OS of the plugin ("source")
359
        #ifdef MAC_ENV
359
        #ifdef MAC_ENV
360
        towin = false;
360
        towin = false;
361
        tomac = true;
361
        tomac = true;
362
        fromwin = ((EndianS32_LtoN(signature) == PARM_SIZE) ||
362
        fromwin = ((EndianS32_LtoN(signature) == PARM_SIZE) ||
363
                (EndianS32_LtoN(signature) == PARM_SIZE_PREMIERE) ||
363
                (EndianS32_LtoN(signature) == PARM_SIZE_PREMIERE) ||
364
                (EndianS32_LtoN(signature) == PARM_SIG_MAC)) && EndianS32_LtoN(standalone) == 1;
364
                (EndianS32_LtoN(signature) == PARM_SIG_MAC)) && EndianS32_LtoN(standalone) == 1;
365
        frommac = ((signature == PARM_SIZE) ||
365
        frommac = ((signature == PARM_SIZE) ||
366
                (signature == PARM_SIZE_PREMIERE) ||
366
                (signature == PARM_SIZE_PREMIERE) ||
367
                (signature == PARM_SIG_MAC)) && standalone == 1;
367
                (signature == PARM_SIG_MAC)) && standalone == 1;
368
        #else
368
        #else
369
        towin = true;
369
        towin = true;
370
        tomac = false;
370
        tomac = false;
371
        fromwin = ((signature == PARM_SIZE) ||
371
        fromwin = ((signature == PARM_SIZE) ||
372
                (signature == PARM_SIZE_PREMIERE) ||
372
                (signature == PARM_SIZE_PREMIERE) ||
373
                (signature == PARM_SIG_MAC)) && standalone == 1;
373
                (signature == PARM_SIG_MAC)) && standalone == 1;
374
        frommac = ((EndianS32_LtoN(signature) == PARM_SIZE) ||
374
        frommac = ((EndianS32_LtoN(signature) == PARM_SIZE) ||
375
                (EndianS32_LtoN(signature) == PARM_SIZE_PREMIERE) ||
375
                (EndianS32_LtoN(signature) == PARM_SIZE_PREMIERE) ||
376
                (EndianS32_LtoN(signature) == PARM_SIG_MAC)) && EndianS32_LtoN(standalone) == 1;
376
                (EndianS32_LtoN(signature) == PARM_SIG_MAC)) && EndianS32_LtoN(standalone) == 1;
377
        #endif
377
        #endif
378
 
378
 
379
        // Is it a valid signature?
379
        // Is it a valid signature?
380
        if (!fromwin && !frommac) {
380
        if (!fromwin && !frommac) {
381
                // No valid signature found
381
                // No valid signature found
382
                return false;
382
                return false;
383
        }
383
        }
384
 
384
 
385
        // Does it come from Premiere or Photoshop?
385
        // Does it come from Premiere or Photoshop?
386
        // Initialize pparm
386
        // Initialize pparm
387
        if ((signature == PARM_SIZE_PREMIERE) || (EndianS32_LtoN(signature) == PARM_SIZE_PREMIERE)) {
387
        if ((signature == PARM_SIZE_PREMIERE) || (EndianS32_LtoN(signature) == PARM_SIZE_PREMIERE)) {
388
                // It comes from Premiere. Swap R and B channel and convert to a Photoshop PARM_T
388
                // It comes from Premiere. Swap R and B channel and convert to a Photoshop PARM_T
389
                convert_premiere_to_photoshop(pparm, (PARM_T_PREMIERE*)p);
389
                convert_premiere_to_photoshop(pparm, (PARM_T_PREMIERE*)p);
390
        } else {
390
        } else {
391
                // It is already Photoshop. Just copy to pparm.
391
                // It is already Photoshop. Just copy to pparm.
392
                memcpy(pparm, p, sizeof(PARM_T));
392
                memcpy(pparm, p, sizeof(PARM_T));
393
        }
393
        }
394
 
394
 
395
        // Do we need to do string conversion?
395
        // Do we need to do string conversion?
396
        if (frommac) {
396
        if (frommac) {
397
                /* Mac PARM resource stores Pascal strings - convert to C strings, since this is what we work internally with (regardles of OS) */
397
                /* Mac PARM resource stores Pascal strings - convert to C strings, since this is what we work internally with (regardles of OS) */
398
                myp2cstr((unsigned char*)pparm->szCategory);
398
                myp2cstr((unsigned char*)pparm->szCategory);
399
                myp2cstr((unsigned char*)pparm->szTitle);
399
                myp2cstr((unsigned char*)pparm->szTitle);
400
                myp2cstr((unsigned char*)pparm->szCopyright);
400
                myp2cstr((unsigned char*)pparm->szCopyright);
401
                myp2cstr((unsigned char*)pparm->szAuthor);
401
                myp2cstr((unsigned char*)pparm->szAuthor);
402
                for (i = 0; i < 4; ++i)
402
                for (i = 0; i < 4; ++i)
403
                        myp2cstr((unsigned char*)pparm->szMap[i]);
403
                        myp2cstr((unsigned char*)pparm->szMap[i]);
404
                for (i = 0; i < 8; ++i)
404
                for (i = 0; i < 8; ++i)
405
                        myp2cstr((unsigned char*)pparm->szCtl[i]);
405
                        myp2cstr((unsigned char*)pparm->szCtl[i]);
406
        }
406
        }
407
 
407
 
408
        // Case #1: Mac is reading Windows (Win16/32/64) plugin
408
        // Case #1: Mac is reading Windows (Win16/32/64) plugin
409
        if (fromwin && tomac) {
409
        if (fromwin && tomac) {
410
                size_t i;
410
                size_t i;
411
 
411
 
412
                // Convert copyright CRLF to CR (actually, just removing LF)
412
                // Convert copyright CRLF to CR (actually, just removing LF)
413
                char copyrightCRLF[256];
413
                char copyrightCRLF[256];
414
                char* p = &copyrightCRLF[0];
414
                char* p = &copyrightCRLF[0];
415
                for (i = 0; i < strlen(pparm->szCopyright); i++) {
415
                for (i = 0; i < strlen(pparm->szCopyright); i++) {
416
                        if (pparm->szCopyright[i] != LF) {
416
                        if (pparm->szCopyright[i] != LF) {
417
                                *p++ = pparm->szCopyright[i];
417
                                *p++ = pparm->szCopyright[i];
418
                        }
418
                        }
419
                }
419
                }
420
                *p++ = '\0';
420
                *p++ = '\0';
421
                strcpy(pparm->szCopyright, copyrightCRLF);
421
                strcpy(pparm->szCopyright, copyrightCRLF);
422
 
422
 
423
                // these are the only numeric fields we *have* to swap
423
                // these are the only numeric fields we *have* to swap
424
                // all the rest are bool_t flags which (if we're careful) will work in either ordering
424
                // all the rest are bool_t flags which (if we're careful) will work in either ordering
425
                for (i = 0; i < 8; ++i)
425
                for (i = 0; i < 8; ++i)
426
                        pparm->val[i] = EndianS32_LtoN(pparm->val[i]);
426
                        pparm->val[i] = EndianS32_LtoN(pparm->val[i]);
427
        }
427
        }
428
 
428
 
429
        // Case #2: Mac is reading Mac (in case the normal resource extraction didn't work)
429
        // Case #2: Mac is reading Mac (in case the normal resource extraction didn't work)
430
        // Nothing to do
430
        // Nothing to do
431
 
431
 
432
        // Case #3: Windows is reading a Windows plugin (if Resource API failed, e.g. Win64 tries to open Win16 NE file or Win32 tries to open Win64 file)
432
        // Case #3: Windows is reading a Windows plugin (if Resource API failed, e.g. Win64 tries to open Win16 NE file or Win32 tries to open Win64 file)
433
        // Nothing to do
433
        // Nothing to do
434
 
434
 
435
        // Case #4: Windows is reading an old FilterFactory Mac file
435
        // Case #4: Windows is reading an old FilterFactory Mac file
436
        // Note: You must read the ".rsrc" resource fork, not the standalone binary!
436
        // Note: You must read the ".rsrc" resource fork, not the standalone binary!
437
        if (frommac && towin) {
437
        if (frommac && towin) {
438
                size_t i;
438
                size_t i;
439
 
439
 
440
                // Convert CR in the copyright field to CRLF.
440
                // Convert CR in the copyright field to CRLF.
441
                char copyrightCRLF[256];
441
                char copyrightCRLF[256];
442
                char* p = &copyrightCRLF[0];
442
                char* p = &copyrightCRLF[0];
443
                for (i = 0; i < strlen(pparm->szCopyright); i++) {
443
                for (i = 0; i < strlen(pparm->szCopyright); i++) {
444
                        *p++ = pparm->szCopyright[i];
444
                        *p++ = pparm->szCopyright[i];
445
                        if (pparm->szCopyright[i] == CR) {
445
                        if (pparm->szCopyright[i] == CR) {
446
                                *p++ = LF;
446
                                *p++ = LF;
447
                        }
447
                        }
448
                }
448
                }
449
                *p++ = '\0';
449
                *p++ = '\0';
450
                strcpy(pparm->szCopyright, copyrightCRLF);
450
                strcpy(pparm->szCopyright, copyrightCRLF);
451
 
451
 
452
                // these are the only numeric fields we *have* to swap
452
                // these are the only numeric fields we *have* to swap
453
                // all the rest are bool_t flags which (if we're careful) will work in either ordering
453
                // all the rest are bool_t flags which (if we're careful) will work in either ordering
454
                for (i = 0; i < 8; ++i)
454
                for (i = 0; i < 8; ++i)
455
                        pparm->val[i] = EndianS32_LtoN(pparm->val[i]);
455
                        pparm->val[i] = EndianS32_LtoN(pparm->val[i]);
456
        }
456
        }
457
 
457
 
458
        // Now set the values in pparm into the working variables expr[] and slider[], so that they are visible in the GUI
458
        // Now set the values in pparm into the working variables expr[] and slider[], so that they are visible in the GUI
459
 
459
 
460
        for(i = 0; i < 4; ++i){
460
        for(i = 0; i < 4; ++i){
461
                if(expr[i]) free(expr[i]);
461
                if(expr[i]) free(expr[i]);
462
                expr[i] = my_strdup(pparm->szFormula[i]);
462
                expr[i] = my_strdup(pparm->szFormula[i]);
463
        }
463
        }
464
 
464
 
465
        for (i = 0; i < 8; ++i) {
465
        for (i = 0; i < 8; ++i) {
466
                slider[i] = (uint8_t)pparm->val[i];
466
                slider[i] = (uint8_t)pparm->val[i];
467
                /*
467
                /*
468
                if (slider[i] > 0xFF) {
468
                if (slider[i] > 0xFF) {
469
                        // Wrong endianess (e.g. reading a Mac rsrc on Windows)
469
                        // Wrong endianess (e.g. reading a Mac rsrc on Windows)
470
                        // Should not happen since we did the stuff above
470
                        // Should not happen since we did the stuff above
471
                        slider[i] = (uint8_t)EndianS32_LtoN(slider[i]);
471
                        slider[i] = (uint8_t)EndianS32_LtoN(slider[i]);
472
                }
472
                }
473
                */
473
                */
474
        }
474
        }
475
 
475
 
476
        return true;
476
        return true;
477
}
477
}
478
 
478
 
479
Handle readfileintohandle(FILEREF r){
479
Handle readfileintohandle(FILEREF r){
480
        FILEPOS n;
480
        FILEPOS n;
481
        Handle h;
481
        Handle h;
482
        Ptr p;
482
        Ptr p;
483
 
483
 
484
        if( GetEOF(r,&n) == noErr && (h = PINEWHANDLE(n)) ){
484
        if( GetEOF(r,&n) == noErr && (h = PINEWHANDLE(n)) ){
485
                p = PILOCKHANDLE(h,false);
485
                p = PILOCKHANDLE(h,false);
486
                if(SetFPos(r,fsFromStart,0) == noErr && FSRead(r,(FILECOUNT*)&n,p) == noErr){
486
                if(SetFPos(r,fsFromStart,0) == noErr && FSRead(r,(FILECOUNT*)&n,p) == noErr){
487
                        PIUNLOCKHANDLE(h);
487
                        PIUNLOCKHANDLE(h);
488
                        return h;
488
                        return h;
489
                }
489
                }
490
                PIDISPOSEHANDLE(h);
490
                PIDISPOSEHANDLE(h);
491
        }
491
        }
492
        return NULL;
492
        return NULL;
493
}
493
}
494
 
494
 
495
Boolean _picoLineContainsKey(char* line, char** content, const char* searchkey/*=NULL*/) {
495
Boolean _picoLineContainsKey(char* line, char** content, const char* searchkey/*=NULL*/) {
496
        size_t i;
496
        size_t i;
497
        for (i = 0; i < strlen(line); i++) {
497
        for (i = 0; i < strlen(line); i++) {
498
                if (line[i] == '?') break; // avoid that "a?b:c" is detected as key
498
                if (line[i] == '?') break; // avoid that "a?b:c" is detected as key
499
                if (line[i] == ':') {
499
                if (line[i] == ':') {
500
                        // Note: We are ignoring whitespaces, i.e. " A :" != "A:" (TODO: should we change this?)
500
                        // Note: We are ignoring whitespaces, i.e. " A :" != "A:" (TODO: should we change this?)
501
                        if ((searchkey == NULL) || ((i == strlen(searchkey)) && (memcmp(line, searchkey, i) == 0))) {
501
                        if ((searchkey == NULL) || ((i == strlen(searchkey)) && (memcmp(line, searchkey, i) == 0))) {
502
                                i++; // jump over ':' char
502
                                i++; // jump over ':' char
503
                                //while ((line[i] == ' ') || (line[i] == TAB)) i++; // Trim value left
503
                                //while ((line[i] == ' ') || (line[i] == TAB)) i++; // Trim value left
504
                                *content = line + i;
504
                                *content = line + i;
505
                                return true;
505
                                return true;
506
                        }
506
                        }
507
                }
507
                }
508
        }
508
        }
509
        *content = line;
509
        *content = line;
510
        return false;
510
        return false;
511
}
511
}
512
 
512
 
513
void _ffdcomp_removebrackets(char* x, char* maxptr) {
513
void _ffdcomp_removebrackets(char* x, char* maxptr) {
514
        char* closingBracketPos = NULL;
514
        char* closingBracketPos = NULL;
515
        Boolean openingBracketFound = false;
515
        Boolean openingBracketFound = false;
516
        if (x[0] == '[') {
516
        if (x[0] == '[') {
517
                openingBracketFound = true;
517
                openingBracketFound = true;
518
        }
518
        }
519
        x[0] = ':';
519
        x[0] = ':';
520
        x++;
520
        x++;
521
        while (x < maxptr) {
521
        while (x < maxptr) {
522
                if ((!openingBracketFound) && (x[0] == '[')) {
522
                if ((!openingBracketFound) && (x[0] == '[')) {
523
                        openingBracketFound = true;
523
                        openingBracketFound = true;
524
                        x[0] = ' ';
524
                        x[0] = ' ';
525
                }
525
                }
526
                else if (openingBracketFound) {
526
                else if (openingBracketFound) {
527
                        if (x[0] == ']') {
527
                        if (x[0] == ']') {
528
                                closingBracketPos = x;
528
                                closingBracketPos = x;
529
                        }
529
                        }
530
                        else if ((x[0] == CR) || (x[0] == LF)) {
530
                        else if ((x[0] == CR) || (x[0] == LF)) {
531
                                if (closingBracketPos) closingBracketPos[0] = ' '; // last closing pos before CR/LF
531
                                if (closingBracketPos) closingBracketPos[0] = ' '; // last closing pos before CR/LF
532
                                break;
532
                                break;
533
                        }
533
                        }
534
                }
534
                }
535
                x++;
535
                x++;
536
        }
536
        }
537
}
537
}
538
 
538
 
539
// isFormula=false => outputFile is C string. TXT linebreaks become spaces.
539
// isFormula=false => outputFile is C string. TXT linebreaks become spaces.
540
// isFormula=true  => outputFile is C string. TXT line breaks become CRLF line breaks
540
// isFormula=true  => outputFile is C string. TXT line breaks become CRLF line breaks
541
Boolean _picoReadProperty(char* inputFile, int maxInput, const char* property, char* outputFile, size_t maxOutput, Boolean isFormula) {
541
Boolean _picoReadProperty(char* inputFile, int maxInput, const char* property, char* outputFile, size_t maxOutput, Boolean isFormula) {
542
        int i;
542
        int i;
543
        char* outputwork;
543
        char* outputwork;
544
        char* sline;
544
        char* sline;
545
        char* svalue;
545
        char* svalue;
546
        char* inputwork;
546
        char* inputwork;
547
        char* inputworkinitial;
547
        char* inputworkinitial;
548
        outputwork = outputFile;
548
        outputwork = outputFile;
549
        sline = NULL;
549
        sline = NULL;
550
        svalue = NULL;
550
        svalue = NULL;
551
        // Check parameters
551
        // Check parameters
552
        if (maxOutput == 0) return false;
552
        if (maxOutput == 0) return false;
553
        if (inputFile == 0) return false;
553
        if (inputFile == 0) return false;
554
        // Let input memory be read-only, +1 for terminal zero
554
        // Let input memory be read-only, +1 for terminal zero
555
        //char* inputwork = inputFile;
555
        //char* inputwork = inputFile;
556
        inputwork = (char*)malloc(maxInput + 1);
556
        inputwork = (char*)malloc(maxInput + 1);
557
        inputworkinitial = inputwork;
557
        inputworkinitial = inputwork;
558
        if (inputwork == 0) return false;
558
        if (inputwork == 0) return false;
559
        memcpy(inputwork, inputFile, maxInput);
559
        memcpy(inputwork, inputFile, maxInput);
560
        inputwork[maxInput] = 0; // otherwise strstr() will crash
560
        inputwork[maxInput] = 0; // otherwise strstr() will crash
561
 
561
 
562
        // Transform "FFDecomp" TXT file into the similar "PluginCommander" TXT file
562
        // Transform "FFDecomp" TXT file into the similar "PluginCommander" TXT file
563
        if (strstr(inputwork, "Filter Factory Plugin Information:")) {
563
        if (strstr(inputwork, "Filter Factory Plugin Information:")) {
564
                char* x;
564
                char* x;
565
                char* k1;
565
                char* k1;
566
                char* k2;
566
                char* k2;
567
                // Metadata:
567
                // Metadata:
568
                x = strstr(inputwork, "CATEGORY:");
568
                x = strstr(inputwork, "CATEGORY:");
569
                if (x) memcpy(x, "Category:", strlen("Category:"));
569
                if (x) memcpy(x, "Category:", strlen("Category:"));
570
                x = strstr(inputwork, "TITLE:");
570
                x = strstr(inputwork, "TITLE:");
571
                if (x) memcpy(x, "Title:", strlen("Title:"));
571
                if (x) memcpy(x, "Title:", strlen("Title:"));
572
                x = strstr(inputwork, "COPYRIGHT:");
572
                x = strstr(inputwork, "COPYRIGHT:");
573
                if (x) memcpy(x, "Copyright:", strlen("Copyright:"));
573
                if (x) memcpy(x, "Copyright:", strlen("Copyright:"));
574
                x = strstr(inputwork, "AUTHOR:");
574
                x = strstr(inputwork, "AUTHOR:");
575
                if (x) memcpy(x, "Author:", strlen("Author:"));
575
                if (x) memcpy(x, "Author:", strlen("Author:"));
576
                // Controls:
576
                // Controls:
577
                for (i = 0; i < 8; i++) {
577
                for (i = 0; i < 8; i++) {
578
                        k1 = (char*)malloc(strlen("Control X:") + 1);
578
                        k1 = (char*)malloc(strlen("Control X:") + 1);
579
                        sprintf(k1, "Control %d:", i);
579
                        sprintf(k1, "Control %d:", i);
580
                        x = strstr(inputwork, k1);
580
                        x = strstr(inputwork, k1);
581
                        if (x) {
581
                        if (x) {
582
                                k2 = (char*)malloc(strlen("ctl[X]:   ") + 1);
582
                                k2 = (char*)malloc(strlen("ctl[X]:   ") + 1);
583
                                sprintf(k2, "ctl[%d]:   ", i);
583
                                sprintf(k2, "ctl[%d]:   ", i);
584
                                memcpy(x, k2, strlen(k2));
584
                                memcpy(x, k2, strlen(k2));
585
                                x += strlen("ctl[X]");
585
                                x += strlen("ctl[X]");
586
                                _ffdcomp_removebrackets(x, inputwork + maxInput - 1);
586
                                _ffdcomp_removebrackets(x, inputwork + maxInput - 1);
587
                                free(k2);
587
                                free(k2);
588
                        }
588
                        }
589
                        free(k1);
589
                        free(k1);
590
                }
590
                }
591
                // Maps:
591
                // Maps:
592
                for (i = 0; i < 4; i++) {
592
                for (i = 0; i < 4; i++) {
593
                        k1 = (char*)malloc(strlen("Map X:") + 1);
593
                        k1 = (char*)malloc(strlen("Map X:") + 1);
594
                        sprintf(k1, "Map %d:", i);
594
                        sprintf(k1, "Map %d:", i);
595
                        x = strstr(inputwork, k1);
595
                        x = strstr(inputwork, k1);
596
                        if (x) {
596
                        if (x) {
597
                                k2 = (char*)malloc(strlen("map[X]:") + 1);
597
                                k2 = (char*)malloc(strlen("map[X]:") + 1);
598
                                sprintf(k2, "map[%d]:", i);
598
                                sprintf(k2, "map[%d]:", i);
599
                                memcpy(x, k2, strlen(k2));
599
                                memcpy(x, k2, strlen(k2));
600
                                x += strlen("map[X]");
600
                                x += strlen("map[X]");
601
                                _ffdcomp_removebrackets(x, inputwork + maxInput - 1);
601
                                _ffdcomp_removebrackets(x, inputwork + maxInput - 1);
602
                                free(k2);
602
                                free(k2);
603
                        }
603
                        }
604
                        free(k1);
604
                        free(k1);
605
                }
605
                }
606
                // Convert all '\r' to '\n' for the next step to be easier
606
                // Convert all '\r' to '\n' for the next step to be easier
607
                for (i = 0; i < maxInput; i++) {
607
                for (i = 0; i < maxInput; i++) {
608
                        if (inputworkinitial[i] == CR) inputworkinitial[i] = LF;
608
                        if (inputworkinitial[i] == CR) inputworkinitial[i] = LF;
609
                }
609
                }
610
                x = strstr(inputwork, "\nR=\n");
610
                x = strstr(inputwork, "\nR=\n");
611
                if (x) memcpy(x, "\nR:\n", strlen("\nR:\n"));
611
                if (x) memcpy(x, "\nR:\n", strlen("\nR:\n"));
612
                x = strstr(inputwork, "\nG=\n");
612
                x = strstr(inputwork, "\nG=\n");
613
                if (x) memcpy(x, "\nG:\n", strlen("\nG:\n"));
613
                if (x) memcpy(x, "\nG:\n", strlen("\nG:\n"));
614
                x = strstr(inputwork, "\nB=\n");
614
                x = strstr(inputwork, "\nB=\n");
615
                if (x) memcpy(x, "\nB:\n", strlen("\nB:\n"));
615
                if (x) memcpy(x, "\nB:\n", strlen("\nB:\n"));
616
                x = strstr(inputwork, "\nA=\n");
616
                x = strstr(inputwork, "\nA=\n");
617
                if (x) memcpy(x, "\nA:\n", strlen("\nA:\n"));
617
                if (x) memcpy(x, "\nA:\n", strlen("\nA:\n"));
618
        }
618
        }
619
        // Replace all \r and \n with \0, so that we can parse easier
619
        // Replace all \r and \n with \0, so that we can parse easier
620
        for (i = 0; i < maxInput; i++) {
620
        for (i = 0; i < maxInput; i++) {
621
                if (inputworkinitial[i] == CR) inputworkinitial[i] = 0;
621
                if (inputworkinitial[i] == CR) inputworkinitial[i] = 0;
622
                else if (inputworkinitial[i] == LF) inputworkinitial[i] = 0;
622
                else if (inputworkinitial[i] == LF) inputworkinitial[i] = 0;
623
        }
623
        }
624
 
624
 
625
        // Find line that contains out key
625
        // Find line that contains out key
626
        inputwork = inputworkinitial;
626
        inputwork = inputworkinitial;
627
        do {
627
        do {
628
                if (inputwork > inputworkinitial + maxInput) {
628
                if (inputwork > inputworkinitial + maxInput) {
629
                        // Key not found. Set output to empty string
629
                        // Key not found. Set output to empty string
630
                        outputwork[0] = 0;
630
                        outputwork[0] = 0;
631
                        free(inputworkinitial);
631
                        free(inputworkinitial);
632
                        return false;
632
                        return false;
633
                }
633
                }
634
                sline = inputwork;
634
                sline = inputwork;
635
                inputwork += strlen(sline) + 1;
635
                inputwork += strlen(sline) + 1;
636
                if (inputwork - 1 > inputworkinitial + maxInput) {
636
                if (inputwork - 1 > inputworkinitial + maxInput) {
637
                        // Key not found. Set output to empty string
637
                        // Key not found. Set output to empty string
638
                        // TODO: will that be ever called?
638
                        // TODO: will that be ever called?
639
                        outputwork[0] = 0;
639
                        outputwork[0] = 0;
640
                        free(inputworkinitial);
640
                        free(inputworkinitial);
641
                        return false;
641
                        return false;
642
                }
642
                }
643
        } while (!_picoLineContainsKey(sline, &svalue, property));
643
        } while (!_picoLineContainsKey(sline, &svalue, property));
644
 
644
 
645
        // Read line(s) until we find a line with another key, or the line end
645
        // Read line(s) until we find a line with another key, or the line end
646
        do {
646
        do {
647
                while ((svalue[0] == ' ') || (svalue[0] == TAB)) svalue++; // Trim left
647
                while ((svalue[0] == ' ') || (svalue[0] == TAB)) svalue++; // Trim left
648
                while ((svalue[strlen(svalue) - 1] == ' ') || (svalue[strlen(svalue) - 1] == TAB)) svalue[strlen(svalue) - 1] = 0; // Trim right
648
                while ((svalue[strlen(svalue) - 1] == ' ') || (svalue[strlen(svalue) - 1] == TAB)) svalue[strlen(svalue) - 1] = 0; // Trim right
649
 
649
 
650
                if (strlen(svalue) > 0) {
650
                if (strlen(svalue) > 0) {
651
                        if (outputwork + strlen(svalue) + (isFormula ? 3/*CRLF+NUL*/ : 2/*space+NUL*/) > outputFile + maxOutput) {
651
                        if (outputwork + strlen(svalue) + (isFormula ? 3/*CRLF+NUL*/ : 2/*space+NUL*/) > outputFile + maxOutput) {
652
                                int remaining = maxOutput - (outputwork - outputFile) - 1;
652
                                size_t remaining = maxOutput - (outputwork - outputFile) - 1;
653
                                //printf("BUFFER FULL (remaining = %d)\n", remaining);
653
                                //printf("BUFFER FULL (remaining = %d)\n", remaining);
654
                                memcpy(outputwork, svalue, remaining);
654
                                memcpy(outputwork, svalue, remaining);
655
                                outputwork += remaining;
655
                                outputwork += remaining;
656
                                outputwork[0] = 0;
656
                                outputwork[0] = 0;
657
                                free(inputworkinitial);
657
                                free(inputworkinitial);
658
                                return true;
658
                                return true;
659
                        }
659
                        }
660
                        else {
660
                        else {
661
                                memcpy(outputwork, svalue, strlen(svalue));
661
                                memcpy(outputwork, svalue, strlen(svalue));
662
                                outputwork += strlen(svalue);
662
                                outputwork += strlen(svalue);
663
                                if (isFormula) {
663
                                if (isFormula) {
664
                                        // Formulas: TXT line break stays line break (important if you have comments!)
664
                                        // Formulas: TXT line break stays line break (important if you have comments!)
665
                                        outputwork[0] = CR;
665
                                        outputwork[0] = CR;
666
                                        outputwork[1] = LF;
666
                                        outputwork[1] = LF;
667
                                        outputwork += 2;
667
                                        outputwork += 2;
668
                                }
668
                                }
669
                                else {
669
                                else {
670
                                        // Everything else: TXT line breaks becomes single whitespace
670
                                        // Everything else: TXT line breaks becomes single whitespace
671
                                        outputwork[0] = ' ';
671
                                        outputwork[0] = ' ';
672
                                        outputwork++;
672
                                        outputwork++;
673
                                }
673
                                }
674
                        }
674
                        }
675
                }
675
                }
676
                outputwork[0] = 0;
676
                outputwork[0] = 0;
677
 
677
 
678
                // Process next line
678
                // Process next line
679
                if (inputwork > inputworkinitial + maxInput) break;
679
                if (inputwork > inputworkinitial + maxInput) break;
680
                sline = inputwork;
680
                sline = inputwork;
681
                inputwork += strlen(sline) + 1;
681
                inputwork += strlen(sline) + 1;
682
                if (inputwork - 1 > inputworkinitial + maxInput) break; // TODO: will that be ever called?
682
                if (inputwork - 1 > inputworkinitial + maxInput) break; // TODO: will that be ever called?
683
        } while (!_picoLineContainsKey(sline, &svalue, NULL));
683
        } while (!_picoLineContainsKey(sline, &svalue, NULL));
684
 
684
 
685
        // Remove trailing whitespace
685
        // Remove trailing whitespace
686
        if (outputwork > outputFile) {
686
        if (outputwork > outputFile) {
687
                outputwork -= 1;
687
                outputwork -= 1;
688
                outputwork[0] = 0;
688
                outputwork[0] = 0;
689
        }
689
        }
690
        free(inputworkinitial);
690
        free(inputworkinitial);
691
        return true;
691
        return true;
692
}
692
}
693
 
693
 
694
Boolean readfile_picotxt(StandardFileReply* sfr, char** reason) {
694
Boolean readfile_picotxt(StandardFileReply* sfr, char** reason) {
695
        extern int ctls[], maps[];
695
        extern int ctls[], maps[];
696
 
696
 
697
        Handle h;
697
        Handle h;
698
        Boolean res = false;
698
        Boolean res = false;
699
        FILEREF refnum;
699
        FILEREF refnum;
700
 
700
 
701
        UNREFERENCED_PARAMETER(reason);
701
        UNREFERENCED_PARAMETER(reason);
702
 
702
 
703
        if (!fileHasExtension(sfr, ".txt")) return false;
703
        if (!fileHasExtension(sfr, TEXT(".txt"))) return false;
704
 
704
 
705
        if (FSpOpenDF(&sfr->sfFile, fsRdPerm, &refnum) == noErr) {
705
        if (FSpOpenDF(&sfr->sfFile, fsRdPerm, &refnum) == noErr) {
706
                if ((h = readfileintohandle(refnum))) {
706
                if ((h = readfileintohandle(refnum))) {
707
                        FILECOUNT count = PIGETHANDLESIZE(h);
707
                        FILECOUNT count = PIGETHANDLESIZE(h);
708
                        char* q = PILOCKHANDLE(h, false);
708
                        char* q = PILOCKHANDLE(h, false);
709
 
709
 
710
                        char out[256];
710
                        char out[256];
711
                        if (_picoReadProperty(q, count, "Title", out, sizeof(out), false)) {
711
                        if (_picoReadProperty(q, count, "Title", out, sizeof(out), false)) {
712
                                int i;
712
                                int i;
713
 
713
 
714
                                // Plugin infos
714
                                // Plugin infos
715
                                _picoReadProperty(q, count, "Title", gdata->parm.szTitle, sizeof(gdata->parm.szTitle), false);
715
                                _picoReadProperty(q, count, "Title", gdata->parm.szTitle, sizeof(gdata->parm.szTitle), false);
716
                                _picoReadProperty(q, count, "Category", gdata->parm.szCategory, sizeof(gdata->parm.szCategory), false);
716
                                _picoReadProperty(q, count, "Category", gdata->parm.szCategory, sizeof(gdata->parm.szCategory), false);
717
                                _picoReadProperty(q, count, "Author", gdata->parm.szAuthor, sizeof(gdata->parm.szAuthor), false);
717
                                _picoReadProperty(q, count, "Author", gdata->parm.szAuthor, sizeof(gdata->parm.szAuthor), false);
718
                                _picoReadProperty(q, count, "Copyright", gdata->parm.szCopyright, sizeof(gdata->parm.szCopyright), false);
718
                                _picoReadProperty(q, count, "Copyright", gdata->parm.szCopyright, sizeof(gdata->parm.szCopyright), false);
719
                                //_picoReadProperty(q, count, "Filename", gdata->parm.xxx, sizeof(gdata->parm.xxx), false);
719
                                //_picoReadProperty(q, count, "Filename", gdata->parm.xxx, sizeof(gdata->parm.xxx), false);
720
 
720
 
721
                                // Expressions
721
                                // Expressions
722
                                if (!_picoReadProperty(q, count, "R", gdata->parm.szFormula[0], sizeof(gdata->parm.szFormula[0]), true))
722
                                if (!_picoReadProperty(q, count, "R", gdata->parm.szFormula[0], sizeof(gdata->parm.szFormula[0]), true))
723
                                        strcpy(gdata->parm.szFormula[0], "r");
723
                                        strcpy(gdata->parm.szFormula[0], "r");
724
                                if (!_picoReadProperty(q, count, "G", gdata->parm.szFormula[1], sizeof(gdata->parm.szFormula[1]), true))
724
                                if (!_picoReadProperty(q, count, "G", gdata->parm.szFormula[1], sizeof(gdata->parm.szFormula[1]), true))
725
                                        strcpy(gdata->parm.szFormula[1], "g");
725
                                        strcpy(gdata->parm.szFormula[1], "g");
726
                                if (!_picoReadProperty(q, count, "B", gdata->parm.szFormula[2], sizeof(gdata->parm.szFormula[2]), true))
726
                                if (!_picoReadProperty(q, count, "B", gdata->parm.szFormula[2], sizeof(gdata->parm.szFormula[2]), true))
727
                                        strcpy(gdata->parm.szFormula[2], "b");
727
                                        strcpy(gdata->parm.szFormula[2], "b");
728
                                if (!_picoReadProperty(q, count, "A", gdata->parm.szFormula[3], sizeof(gdata->parm.szFormula[3]), true))
728
                                if (!_picoReadProperty(q, count, "A", gdata->parm.szFormula[3], sizeof(gdata->parm.szFormula[3]), true))
729
                                        strcpy(gdata->parm.szFormula[3], "a");
729
                                        strcpy(gdata->parm.szFormula[3], "a");
730
                                for (i = 0; i < 4; i++) {
730
                                for (i = 0; i < 4; i++) {
731
                                        if (expr[i]) free(expr[i]);
731
                                        if (expr[i]) free(expr[i]);
732
                                        expr[i] = my_strdup(gdata->parm.szFormula[i]);
732
                                        expr[i] = my_strdup(gdata->parm.szFormula[i]);
733
                                }
733
                                }
734
 
734
 
735
                                // Slider names
735
                                // Slider names
736
                                for (i = 0; i < 8; i++) {
736
                                for (i = 0; i < 8; i++) {
737
                                        char keyname[7];
737
                                        char keyname[7];
738
                                        sprintf(keyname, "ctl[%d]", i);
738
                                        sprintf(keyname, "ctl[%d]", i);
739
                                        _picoReadProperty(q, count, keyname, gdata->parm.szCtl[i], sizeof(gdata->parm.szCtl[i]), false);
739
                                        _picoReadProperty(q, count, keyname, gdata->parm.szCtl[i], sizeof(gdata->parm.szCtl[i]), false);
740
                                }
740
                                }
741
 
741
 
742
                                // Slider values
742
                                // Slider values
743
                                for (i = 0; i < 8; i++) {
743
                                for (i = 0; i < 8; i++) {
744
                                        char keyname[7], tmp[5];
744
                                        char keyname[7], tmp[5];
745
                                        sprintf(keyname, "val[%d]", i);
745
                                        sprintf(keyname, "val[%d]", i);
746
                                        if (!_picoReadProperty(q, count, keyname, tmp, sizeof(tmp), false)) {
746
                                        if (!_picoReadProperty(q, count, keyname, tmp, sizeof(tmp), false)) {
747
                                                sprintf(keyname, "def[%d]", i);
747
                                                sprintf(keyname, "def[%d]", i);
748
                                                if (!_picoReadProperty(q, count, keyname, tmp, sizeof(tmp), false)) {
748
                                                if (!_picoReadProperty(q, count, keyname, tmp, sizeof(tmp), false)) {
749
                                                        strcpy(tmp,"0");
749
                                                        strcpy(tmp,"0");
750
                                                }
750
                                                }
751
                                        }
751
                                        }
752
                                        gdata->parm.val[i] = slider[i] = atoi(tmp);
752
                                        gdata->parm.val[i] = slider[i] = atoi(tmp);
753
                                }
753
                                }
754
 
754
 
755
                                // Map names
755
                                // Map names
756
                                for (i = 0; i < 4; i++) {
756
                                for (i = 0; i < 4; i++) {
757
                                        char keyname[7];
757
                                        char keyname[7];
758
                                        sprintf(keyname, "map[%d]", i);
758
                                        sprintf(keyname, "map[%d]", i);
759
                                        _picoReadProperty(q, count, keyname, gdata->parm.szMap[i], sizeof(gdata->parm.szMap[i]), false);
759
                                        _picoReadProperty(q, count, keyname, gdata->parm.szMap[i], sizeof(gdata->parm.szMap[i]), false);
760
                                }
760
                                }
761
 
761
 
762
                                //These will be set when the expressions are evaluated anyway. So this part is optional:
762
                                //These will be set when the expressions are evaluated anyway. So this part is optional:
763
                                checksliders(4, ctls, maps);
763
                                checksliders(4, ctls, maps);
764
                                for (i = 0; i < 8; i++) gdata->parm.ctl_used[i] = ctls[i];
764
                                for (i = 0; i < 8; i++) gdata->parm.ctl_used[i] = ctls[i];
765
                                for (i = 0; i < 4; i++) gdata->parm.map_used[i] = maps[i];
765
                                for (i = 0; i < 4; i++) gdata->parm.map_used[i] = maps[i];
766
 
766
 
767
                                res = true;
767
                                res = true;
768
                        }
768
                        }
769
 
769
 
770
                        PIUNLOCKHANDLE(h);
770
                        PIUNLOCKHANDLE(h);
771
                        PIDISPOSEHANDLE(h);
771
                        PIDISPOSEHANDLE(h);
772
                }
772
                }
773
                FSClose(refnum);
773
                FSClose(refnum);
774
        }
774
        }
775
 
775
 
776
        return res;
776
        return res;
777
}
777
}
778
 
778
 
779
Boolean readfile_afs_pff(StandardFileReply *sfr,char **reason){
779
Boolean readfile_afs_pff(StandardFileReply *sfr,char **reason){
780
        FILEREF r;
780
        FILEREF r;
781
        Handle h;
781
        Handle h;
782
        Boolean res = false;
782
        Boolean res = false;
783
 
783
 
784
        if(FSpOpenDF(&sfr->sfFile,fsRdPerm,&r) == noErr){
784
        if(FSpOpenDF(&sfr->sfFile,fsRdPerm,&r) == noErr){
785
                if( (h = readfileintohandle(r)) ){
785
                if( (h = readfileintohandle(r)) ){
786
                        if( (res = readparams_afs_pff(h,reason)) ) {
786
                        if( (res = readparams_afs_pff(h,reason)) ) {
787
                                gdata->standalone = false; // so metadata fields will default, if user chooses Make...
787
                                gdata->standalone = false; // so metadata fields will default, if user chooses Make...
788
 
788
 
789
                                if (fileHasExtension(sfr, ".pff")) {
789
                                if (fileHasExtension(sfr, TEXT(".pff"))) {
790
                                        // If it is a Premiere settings file, we need to swap the channels red and blue
790
                                        // If it is a Premiere settings file, we need to swap the channels red and blue
791
                                        // We just swap the pointers!
791
                                        // We just swap the pointers!
792
                                        char* tmp;
792
                                        char* tmp;
793
                                        tmp = expr[0];
793
                                        tmp = expr[0];
794
                                        expr[0] = expr[2];
794
                                        expr[0] = expr[2];
795
                                        expr[2] = tmp;
795
                                        expr[2] = tmp;
796
                                }
796
                                }
797
                        }
797
                        }
798
 
798
 
799
                        PIDISPOSEHANDLE(h);
799
                        PIDISPOSEHANDLE(h);
800
                }
800
                }
801
                FSClose(r);
801
                FSClose(r);
802
        }else
802
        }else
803
                *reason = _strdup("Could not open the file.");
803
                *reason = _strdup("Could not open the file.");
804
 
804
 
805
        return res;
805
        return res;
806
}
806
}
807
 
807