Subversion Repositories filter_foundry

Rev

Rev 85 | Rev 107 | 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
2 toby 3
    Copyright (C) 2003-5 Toby Thain, toby@telegraphics.com.au
4
 
5
    This program is free software; you can redistribute it and/or modify
106 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
 
106 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 <stddef.h>
21
 
22
#include "ff.h"
23
#include "symtab.h"
24
 
25
#include "PIActions.h"
26
 
27
#include "compat_string.h"
28
 
29
long event_id;
30
 
31
/*
32
Find a printable 4-character key, remembering (see PS API guide):
106 dmarschall 33
All IDŐs starting with an uppercase letter are reserved by Adobe.
2 toby 34
All IDŐs that are all uppercase are reserved by Apple.
35
All IDŐs that are all lowercase are reserved by Apple.
36
This leaves all IDŐs that begin with a lowercase letter and have at least
37
one uppercase letter for you and other plug-in developers.
38
*/
39
unsigned long printablehash(unsigned long hash){
48 toby 40
        unsigned long key = 'a' + (hash % 26);  hash /= 26; // first lower case
41
        key =   (key<<8) | (' ' + (hash % 95)); hash /= 95; // any printable
42
        key =   (key<<8) | (' ' + (hash % 95)); hash /= 95; // any printable
43
        return  (key<<8) | ('A' + (hash % 26));             // last upper case
2 toby 44
}
45
 
46
long fixpipl(PIPropertyList *pipl,long origsize,StringPtr title){
47
        PIProperty *prop;
23 toby 48
        char *p;
2 toby 49
        struct hstm_data{
50
                /* this structure must be 14+1 bytes long, to match PiPL structure */
51
                long version; /* = 0 */
52
                long class_id;
53
                long event_id;
54
                short aete_resid;
55
                char scope[1];
56
        };
57
        struct hstm_data *hstm;
58
        int scopelen;
59
        unsigned long hash;
60
 
61
        pipl->count += 3; // more keys in PiPL
62
 
23 toby 63
        p = (char*)pipl + origsize;
64
        prop = (PIProperty*)p;
2 toby 65
 
66
        /* add Title/Name property key */
106 dmarschall 67
 
2 toby 68
        prop->vendorID = kPhotoshopSignature;
69
        prop->propertyKey = PINameProperty;
70
        prop->propertyID = 0;
71
        prop->propertyLength = title[0]+1;
72
        PLstrcpy((StringPtr)prop->propertyData,title);
106 dmarschall 73
 
23 toby 74
        // skip past new property record, and any padding
75
        p += (offsetof(PIProperty,propertyData) + prop->propertyLength + 3) & -4;
76
        prop = (PIProperty*)p;
106 dmarschall 77
 
2 toby 78
        /* add Category property key */
106 dmarschall 79
 
2 toby 80
        prop->vendorID = kPhotoshopSignature;
81
        prop->propertyKey = PICategoryProperty;
82
        prop->propertyID = 0;
83
        prop->propertyLength = gdata->parm.category[0]+1;
84
        PLstrcpy((StringPtr)prop->propertyData,gdata->parm.category);
106 dmarschall 85
 
23 toby 86
        p += (offsetof(PIProperty,propertyData) + prop->propertyLength + 3) & -4;
87
        prop = (PIProperty*)p;
2 toby 88
 
106 dmarschall 89
        /* add HasTerminology property key */
2 toby 90
 
91
        /* construct scope string by concatenating Category and Title - hopefully unique! */
92
        hstm = (struct hstm_data*)prop->propertyData;
93
        scopelen = sprintf(hstm->scope,"%s %s",
94
                                           INPLACEP2CSTR(gdata->parm.category),
95
                                           INPLACEP2CSTR(title));
96
 
97
        /* make up a new event ID for this aete, based on printable base-95 hash of scope */
98
        hash = djb2(hstm->scope);
99
        event_id = printablehash(hash); /* this is used by fix_aete later... */
100
 
101
        prop->vendorID = kPhotoshopSignature;
102
        prop->propertyKey = PIHasTerminologyProperty;
103
        prop->propertyID = 0;
104
        prop->propertyLength = offsetof(struct hstm_data,scope) + scopelen + 1;
105
        hstm->version = 0;
106
        hstm->class_id = plugInClassID;
107
        hstm->event_id = event_id;
108
        hstm->aete_resid = AETE_ID;
106 dmarschall 109
 
23 toby 110
        p += (16+prop->propertyLength+3) & -4;
2 toby 111
 
23 toby 112
        return p - (char*)pipl;  // figure how many bytes were added
2 toby 113
}
114
 
115
/* Mac aete resources include word alignments after string pairs; Windows ones apparently don't */
116
#ifdef MAC_ENV
117
        #define ALIGNWORD(j) (j += j & 1)
118
#else
119
        #define ALIGNWORD(j)
120
#endif
121
#define SKIP_PSTR(j) (j += 1+aete[j])
122
 
123
long fixaete(unsigned char *aete,long origsize,StringPtr title){
124
        int offset,oldlen,newlen,desclen,oldpad,newpad;
125
        Str255 desc;
106 dmarschall 126
 
2 toby 127
        offset = 8; /* point at suite name */
128
 
129
        SKIP_PSTR(offset); /* skip suite name (vendor) [maybe this should become author??] */
130
        SKIP_PSTR(offset); /* skip suite description [set this from dialog field??] */
131
        ALIGNWORD(offset);
132
        offset += 4+2+2+2; /* offset now points to filter name. */
133
 
134
        oldlen = aete[offset];
135
        newlen = title[0];
136
 
137
        /* shift aete data taking into account new title string */
138
        desclen = aete[offset+1+oldlen];
139
        PLstrcpy(desc,(StringPtr)(aete+offset+1+oldlen));  /* save description string... */
140
#ifdef MAC_ENV
141
        /* see if alignment padding is necessary */
142
        oldpad = (oldlen + desclen) & 1;
143
        newpad = (newlen + desclen) & 1;
144
#else
145
        oldpad = newpad = 0;
146
#endif
147
        /* shift latter part of aete data, taking into account new string lengths */
106 dmarschall 148
        memcpy(aete+offset+1+newlen+newpad,
149
                   aete+offset+1+oldlen+oldpad,
62 toby 150
                   origsize-offset-1-oldlen-oldpad); /* phew! */
2 toby 151
        /* copy in new title string */
152
        PLstrcpy((StringPtr)(aete+offset),title);
153
        /* copy description string into right place... [this could be new description from dialog field??] */
106 dmarschall 154
        PLstrcpy((StringPtr)(aete+offset+1+newlen),desc);
155
 
2 toby 156
        SKIP_PSTR(offset); /* skip (new) event name */
157
        SKIP_PSTR(offset); /* skip event description */
158
        ALIGNWORD(offset);
106 dmarschall 159
 
2 toby 160
        /* set event ID */
161
        *(unsigned long*)(aete+offset+4) = event_id; /* FIXME: this might be unaligned access on some platforms?? */
162
 
163
        return origsize-oldlen-oldpad+newlen+newpad;
164
}
85 toby 165
 
166
void obfusc(unsigned char *pparm,size_t size){
167
        int i;
168
        unsigned char *p;
106 dmarschall 169
 
170
        /* Do a small self-test to test if the stdlib implementation works as expected, i.e. that it only
171
         * depends on the seed set by srand() and on nothing else.
172
         */
173
        srand(0xdc43df3c);
174
        int selftest1 = rand();
175
        int selftest2 = rand();
176
        int selftest3 = rand();
177
 
178
        srand(0xdc43df3c);
179
        if ((rand() != selftest1) || (rand() != selftest2) || (rand() != selftest3)) {
180
                // This should never happen
181
                simplealert("Stdcall rand() implementation does not work as expected. Obfuscation operation will be cancelled.");
182
                return; // apply no obfuscation
183
        }
184
 
85 toby 185
        /* Very simplistic. meant to hide from casual observation/loading only.
186
         * Results are platform dependent, but this should not matter. */
187
        srand(0xdc43df3c);
188
        for(i = size, p = pparm; i--;)
189
                *p++ ^= rand();
190
}