Subversion Repositories filter_foundry

Rev

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

Rev Author Line No. Line
2 toby 1
/*
18 toby 2
    This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
85 toby 3
    Copyright (C) 2003-7 Toby Thain, toby@telegraphics.com.au
2 toby 4
 
5
    This program is free software; you can redistribute it and/or modify
131 dmarschall 6
    it under the terms of the GNU General Public License as published by
2 toby 7
    the Free Software Foundation; either version 2 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14
 
131 dmarschall 15
    You should have received a copy of the GNU General Public License
2 toby 16
    along with this program; if not, write to the Free Software
17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
*/
19
 
20
#include "ff.h"
21
 
22
#include "file_compat.h"
23
 
149 dmarschall 24
#ifdef MAC_ENV
25
#include <Endian.h>
26
#endif
27
 
2 toby 28
enum{
85 toby 29
        BUFSIZE = 4L<<10,
2 toby 30
        MAXLINE = 0x200,
31
};
32
 
33
Boolean readparams(Handle h,Boolean alerts,char **reason){
34
        Boolean res = false;
35
        char linebuf[MAXLINE+1],curexpr[MAXEXPR+1],*p,*dataend,*q;
36
        int c,linecnt,lineptr,exprcnt;
37
 
15 toby 38
        if(!h){
39
                *reason = "readparams: Null parameter handle.";
40
                return false;
41
        }
42
 
2 toby 43
        p = PILOCKHANDLE(h,false);
44
        dataend = p + PIGETHANDLESIZE(h);
131 dmarschall 45
 
2 toby 46
        q = curexpr;
47
        linecnt = exprcnt = lineptr = 0;
48
 
49
        *reason = "File was too short.";
85 toby 50
        while(p < dataend){
2 toby 51
 
52
                c = *p++;
53
 
54
                if(c==CR || c==LF){ /* detected end of line */
131 dmarschall 55
 
2 toby 56
                        /* look ahead to see if we need to skip a line feed (DOS EOL convention) */
131 dmarschall 57
                        if(c == CR && *p == LF && p < dataend)
2 toby 58
                                ++p;
131 dmarschall 59
 
2 toby 60
                        linebuf[lineptr] = 0; /* add terminating NUL to line buffer */
61
 
62
                        /* process complete line */
63
                        if(linecnt==0){
64
                                if(strcmp(linebuf,"%RGB-1.0")){
65
                                        if(alerts)
85 toby 66
                                                *reason = "This doesn't look like a Filter Factory file (first line is not \"%RGB-1.0\").";
2 toby 67
                                        break;
68
                                }
69
                        }else if(linecnt<=8){
70
                                slider[linecnt-1] = atoi(linebuf);
71
                        }else{
131 dmarschall 72
                                if(lineptr){
2 toby 73
                                        /* it's not an empty line; append it to current expr string */
74
                                        if( q+lineptr > curexpr+MAXEXPR ){
85 toby 75
                                                *reason = "Found an expression longer than 1024 characters.";
2 toby 76
                                                break;
77
                                        }
78
                                        q = cat(q,linebuf);
79
                                }else{
80
                                        /* it's an empty line: we've completed the expr string */
131 dmarschall 81
                                        if(expr[exprcnt])
2 toby 82
                                                free(expr[exprcnt]);
83
                                        *q = 0;
84
                                        if(!(expr[exprcnt] = my_strdup(curexpr))){
85 toby 85
                                                *reason = "Could not get memory for expression.";
2 toby 86
                                                break;
87
                                        }
88
 
89
                                        if(++exprcnt == 4){
90
                                                res = true;
91
                                                break; /* got everything we want */
92
                                        }
93
 
94
                                        q = curexpr; /* empty current expr, ready for next one */
95
                                }
96
                        }
131 dmarschall 97
 
2 toby 98
                        ++linecnt;
99
                        lineptr = 0;
100
                }else{
101
                        /* store character */
102
                        if(c=='\\'){ /* escape sequence */
103
                                if(p < dataend){
104
                                        c = *p++;
105
                                        switch(c){
106
                                        case 'r': c = CR;
107
                                        case '\\': break;
131 dmarschall 108
                                        default:
2 toby 109
                                                if(alerts) alertuser("Warning:","Unknown escape sequence in input.");
110
                                        }
131 dmarschall 111
                                }//else if(alerts) alertuser("Warning:","truncated escape sequence ends input");
2 toby 112
                        }
113
 
114
                        if(lineptr < MAXLINE)
115
                                linebuf[lineptr++] = c;
116
                }
117
        }
131 dmarschall 118
 
2 toby 119
        PIUNLOCKHANDLE(h);
120
 
121
        return res;
122
}
123
 
145 dmarschall 124
void convert_premiere_to_photoshop(PARM_T* photoshop, PARM_T_PREMIERE* premiere) {
125
        int i;
126
 
127
        photoshop->cbSize = sizeof(PARM_T);
128
        photoshop->standalone = premiere->standalone;
129
        for (i=0;i<8;++i)
130
          photoshop->val[i] = premiere->val[i];
131
        photoshop->popDialog = premiere->popDialog;
132
        photoshop->unknown1 = premiere->unknown1;
133
        photoshop->unknown2 = premiere->unknown2;
134
        photoshop->unknown3 = premiere->unknown3;
135
        for (i=0;i<4;++i)
136
          photoshop->map_used[i] = premiere->map_used[i];
137
        for (i=0;i<8;++i)
138
          photoshop->ctl_used[i] = premiere->ctl_used[i];
139
        memcpy((void*)photoshop->category, (void*)premiere->category, sizeof(photoshop->category));
140
        photoshop->iProtected = premiere->iProtected;
146 dmarschall 141
        memcpy((void*)photoshop->title, (void*)premiere->title, sizeof(photoshop->title));
142
        memcpy((void*)photoshop->copyright, (void*)premiere->copyright, sizeof(photoshop->copyright));
143
        memcpy((void*)photoshop->author, (void*)premiere->author, sizeof(photoshop->author));
145 dmarschall 144
        for (i=0;i<4;++i)
145
          memcpy((void*)photoshop->map[i], (void*)premiere->map[i], sizeof(photoshop->map[i]));
146
        for (i=0;i<8;++i)
147
          memcpy((void*)photoshop->ctl[i], (void*)premiere->ctl[i], sizeof(photoshop->ctl[i]));
148
 
149
        if (premiere->singleExpression) {
150
                memcpy((void*)photoshop->formula[0], (void*)premiere->formula[3], sizeof(photoshop->formula[3]));
151
                memcpy((void*)photoshop->formula[1], (void*)premiere->formula[3], sizeof(photoshop->formula[3]));
152
                memcpy((void*)photoshop->formula[2], (void*)premiere->formula[3], sizeof(photoshop->formula[3]));
146 dmarschall 153
                memcpy((void*)photoshop->formula[3], (void*)premiere->formula[3], sizeof(photoshop->formula[3]));
145 dmarschall 154
        } else {
155
                memcpy((void*)photoshop->formula[0], (void*)premiere->formula[2], sizeof(photoshop->formula[2]));
156
                memcpy((void*)photoshop->formula[1], (void*)premiere->formula[1], sizeof(photoshop->formula[1]));
157
                memcpy((void*)photoshop->formula[2], (void*)premiere->formula[0], sizeof(photoshop->formula[0]));
158
                memcpy((void*)photoshop->formula[3], (void*)premiere->formula[3], sizeof(photoshop->formula[3]));
159
        }
160
}
161
 
149 dmarschall 162
Boolean read8bfplugin(StandardFileReply *sfr,char **reason){
163
        unsigned char magic[2];
164
        long count;
165
        Handle h;
166
        Boolean res = false;
167
        FILEREF refnum;
168
        int i;
169
 
170
        if(!FSpOpenDF(&sfr->sfFile,fsRdPerm,&refnum)){
171
                // check DOS EXE magic number
172
                count = 2;
173
                if(!FSRead(refnum,&count,magic) && magic[0]=='M' && magic[1]=='Z'){
174
                        if(!GetEOF(refnum,&count) && count < 256L<<10){ // sanity check file size < 256K
175
                                if( (h = readfileintohandle(refnum)) ){
176
                                        long *q = (long*)PILOCKHANDLE(h,false);
177
 
178
                                        // look for signature at start of valid PARM resource
179
                                        // This signature is observed in Filter Factory standalones.
180
                                        for( count /= 4 ; count >= PARM_SIZE/4 ; --count, ++q )
181
 
182
#ifdef MAC_ENV
183
                                                if( ((EndianS32_LtoN(q[0]) == PARM_SIZE) ||
184
                                                     (EndianS32_LtoN(q[0]) == PARM_SIZE_PREMIERE) ||
185
                                                     (EndianS32_LtoN(q[0]) == PARM_SIG_FOUNDRY_OLD)) && EndianS32_LtoN(q[1]) == 1
186
                                                        && (res = readPARM((char*)q, &gdata->parm, reason, 1 /*Windows format resource*/)) )
187
                                                {
188
                                                        // these are the only numeric fields we *have* to swap
189
                                                        // all the rest are flags which (if we're careful) will work in either ordering
190
                                                        for(i = 0; i < 8; ++i)
191
                                                                slider[i] = EndianS32_LtoN(slider[i]);
192
                                                }
193
#else
194
                                                if( ((q[0] == PARM_SIZE) ||
195
                                                     (q[0] == PARM_SIZE_PREMIERE) ||
196
                                                     (q[0] == PARM_SIG_FOUNDRY_OLD)) && q[1] == 1
197
                                                        && (res = readPARM((char*)q, &gdata->parm, reason, 1 /*Windows format resource*/)) )
198
                                                {
199
                                                }
200
#endif
201
 
202
                                        PIDISPOSEHANDLE(h);
203
                                }
204
                        }
205
                } // else no point in proceeding
206
                FSClose(refnum);
207
        }else
208
                *reason = "Could not open file.";
209
        return res;
210
}
211
 
45 toby 212
Boolean readPARM(Ptr p,PARM_T *pparm,char **reasonstr,int fromwin){
2 toby 213
        int i;
214
 
145 dmarschall 215
        if (*((unsigned int*)p) == PARM_SIZE_PREMIERE) {
216
                convert_premiere_to_photoshop(pparm, (PARM_T_PREMIERE*)p);
217
        } else {
218
                // Assume it is Photoshop. Signature either PARM_SIZE (0x2068) or 0x1C68
219
                memcpy(pparm,p,sizeof(PARM_T));
220
        }
2 toby 221
 
45 toby 222
        if(fromwin){
223
                /* Windows PARM resource stores C strings - convert to Pascal strings  */
224
                myc2pstr((char*)pparm->category);
225
                myc2pstr((char*)pparm->title);
226
                myc2pstr((char*)pparm->copyright);
227
                myc2pstr((char*)pparm->author);
85 toby 228
                for(i = 0; i < 4; ++i)
45 toby 229
                        myc2pstr((char*)pparm->map[i]);
85 toby 230
                for(i = 0; i < 8; ++i)
45 toby 231
                        myc2pstr((char*)pparm->ctl[i]);
232
        }
233
 
85 toby 234
        for(i = 0; i < 4; ++i){
2 toby 235
                if(expr[i]) free(expr[i]);
236
                expr[i] = my_strdup(pparm->formula[i]);
237
        }
238
 
85 toby 239
        for(i = 0; i < 8; ++i)
2 toby 240
                slider[i] = pparm->val[i];
241
 
45 toby 242
        return true;
2 toby 243
}
244
 
245
Handle readfileintohandle(FILEREF r){
246
        long n;
247
        Handle h;
248
        Ptr p;
249
 
250
        if( !GetEOF(r,&n) && (h = PINEWHANDLE(n)) ){
251
                p = PILOCKHANDLE(h,false);
45 toby 252
                if(!SetFPos(r,fsFromStart,0) && !FSRead(r,&n,p)){
2 toby 253
                        PIUNLOCKHANDLE(h);
254
                        return h;
255
                }
256
                PIDISPOSEHANDLE(h);
257
        }
258
        return NULL;
259
}
260
 
261
Boolean readfile(StandardFileReply *sfr,char **reason){
262
        FILEREF r;
263
        Handle h;
264
        Boolean res = false;
265
 
266
        if(!FSpOpenDF(&sfr->sfFile,fsRdPerm,&r)){
23 toby 267
                if( (h = readfileintohandle(r)) ){
268
                        if( (res = readparams(h,true,reason)) )
2 toby 269
                                gdata->standalone = false; // so metadata fields will default, if user chooses Make...
145 dmarschall 270
 
271
                        if (!strcasecmp((char*)sfr->sfFile.name + 1 + sfr->nFileExtension,"pff")) {
272
                                char* tmp;
273
                                tmp = my_strdup(expr[0]);
274
                                memcpy((void*)expr[0], (void*)expr[2], sizeof(expr[0]));
275
                                memcpy((void*)expr[2], (void*)tmp, sizeof(expr[2]));
276
                                free(tmp);
277
                        }
278
 
2 toby 279
                        PIDISPOSEHANDLE(h);
280
                }
281
                FSClose(r);
282
        }else
85 toby 283
                *reason = "Could not open the file.";
2 toby 284
 
285
        return res;
286
}