Subversion Repositories filter_foundry

Rev

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