Rev 274 | Rev 308 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 274 | Rev 301 | ||
---|---|---|---|
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(Handle h,Boolean alerts,char **reason){ |
41 | Boolean readparams(Handle h,Boolean alerts,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 EOL convention) */ |
65 | /* look ahead to see if we need to skip a line feed (DOS EOL convention) */ |
66 | if(c == CR && *p == LF && p < dataend) |
66 | if(c == CR && *p == LF && p < dataend) |
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 | if(alerts) |
74 | if(alerts) |
75 | *reason = _strdup("This doesn't look like a Filter Factory file (first line is not \"%RGB-1.0\")."); |
75 | *reason = _strdup("This doesn't look like a Filter Factory file (first line is not \"%RGB-1.0\")."); |
76 | break; |
76 | break; |
77 | } |
77 | } |
78 | }else if(linecnt<=8){ |
78 | }else if(linecnt<=8){ |
79 | slider[linecnt-1] = atoi(linebuf); |
79 | slider[linecnt-1] = atoi(linebuf); |
80 | }else{ |
80 | }else{ |
81 | if(lineptr){ |
81 | if(lineptr){ |
82 | /* it's not an empty line; append it to current expr string */ |
82 | /* it's not an empty line; append it to current expr string */ |
83 | if( q+lineptr > curexpr+MAXEXPR ){ |
83 | if( q+lineptr > curexpr+MAXEXPR ){ |
84 | *reason = _strdup("Found an expression longer than 1024 characters."); |
84 | *reason = _strdup("Found an expression longer than 1024 characters."); |
85 | break; |
85 | break; |
86 | } |
86 | } |
87 | q = cat(q,linebuf); |
87 | q = cat(q,linebuf); |
88 | }else{ |
88 | }else{ |
89 | /* it's an empty line: we've completed the expr string */ |
89 | /* it's an empty line: we've completed the expr string */ |
90 | if(expr[exprcnt]) |
90 | if(expr[exprcnt]) |
91 | free(expr[exprcnt]); |
91 | free(expr[exprcnt]); |
92 | *q = 0; |
92 | *q = 0; |
93 | if(!(expr[exprcnt] = my_strdup(curexpr))){ |
93 | if(!(expr[exprcnt] = my_strdup(curexpr))){ |
94 | *reason = _strdup("Could not get memory for expression."); |
94 | *reason = _strdup("Could not get memory for expression."); |
95 | break; |
95 | break; |
96 | } |
96 | } |
97 | 97 | ||
98 | if(++exprcnt == 4){ |
98 | if(++exprcnt == 4){ |
99 | res = true; |
99 | res = true; |
100 | break; /* got everything we want */ |
100 | break; /* got everything we want */ |
101 | } |
101 | } |
102 | 102 | ||
103 | q = curexpr; /* empty current expr, ready for next one */ |
103 | q = curexpr; /* empty current expr, ready for next one */ |
104 | } |
104 | } |
105 | } |
105 | } |
106 | 106 | ||
107 | ++linecnt; |
107 | ++linecnt; |
108 | lineptr = 0; |
108 | lineptr = 0; |
109 | }else{ |
109 | }else{ |
110 | /* store character */ |
110 | /* store character */ |
111 | if(c=='\\'){ /* escape sequence */ |
111 | if(c=='\\'){ /* escape sequence */ |
112 | if(p < dataend){ |
112 | if(p < dataend){ |
113 | c = *p++; |
113 | c = *p++; |
114 | switch(c){ |
114 | switch(c){ |
115 | case 'r': |
115 | case 'r': |
116 | #if WIN_ENV |
116 | #if WIN_ENV |
117 | c = CR; |
117 | c = CR; |
118 | if (lineptr < MAXLINE) |
118 | if (lineptr < MAXLINE) |
119 | linebuf[lineptr++] = c; |
119 | linebuf[lineptr++] = c; |
120 | c = LF; |
120 | c = LF; |
121 | #else |
121 | #else |
122 | c = CR; |
122 | c = CR; |
123 | #endif |
123 | #endif |
124 | break; |
124 | break; |
125 | case '\\': break; |
125 | case '\\': break; |
126 | default: |
126 | default: |
127 | if(alerts) alertuser(_strdup("Warning:"),_strdup("Unknown escape sequence in input.")); |
127 | if(alerts) alertuser(_strdup("Warning:"),_strdup("Unknown escape sequence in input.")); |
128 | } |
128 | } |
129 | }//else if(alerts) alertuser(_strdup("Warning:"),_strdup("truncated escape sequence ends input")); |
129 | }//else if(alerts) alertuser(_strdup("Warning:"),_strdup("truncated escape sequence ends input")); |
130 | } |
130 | } |
131 | 131 | ||
132 | if(lineptr < MAXLINE) |
132 | if(lineptr < MAXLINE) |
133 | linebuf[lineptr++] = c; |
133 | linebuf[lineptr++] = c; |
134 | } |
134 | } |
135 | } |
135 | } |
136 | 136 | ||
137 | PIUNLOCKHANDLE(h); |
137 | PIUNLOCKHANDLE(h); |
138 | 138 | ||
139 | if (res) *reason = NULL; // no error |
139 | if (res) *reason = NULL; // no error |
140 | return res; |
140 | return res; |
141 | } |
141 | } |
142 | 142 | ||
143 | void convert_premiere_to_photoshop(PARM_T* photoshop, PARM_T_PREMIERE* premiere) { |
143 | void convert_premiere_to_photoshop(PARM_T* photoshop, PARM_T_PREMIERE* premiere) { |
144 | int i; |
144 | int i; |
145 | 145 | ||
146 | photoshop->cbSize = sizeof(PARM_T); |
146 | photoshop->cbSize = sizeof(PARM_T); |
147 | photoshop->standalone = premiere->standalone; |
147 | photoshop->standalone = premiere->standalone; |
148 | for (i=0;i<8;++i) |
148 | for (i=0;i<8;++i) |
149 | photoshop->val[i] = premiere->val[i]; |
149 | photoshop->val[i] = premiere->val[i]; |
150 | photoshop->popDialog = premiere->popDialog; |
150 | photoshop->popDialog = premiere->popDialog; |
151 | photoshop->unknown1 = premiere->unknown1; |
151 | photoshop->unknown1 = premiere->unknown1; |
152 | photoshop->unknown2 = premiere->unknown2; |
152 | photoshop->unknown2 = premiere->unknown2; |
153 | photoshop->unknown3 = premiere->unknown3; |
153 | photoshop->unknown3 = premiere->unknown3; |
154 | for (i=0;i<4;++i) |
154 | for (i=0;i<4;++i) |
155 | photoshop->map_used[i] = premiere->map_used[i]; |
155 | photoshop->map_used[i] = premiere->map_used[i]; |
156 | for (i=0;i<8;++i) |
156 | for (i=0;i<8;++i) |
157 | photoshop->ctl_used[i] = premiere->ctl_used[i]; |
157 | photoshop->ctl_used[i] = premiere->ctl_used[i]; |
158 | sprintf((char*)photoshop->category, "Filter Factory"); // Premiere plugins do not have a category attribute |
158 | sprintf((char*)photoshop->category, "Filter Factory"); // Premiere plugins do not have a category attribute |
159 | photoshop->iProtected = 0; // Premiere plugins do not have a protect flag |
159 | photoshop->iProtected = 0; // Premiere plugins do not have a protect flag |
160 | memcpy((void*)photoshop->title, (void*)premiere->title, sizeof(photoshop->title)); |
160 | memcpy((void*)photoshop->title, (void*)premiere->title, sizeof(photoshop->title)); |
161 | memcpy((void*)photoshop->copyright, (void*)premiere->copyright, sizeof(photoshop->copyright)); |
161 | memcpy((void*)photoshop->copyright, (void*)premiere->copyright, sizeof(photoshop->copyright)); |
162 | memcpy((void*)photoshop->author, (void*)premiere->author, sizeof(photoshop->author)); |
162 | memcpy((void*)photoshop->author, (void*)premiere->author, sizeof(photoshop->author)); |
163 | for (i=0;i<4;++i) |
163 | for (i=0;i<4;++i) |
164 | memcpy((void*)photoshop->map[i], (void*)premiere->map[i], sizeof(photoshop->map[i])); |
164 | memcpy((void*)photoshop->map[i], (void*)premiere->map[i], sizeof(photoshop->map[i])); |
165 | for (i=0;i<8;++i) |
165 | for (i=0;i<8;++i) |
166 | memcpy((void*)photoshop->ctl[i], (void*)premiere->ctl[i], sizeof(photoshop->ctl[i])); |
166 | memcpy((void*)photoshop->ctl[i], (void*)premiere->ctl[i], sizeof(photoshop->ctl[i])); |
167 | 167 | ||
168 | if (premiere->singleExpression) { |
168 | if (premiere->singleExpression) { |
169 | memcpy((void*)photoshop->formula[0], (void*)premiere->formula[3], sizeof(photoshop->formula[3])); |
169 | memcpy((void*)photoshop->formula[0], (void*)premiere->formula[3], sizeof(photoshop->formula[3])); |
170 | memcpy((void*)photoshop->formula[1], (void*)premiere->formula[3], sizeof(photoshop->formula[3])); |
170 | memcpy((void*)photoshop->formula[1], (void*)premiere->formula[3], sizeof(photoshop->formula[3])); |
171 | memcpy((void*)photoshop->formula[2], (void*)premiere->formula[3], sizeof(photoshop->formula[3])); |
171 | memcpy((void*)photoshop->formula[2], (void*)premiere->formula[3], sizeof(photoshop->formula[3])); |
172 | memcpy((void*)photoshop->formula[3], (void*)premiere->formula[3], sizeof(photoshop->formula[3])); |
172 | memcpy((void*)photoshop->formula[3], (void*)premiere->formula[3], sizeof(photoshop->formula[3])); |
173 | } else { |
173 | } else { |
174 | memcpy((void*)photoshop->formula[0], (void*)premiere->formula[2], sizeof(photoshop->formula[2])); |
174 | memcpy((void*)photoshop->formula[0], (void*)premiere->formula[2], sizeof(photoshop->formula[2])); |
175 | memcpy((void*)photoshop->formula[1], (void*)premiere->formula[1], sizeof(photoshop->formula[1])); |
175 | memcpy((void*)photoshop->formula[1], (void*)premiere->formula[1], sizeof(photoshop->formula[1])); |
176 | memcpy((void*)photoshop->formula[2], (void*)premiere->formula[0], sizeof(photoshop->formula[0])); |
176 | memcpy((void*)photoshop->formula[2], (void*)premiere->formula[0], sizeof(photoshop->formula[0])); |
177 | memcpy((void*)photoshop->formula[3], (void*)premiere->formula[3], sizeof(photoshop->formula[3])); |
177 | memcpy((void*)photoshop->formula[3], (void*)premiere->formula[3], sizeof(photoshop->formula[3])); |
178 | } |
178 | } |
179 | } |
179 | } |
180 | 180 | ||
181 | Boolean read8bfplugin(StandardFileReply *sfr,char **reason){ |
181 | Boolean read8bfplugin(StandardFileReply *sfr,char **reason){ |
182 | unsigned char magic[2]; |
182 | unsigned char magic[2]; |
183 | FILECOUNT count; |
183 | FILECOUNT count; |
184 | Handle h; |
184 | Handle h; |
185 | Boolean res = false; |
185 | Boolean res = false; |
186 | FILEREF refnum; |
186 | FILEREF refnum; |
187 | int i; |
187 | int i; |
188 | 188 | ||
189 | if(FSpOpenDF(&sfr->sfFile,fsRdPerm,&refnum) == noErr){ |
189 | if(FSpOpenDF(&sfr->sfFile,fsRdPerm,&refnum) == noErr){ |
190 | // check DOS EXE magic number |
190 | // check DOS EXE magic number |
191 | count = 2; |
191 | count = 2; |
192 | if(FSRead(refnum,&count,magic) == noErr /*&& magic[0]=='M' && magic[1]=='Z'*/){ |
192 | if(FSRead(refnum,&count,magic) == noErr /*&& magic[0]=='M' && magic[1]=='Z'*/){ |
193 | if(GetEOF(refnum,(FILEPOS*)&count) == noErr && count < 2048L<<10){ // sanity check file size < 2MiB (note that "Debug" builds can have approx 700 KiB while "Release" builds have approx 300 KiB) |
193 | if(GetEOF(refnum,(FILEPOS*)&count) == noErr && count < 2048L<<10){ // sanity check file size < 2MiB (note that "Debug" builds can have approx 700 KiB while "Release" builds have approx 300 KiB) |
194 | if( (h = readfileintohandle(refnum)) ){ |
194 | if( (h = readfileintohandle(refnum)) ){ |
195 | long *q = (long*)PILOCKHANDLE(h,false); |
195 | long *q = (long*)PILOCKHANDLE(h,false); |
196 | 196 | ||
197 | // look for signature at start of valid PARM resource |
197 | // look for signature at start of valid PARM resource |
198 | // This signature is observed in Filter Factory standalones. |
198 | // This signature is observed in Filter Factory standalones. |
199 | for( count /= 4 ; count >= PARM_SIZE/4 ; --count, ++q ) |
199 | for( count /= 4 ; count >= PARM_SIZE/4 ; --count, ++q ) |
200 | { |
200 | { |
201 | 201 | ||
202 | #ifdef MAC_ENV |
202 | #ifdef MAC_ENV |
203 | // Case #1: Mac is reading Windows (Win16/32/64) plugin |
203 | // Case #1: Mac is reading Windows (Win16/32/64) plugin |
204 | if( ((EndianS32_LtoN(q[0]) == PARM_SIZE) || |
204 | if( ((EndianS32_LtoN(q[0]) == PARM_SIZE) || |
205 | (EndianS32_LtoN(q[0]) == PARM_SIZE_PREMIERE) || |
205 | (EndianS32_LtoN(q[0]) == PARM_SIZE_PREMIERE) || |
206 | (EndianS32_LtoN(q[0]) == PARM_SIG_MAC)) && EndianS32_LtoN(q[1]) == 1 |
206 | (EndianS32_LtoN(q[0]) == PARM_SIG_MAC)) && EndianS32_LtoN(q[1]) == 1 |
207 | && (res = readPARM((char*)q, &gdata->parm, reason, 1 /*Windows format resource*/)) ) |
207 | && (res = readPARM((char*)q, &gdata->parm, reason, 1 /*Windows format resource*/)) ) |
208 | { |
208 | { |
209 | // these are the only numeric fields we *have* to swap |
209 | // these are the only numeric fields we *have* to swap |
210 | // all the rest are flags which (if we're careful) will work in either ordering |
210 | // all the rest are flags which (if we're careful) will work in either ordering |
211 | for(i = 0; i < 8; ++i) |
211 | for(i = 0; i < 8; ++i) |
212 | slider[i] = EndianS32_LtoN(slider[i]); |
212 | slider[i] = EndianS32_LtoN(slider[i]); |
213 | } |
213 | } |
214 | #else |
214 | #else |
215 | // Case #2: Windows is reading a Windows plugin (if Resource API failed, e.g. Win64 tries to open NE file, Win32 tries to open 64bit file) |
215 | // Case #2: Windows is reading a Windows plugin (if Resource API failed, e.g. Win64 tries to open NE file, Win32 tries to open 64bit file) |
216 | if( ((q[0] == PARM_SIZE) || |
216 | if( ((q[0] == PARM_SIZE) || |
217 | (q[0] == PARM_SIZE_PREMIERE) || |
217 | (q[0] == PARM_SIZE_PREMIERE) || |
218 | (q[0] == PARM_SIG_MAC)) && q[1] == 1 |
218 | (q[0] == PARM_SIG_MAC)) && q[1] == 1 |
219 | && (res = readPARM((char*)q, &gdata->parm, reason, 1)) ) |
219 | && (res = readPARM((char*)q, &gdata->parm, reason, 1)) ) |
220 | { |
220 | { |
221 | } |
221 | } |
222 | 222 | ||
223 | // Case #3: Windows is reading an old FilterFactory Mac file (.bin) |
223 | // Case #3: Windows is reading an old FilterFactory Mac file (.bin) |
224 | else if( ((EndianS32_LtoN(q[0]) == PARM_SIZE) || |
224 | else if( ((EndianS32_LtoN(q[0]) == PARM_SIZE) || |
225 | (EndianS32_LtoN(q[0]) == PARM_SIZE_PREMIERE) || |
225 | (EndianS32_LtoN(q[0]) == PARM_SIZE_PREMIERE) || |
226 | (EndianS32_LtoN(q[0]) == PARM_SIG_MAC)) && EndianS32_LtoN(q[1]) == 1 |
226 | (EndianS32_LtoN(q[0]) == PARM_SIG_MAC)) && EndianS32_LtoN(q[1]) == 1 |
227 | && (res = readPARM((char*)q, &gdata->parm, reason, 0 /*Strings are already PStrings*/)) ) |
227 | && (res = readPARM((char*)q, &gdata->parm, reason, 0 /*Strings are already PStrings*/)) ) |
228 | { |
228 | { |
229 | // these are the only numeric fields we *have* to swap |
229 | // these are the only numeric fields we *have* to swap |
230 | // all the rest are flags which (if we're careful) will work in either ordering |
230 | // all the rest are flags which (if we're careful) will work in either ordering |
231 | for(i = 0; i < 8; ++i) |
231 | for(i = 0; i < 8; ++i) |
232 | slider[i] = EndianS32_LtoN(slider[i]); |
232 | slider[i] = EndianS32_LtoN(slider[i]); |
233 | } |
233 | } |
234 | #endif |
234 | #endif |
235 | 235 | ||
236 | if (res) break; |
236 | if (res) break; |
237 | } |
237 | } |
238 | PIDISPOSEHANDLE(h); |
238 | PIDISPOSEHANDLE(h); |
239 | } |
239 | } |
240 | } |
240 | } |
241 | } // else no point in proceeding |
241 | } // else no point in proceeding |
242 | FSClose(refnum); |
242 | FSClose(refnum); |
243 | }else |
243 | }else |
244 | *reason = _strdup("Could not open file."); |
244 | *reason = _strdup("Could not open file."); |
245 | 245 | ||
246 | if (res) gdata->obfusc = false; |
246 | if (res) gdata->obfusc = false; |
247 | return res; |
247 | return res; |
248 | } |
248 | } |
249 | 249 | ||
250 | Boolean readPARM(Ptr p,PARM_T *pparm,char **reasonstr,int fromwin){ |
250 | Boolean readPARM(Ptr p,PARM_T *pparm,char **reasonstr,int fromwin){ |
251 | int i; |
251 | int i; |
252 | 252 | ||
253 | if (*((unsigned int*)p) == PARM_SIZE_PREMIERE) { |
253 | if (*((unsigned int*)p) == PARM_SIZE_PREMIERE) { |
254 | convert_premiere_to_photoshop(pparm, (PARM_T_PREMIERE*)p); |
254 | convert_premiere_to_photoshop(pparm, (PARM_T_PREMIERE*)p); |
255 | } else { |
255 | } else { |
256 | // Assume it is Photoshop. Signature either PARM_SIZE (0x2068) or 0x1C68 |
256 | // Assume it is Photoshop. Signature either PARM_SIZE (0x2068) or 0x1C68 |
257 | memcpy(pparm,p,sizeof(PARM_T)); |
257 | memcpy(pparm,p,sizeof(PARM_T)); |
258 | } |
258 | } |
259 | 259 | ||
260 | if(fromwin){ |
260 | if(fromwin){ |
261 | /* Windows PARM resource stores C strings - convert to Pascal strings */ |
261 | /* Windows PARM resource stores C strings - convert to Pascal strings */ |
262 | myc2pstr((char*)pparm->category); |
262 | myc2pstr((char*)pparm->category); |
263 | myc2pstr((char*)pparm->title); |
263 | myc2pstr((char*)pparm->title); |
264 | myc2pstr((char*)pparm->copyright); |
264 | myc2pstr((char*)pparm->copyright); |
265 | myc2pstr((char*)pparm->author); |
265 | myc2pstr((char*)pparm->author); |
266 | for(i = 0; i < 4; ++i) |
266 | for(i = 0; i < 4; ++i) |
267 | myc2pstr((char*)pparm->map[i]); |
267 | myc2pstr((char*)pparm->map[i]); |
268 | for(i = 0; i < 8; ++i) |
268 | for(i = 0; i < 8; ++i) |
269 | myc2pstr((char*)pparm->ctl[i]); |
269 | myc2pstr((char*)pparm->ctl[i]); |
270 | } |
270 | } |
271 | 271 | ||
272 | for(i = 0; i < 4; ++i){ |
272 | for(i = 0; i < 4; ++i){ |
273 | if(expr[i]) free(expr[i]); |
273 | if(expr[i]) free(expr[i]); |
274 | expr[i] = my_strdup(pparm->formula[i]); |
274 | expr[i] = my_strdup(pparm->formula[i]); |
275 | } |
275 | } |
276 | 276 | ||
277 | for(i = 0; i < 8; ++i) |
277 | for(i = 0; i < 8; ++i) |
278 | slider[i] = pparm->val[i]; |
278 | slider[i] = (uint8_t)pparm->val[i]; |
279 | 279 | ||
280 | return true; |
280 | return true; |
281 | } |
281 | } |
282 | 282 | ||
283 | Handle readfileintohandle(FILEREF r){ |
283 | Handle readfileintohandle(FILEREF r){ |
284 | FILEPOS n; |
284 | FILEPOS n; |
285 | Handle h; |
285 | Handle h; |
286 | Ptr p; |
286 | Ptr p; |
287 | 287 | ||
288 | if( GetEOF(r,&n) == noErr && (h = PINEWHANDLE(n)) ){ |
288 | if( GetEOF(r,&n) == noErr && (h = PINEWHANDLE(n)) ){ |
289 | p = PILOCKHANDLE(h,false); |
289 | p = PILOCKHANDLE(h,false); |
290 | if(SetFPos(r,fsFromStart,0) == noErr && FSRead(r,(FILECOUNT*)&n,p) == noErr){ |
290 | if(SetFPos(r,fsFromStart,0) == noErr && FSRead(r,(FILECOUNT*)&n,p) == noErr){ |
291 | PIUNLOCKHANDLE(h); |
291 | PIUNLOCKHANDLE(h); |
292 | return h; |
292 | return h; |
293 | } |
293 | } |
294 | PIDISPOSEHANDLE(h); |
294 | PIDISPOSEHANDLE(h); |
295 | } |
295 | } |
296 | return NULL; |
296 | return NULL; |
297 | } |
297 | } |
298 | 298 | ||
299 | Boolean fileHasExtension(StandardFileReply *sfr, const char* extension) { |
299 | Boolean fileHasExtension(StandardFileReply *sfr, const char* extension) { |
300 | #ifdef WIN_ENV |
300 | #ifdef WIN_ENV |
301 | 301 | ||
302 | char name[MAX_PATH+1]; |
302 | char name[MAX_PATH+1]; |
303 | return sfr->nFileExtension && !strcasecmp(myp2cstrcpy(name,sfr->sfFile.name) + sfr->nFileExtension - 1,extension); |
303 | return sfr->nFileExtension && !strcasecmp(myp2cstrcpy(name,sfr->sfFile.name) + sfr->nFileExtension - 1,extension); |
304 | 304 | ||
305 | #else |
305 | #else |
306 | 306 | ||
307 | char name[1025]; // https://stackoverflow.com/questions/1295135/longest-pathname-string-in-mac-os-x-hfs |
307 | char name[1025]; // https://stackoverflow.com/questions/1295135/longest-pathname-string-in-mac-os-x-hfs |
308 | char* s = myp2cstrcpy(name,sfr->sfFile.name); |
308 | char* s = myp2cstrcpy(name,sfr->sfFile.name); |
309 | return strcmp(s + strlen(s) - strlen(extension), extension) == 0; |
309 | return strcmp(s + strlen(s) - strlen(extension), extension) == 0; |
310 | 310 | ||
311 | #endif |
311 | #endif |
312 | } |
312 | } |
313 | 313 | ||
314 | Boolean readfile(StandardFileReply *sfr,char **reason){ |
314 | Boolean readfile(StandardFileReply *sfr,char **reason){ |
315 | FILEREF r; |
315 | FILEREF r; |
316 | Handle h; |
316 | Handle h; |
317 | Boolean res = false; |
317 | Boolean res = false; |
318 | 318 | ||
319 | if(FSpOpenDF(&sfr->sfFile,fsRdPerm,&r) == noErr){ |
319 | if(FSpOpenDF(&sfr->sfFile,fsRdPerm,&r) == noErr){ |
320 | if( (h = readfileintohandle(r)) ){ |
320 | if( (h = readfileintohandle(r)) ){ |
321 | if( (res = readparams(h,true,reason)) ) { |
321 | if( (res = readparams(h,true,reason)) ) { |
322 | gdata->standalone = false; // so metadata fields will default, if user chooses Make... |
322 | gdata->standalone = false; // so metadata fields will default, if user chooses Make... |
323 | 323 | ||
324 | if (fileHasExtension(sfr, ".pff")) { |
324 | if (fileHasExtension(sfr, ".pff")) { |
325 | // If it is a Premiere settings file, we need to swap the channels red and blue |
325 | // If it is a Premiere settings file, we need to swap the channels red and blue |
326 | // We just swap the pointers! |
326 | // We just swap the pointers! |
327 | char* tmp; |
327 | char* tmp; |
328 | tmp = expr[0]; |
328 | tmp = expr[0]; |
329 | expr[0] = expr[2]; |
329 | expr[0] = expr[2]; |
330 | expr[2] = tmp; |
330 | expr[2] = tmp; |
331 | } |
331 | } |
332 | } |
332 | } |
333 | 333 | ||
334 | PIDISPOSEHANDLE(h); |
334 | PIDISPOSEHANDLE(h); |
335 | } |
335 | } |
336 | FSClose(r); |
336 | FSClose(r); |
337 | }else |
337 | }else |
338 | *reason = _strdup("Could not open the file."); |
338 | *reason = _strdup("Could not open the file."); |
339 | 339 | ||
340 | return res; |
340 | return res; |
341 | } |
341 | } |
342 | 342 |