Subversion Repositories filter_foundry

Rev

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

Rev 189 Rev 192
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-2019 Toby Thain, toby@telegraphics.com.au
3
    Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au
-
 
4
    Copyright (C) 2018-2019 Daniel Marschall, ViaThinkSoft
4
 
5
 
5
        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
6
        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
7
        the Free Software Foundation; either version 2 of the License, or
8
        the Free Software Foundation; either version 2 of the License, or
8
        (at your option) any later version.
9
        (at your option) any later version.
9
 
10
 
10
        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,
11
        but WITHOUT ANY WARRANTY; without even the implied warranty of
12
        but WITHOUT ANY WARRANTY; without even the implied warranty of
12
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
        GNU General Public License for more details.
14
        GNU General Public License for more details.
14
 
15
 
15
        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
16
        along with this program; if not, write to the Free Software
17
        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
        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
*/
19
*/
19
 
20
 
20
#include <stddef.h>
21
#include <stddef.h>
21
#include <stdint.h>
22
#include <stdint.h>
22
#include <assert.h>
23
#include <assert.h>
23
 
24
 
24
#include "ff.h"
25
#include "ff.h"
25
#include "symtab.h"
26
#include "symtab.h"
26
 
27
 
27
#include "PIActions.h"
28
#include "PIActions.h"
28
#include "PITerminology.h"
29
#include "PITerminology.h"
29
 
30
 
30
#include "compat_string.h"
31
#include "compat_string.h"
31
 
32
 
32
long event_id;
33
long event_id;
33
 
34
 
34
/*
35
/*
35
Find a printable 4-character key, remembering (see PS API guide):
36
Find a printable 4-character key, remembering (see PS API guide):
36
All IDs starting with an uppercase letter are reserved by Adobe.
37
All IDs starting with an uppercase letter are reserved by Adobe.
37
All IDs that are all uppercase are reserved by Apple.
38
All IDs that are all uppercase are reserved by Apple.
38
All IDs that are all lowercase are reserved by Apple.
39
All IDs that are all lowercase are reserved by Apple.
39
This leaves all IDs that begin with a lowercase letter and have at least
40
This leaves all IDs that begin with a lowercase letter and have at least
40
one uppercase letter for you and other plug-in developers.
41
one uppercase letter for you and other plug-in developers.
41
*/
42
*/
42
unsigned long printablehash(unsigned long hash) {
43
unsigned long printablehash(unsigned long hash) {
43
        unsigned long key = 'a' + (hash % 26);  hash /= 26; // first lower case
44
        unsigned long key = 'a' + (hash % 26);  hash /= 26; // first lower case
44
        key = (key << 8) | (' ' + (hash % 95)); hash /= 95; // any printable
45
        key = (key << 8) | (' ' + (hash % 95)); hash /= 95; // any printable
45
        key = (key << 8) | (' ' + (hash % 95)); hash /= 95; // any printable
46
        key = (key << 8) | (' ' + (hash % 95)); hash /= 95; // any printable
46
        return  (key << 8) | ('A' + (hash % 26));             // last upper case
47
        return  (key << 8) | ('A' + (hash % 26));             // last upper case
47
}
48
}
48
 
49
 
49
long roundToNext4(long x) {
50
long roundToNext4(long x) {
50
        int pad = 4 - (x % 4);
51
        int pad = 4 - (x % 4);
51
        if (pad == 0) pad = 4;
52
        if (pad == 0) pad = 4;
52
        return x + pad;
53
        return x + pad;
53
}
54
}
54
 
55
 
55
size_t fixpipl(PIPropertyList *pipl, size_t origsize, StringPtr title) {
56
size_t fixpipl(PIPropertyList *pipl, size_t origsize, StringPtr title) {
56
        PIProperty *prop;
57
        PIProperty *prop;
57
        char *p;
58
        char *p;
58
        struct hstm_data {
59
        struct hstm_data {
59
                /* this structure must be 14+1 bytes long, to match PiPL structure */
60
                /* this structure must be 14+1 bytes long, to match PiPL structure */
60
                long version; /* = 0 */
61
                long version; /* = 0 */
61
                long class_id;
62
                long class_id;
62
                long event_id;
63
                long event_id;
63
                short aete_resid;
64
                short aete_resid;
64
                char scope[1];
65
                char scope[1];
65
        };
66
        };
66
        struct hstm_data *hstm;
67
        struct hstm_data *hstm;
67
        int scopelen;
68
        int scopelen;
68
        unsigned long hash;
69
        unsigned long hash;
69
 
70
 
70
        pipl->count += 3; // 3 more keys in PiPL: name, catg, hstm
71
        pipl->count += 3; // 3 more keys in PiPL: name, catg, hstm
71
 
72
 
72
        p = (char*)pipl + origsize;
73
        p = (char*)pipl + origsize;
73
        prop = (PIProperty*)p;
74
        prop = (PIProperty*)p;
74
 
75
 
75
        /* add Title/Name property key */
76
        /* add Title/Name property key */
76
 
77
 
77
        prop->vendorID = kPhotoshopSignature;
78
        prop->vendorID = kPhotoshopSignature;
78
        prop->propertyKey = PINameProperty;
79
        prop->propertyKey = PINameProperty;
79
        prop->propertyID = 0;
80
        prop->propertyID = 0;
80
        prop->propertyLength = roundToNext4(title[0] + 1);
81
        prop->propertyLength = roundToNext4(title[0] + 1);
81
        PLstrcpy((StringPtr)prop->propertyData, title);
82
        PLstrcpy((StringPtr)prop->propertyData, title);
82
 
83
 
83
        // skip past new property record, and any padding
84
        // skip past new property record, and any padding
84
        p += offsetof(PIProperty, propertyData) + prop->propertyLength;
85
        p += offsetof(PIProperty, propertyData) + prop->propertyLength;
85
        prop = (PIProperty*)p;
86
        prop = (PIProperty*)p;
86
 
87
 
87
        /* add Category property key */
88
        /* add Category property key */
88
 
89
 
89
        prop->vendorID = kPhotoshopSignature;
90
        prop->vendorID = kPhotoshopSignature;
90
        prop->propertyKey = PICategoryProperty;
91
        prop->propertyKey = PICategoryProperty;
91
        prop->propertyID = 0;
92
        prop->propertyID = 0;
92
        prop->propertyLength = roundToNext4(gdata->parm.category[0] + 1);
93
        prop->propertyLength = roundToNext4(gdata->parm.category[0] + 1);
93
        PLstrcpy((StringPtr)prop->propertyData, gdata->parm.category);
94
        PLstrcpy((StringPtr)prop->propertyData, gdata->parm.category);
94
 
95
 
95
        p += offsetof(PIProperty, propertyData) + prop->propertyLength;
96
        p += offsetof(PIProperty, propertyData) + prop->propertyLength;
96
        prop = (PIProperty*)p;
97
        prop = (PIProperty*)p;
97
 
98
 
98
        /* add HasTerminology property key */
99
        /* add HasTerminology property key */
99
 
100
 
100
        /* construct scope string by concatenating Category and Title - hopefully unique! */
101
        /* construct scope string by concatenating Category and Title - hopefully unique! */
101
        hstm = (struct hstm_data*)prop->propertyData;
102
        hstm = (struct hstm_data*)prop->propertyData;
102
        scopelen = sprintf(hstm->scope, "%s %s",
103
        scopelen = sprintf(hstm->scope, "%s %s",
103
                INPLACEP2CSTR(gdata->parm.category),
104
                INPLACEP2CSTR(gdata->parm.category),
104
                INPLACEP2CSTR(title));
105
                INPLACEP2CSTR(title));
105
 
106
 
106
        /* make up a new event ID for this aete, based on printable base-95 hash of scope */
107
        /* make up a new event ID for this aete, based on printable base-95 hash of scope */
107
        hash = djb2(hstm->scope);
108
        hash = djb2(hstm->scope);
108
        event_id = printablehash(hash); /* this is used by aete_generate() later... */
109
        event_id = printablehash(hash); /* this is used by aete_generate() later... */
109
 
110
 
110
        prop->vendorID = kPhotoshopSignature;
111
        prop->vendorID = kPhotoshopSignature;
111
        prop->propertyKey = PIHasTerminologyProperty;
112
        prop->propertyKey = PIHasTerminologyProperty;
112
        prop->propertyID = 0;
113
        prop->propertyID = 0;
113
        prop->propertyLength = roundToNext4(offsetof(struct hstm_data, scope) + scopelen);
114
        prop->propertyLength = roundToNext4(offsetof(struct hstm_data, scope) + scopelen);
114
 
115
 
115
        hstm->version = 0;
116
        hstm->version = 0;
116
        hstm->class_id = plugInClassID;
117
        hstm->class_id = plugInClassID;
117
        hstm->event_id = event_id;
118
        hstm->event_id = event_id;
118
        hstm->aete_resid = AETE_ID;
119
        hstm->aete_resid = AETE_ID;
119
 
120
 
120
        p += offsetof(PIProperty, propertyData) + prop->propertyLength;
121
        p += offsetof(PIProperty, propertyData) + prop->propertyLength;
121
 
122
 
122
        return p - (char*)pipl;  // figure how many bytes were added
123
        return p - (char*)pipl;  // figure how many bytes were added
123
}
124
}
124
 
125
 
125
void _aete_write_byte(void** aeteptr, uint8_t val) {
126
void _aete_write_byte(void** aeteptr, uint8_t val) {
126
        uint8_t* tmp = *((uint8_t**)aeteptr);
127
        uint8_t* tmp = *((uint8_t**)aeteptr);
127
        *tmp = val;
128
        *tmp = val;
128
        *aeteptr = (void*)((unsigned char*)tmp + 1);
129
        *aeteptr = (void*)((unsigned char*)tmp + 1);
129
}
130
}
130
#define AETE_WRITE_BYTE(i) _aete_write_byte(&aeteptr, (i));
131
#define AETE_WRITE_BYTE(i) _aete_write_byte(&aeteptr, (i));
131
 
132
 
132
void _aete_write_word(void** aeteptr, uint16_t val) {
133
void _aete_write_word(void** aeteptr, uint16_t val) {
133
        uint16_t* tmp = *((uint16_t**)aeteptr);
134
        uint16_t* tmp = *((uint16_t**)aeteptr);
134
        *tmp = val;
135
        *tmp = val;
135
        *aeteptr = (void*)((unsigned char*)tmp + 2);
136
        *aeteptr = (void*)((unsigned char*)tmp + 2);
136
}
137
}
137
#define AETE_WRITE_WORD(i) _aete_write_word(&aeteptr, (i));
138
#define AETE_WRITE_WORD(i) _aete_write_word(&aeteptr, (i));
138
 
139
 
139
void _aete_write_dword(void** aeteptr, uint32_t val) {
140
void _aete_write_dword(void** aeteptr, uint32_t val) {
140
        uint32_t* tmp = *((uint32_t**)aeteptr);
141
        uint32_t* tmp = *((uint32_t**)aeteptr);
141
        *tmp = val;
142
        *tmp = val;
142
        *aeteptr = (void*)((unsigned char*)tmp + 4);
143
        *aeteptr = (void*)((unsigned char*)tmp + 4);
143
}
144
}
144
#define AETE_WRITE_DWORD(i) _aete_write_dword(&aeteptr, (i));
145
#define AETE_WRITE_DWORD(i) _aete_write_dword(&aeteptr, (i));
145
 
146
 
146
void _aete_write_pstr(void** aeteptr, char* str) {
147
void _aete_write_pstr(void** aeteptr, char* str) {
147
        char* tmp;
148
        char* tmp;
148
 
149
 
149
        assert(strlen(str) <= 255);
150
        assert(strlen(str) <= 255);
150
 
151
 
151
        _aete_write_byte(aeteptr, (uint8_t)strlen(str));
152
        _aete_write_byte(aeteptr, (uint8_t)strlen(str));
152
 
153
 
153
        tmp = *((char**)aeteptr);
154
        tmp = *((char**)aeteptr);
154
        strcpy(tmp, str);
155
        strcpy(tmp, str);
155
        *aeteptr = (void*)((unsigned char*)tmp + strlen(str));
156
        *aeteptr = (void*)((unsigned char*)tmp + strlen(str));
156
}
157
}
157
#define AETE_WRITE_PSTR(s) _aete_write_pstr(&aeteptr, (s));
158
#define AETE_WRITE_PSTR(s) _aete_write_pstr(&aeteptr, (s));
158
 
159
 
159
void _aete_align_word(void** aeteptr) {
160
void _aete_align_word(void** aeteptr) {
160
        #ifdef MAC_ENV
161
        #ifdef MAC_ENV
161
        unsigned char* tmp = *((unsigned char**)aeteptr);
162
        unsigned char* tmp = *((unsigned char**)aeteptr);
162
        tmp += (intptr_t)tmp & 1;
163
        tmp += (intptr_t)tmp & 1;
163
        *aeteptr = (void*)tmp;
164
        *aeteptr = (void*)tmp;
164
        #endif
165
        #endif
165
}
166
}
166
#define AETE_ALIGN_WORD() _aete_align_word(&aeteptr);
167
#define AETE_ALIGN_WORD() _aete_align_word(&aeteptr);
167
 
168
 
168
void* _aete_property(void* aeteptr, PARM_T *pparm, int ctlidx, int mapidx, OSType key) {
169
void* _aete_property(void* aeteptr, PARM_T *pparm, int ctlidx, int mapidx, OSType key) {
169
        char tmp[256];
170
        char tmp[256];
170
 
171
 
171
        if (pparm->ctl_used[ctlidx] || pparm->map_used[mapidx]) {
172
        if (pparm->ctl_used[ctlidx] || pparm->map_used[mapidx]) {
172
                if (pparm->map_used[mapidx]) {
173
                if (pparm->map_used[mapidx]) {
173
                        if (ctlidx & 1) {
174
                        if (ctlidx & 1) {
174
                                sprintf(tmp, "... %s", (char*)pparm->map[mapidx]);
175
                                sprintf(tmp, "... %s", (char*)pparm->map[mapidx]);
175
                        } else {
176
                        } else {
176
                                sprintf(tmp, "%s ...", (char*)pparm->map[mapidx]);
177
                                sprintf(tmp, "%s ...", (char*)pparm->map[mapidx]);
177
                        }
178
                        }
178
                        AETE_WRITE_PSTR(tmp);
179
                        AETE_WRITE_PSTR(tmp);
179
                } else {
180
                } else {
180
                        AETE_WRITE_PSTR((char*)pparm->ctl[ctlidx]);
181
                        AETE_WRITE_PSTR((char*)pparm->ctl[ctlidx]);
181
                }
182
                }
182
                AETE_ALIGN_WORD();
183
                AETE_ALIGN_WORD();
183
                AETE_WRITE_DWORD(key);
184
                AETE_WRITE_DWORD(key);
184
                AETE_WRITE_DWORD(typeSInt32);
185
                AETE_WRITE_DWORD(typeSInt32);
185
                AETE_WRITE_PSTR("");
186
                AETE_WRITE_PSTR("");
186
                AETE_ALIGN_WORD();
187
                AETE_ALIGN_WORD();
187
                AETE_WRITE_WORD(0x8000); /* FLAGS_1_OPT_PARAM / flagsOptionalSingleParameter */
188
                AETE_WRITE_WORD(0x8000); /* FLAGS_1_OPT_PARAM / flagsOptionalSingleParameter */
188
        }
189
        }
189
 
190
 
190
        return aeteptr;
191
        return aeteptr;
191
}
192
}
192
 
193
 
193
size_t aete_generate(void* aeteptr, PARM_T *pparm) {
194
size_t aete_generate(void* aeteptr, PARM_T *pparm) {
194
        int numprops;
195
        int numprops;
195
        void *beginptr = aeteptr;
196
        void *beginptr = aeteptr;
196
 
197
 
197
        // Attention!
198
        // Attention!
198
        // - On some systems (e.g. ARM based CPUs) this will cause an unaligned memory access exception.
199
        // - On some systems (e.g. ARM based CPUs) this will cause an unaligned memory access exception.
199
        //   For X86, memory access just becomes slower.
200
        //   For X86, memory access just becomes slower.
200
        // - If you change something here, please also change it in Scripting.rc (Windows) and scripting.r (Mac OS)
201
        // - If you change something here, please also change it in Scripting.rc (Windows) and scripting.r (Mac OS)
201
 
202
 
202
        // Note:
203
        // Note:
203
        // - The 'aete' resource for Mac OS has word alignments after strings (but not if the next element is also a string)
204
        // - The 'aete' resource for Mac OS has word alignments after strings (but not if the next element is also a string)
204
        //   see https://developer.apple.com/library/archive/documentation/mac/pdf/Interapplication_Communication/AE_Term_Resources.pdf page 8-9
205
        //   see https://developer.apple.com/library/archive/documentation/mac/pdf/Interapplication_Communication/AE_Term_Resources.pdf page 8-9
205
 
206
 
206
#ifdef WIN_ENV
207
#ifdef WIN_ENV
207
        AETE_WRITE_WORD(0x0001); /* Reserved (for Photoshop) */
208
        AETE_WRITE_WORD(0x0001); /* Reserved (for Photoshop) */
208
#endif
209
#endif
209
        AETE_WRITE_BYTE(0x01); /* aete version */
210
        AETE_WRITE_BYTE(0x01); /* aete version */
210
        AETE_WRITE_BYTE(0x00); /* aete version */
211
        AETE_WRITE_BYTE(0x00); /* aete version */
211
        AETE_WRITE_WORD(english); /* language specifiers */
212
        AETE_WRITE_WORD(english); /* language specifiers */
212
        AETE_WRITE_WORD(roman);
213
        AETE_WRITE_WORD(roman);
213
        AETE_WRITE_WORD(1); /* 1 suite */
214
        AETE_WRITE_WORD(1); /* 1 suite */
214
        {
215
        {
215
                AETE_WRITE_PSTR(/*"Telegraphics"*/(char*)pparm->author); /* vendor suite name */
216
                AETE_WRITE_PSTR(/*"Telegraphics"*/(char*)pparm->author); /* vendor suite name */
216
                AETE_WRITE_PSTR(""); /* optional description */
217
                AETE_WRITE_PSTR(""); /* optional description */
217
                AETE_ALIGN_WORD();
218
                AETE_ALIGN_WORD();
218
                AETE_WRITE_DWORD(plugInSuiteID); /* suite ID */
219
                AETE_WRITE_DWORD(plugInSuiteID); /* suite ID */
219
                AETE_WRITE_WORD(1); /* suite code, must be 1. Attention: Filters like 'Pointillize' have set this to 0! */
220
                AETE_WRITE_WORD(1); /* suite code, must be 1. Attention: Filters like 'Pointillize' have set this to 0! */
220
                AETE_WRITE_WORD(1); /* suite level, must be 1. Attention: Filters like 'Pointillize' have set this to 0! */
221
                AETE_WRITE_WORD(1); /* suite level, must be 1. Attention: Filters like 'Pointillize' have set this to 0! */
221
                AETE_WRITE_WORD(1); /* 1 event (structure for filters) */
222
                AETE_WRITE_WORD(1); /* 1 event (structure for filters) */
222
                {
223
                {
223
                        AETE_WRITE_PSTR(/*"FilterFoundry"*/(char*)pparm->title); /* event name */
224
                        AETE_WRITE_PSTR(/*"FilterFoundry"*/(char*)pparm->title); /* event name */
224
                        AETE_WRITE_PSTR(""); /* event description */
225
                        AETE_WRITE_PSTR(""); /* event description */
225
                        AETE_ALIGN_WORD();
226
                        AETE_ALIGN_WORD();
226
                        AETE_WRITE_DWORD(plugInClassID); /* event class */
227
                        AETE_WRITE_DWORD(plugInClassID); /* event class */
227
                        AETE_WRITE_DWORD(/*plugInEventID*/event_id); /* event ID */
228
                        AETE_WRITE_DWORD(/*plugInEventID*/event_id); /* event ID */
228
                        /* NO_REPLY: */
229
                        /* NO_REPLY: */
229
                        AETE_WRITE_DWORD(noReply); /* noReply='null' */
230
                        AETE_WRITE_DWORD(noReply); /* noReply='null' */
230
                        AETE_WRITE_PSTR(""); /* reply description */
231
                        AETE_WRITE_PSTR(""); /* reply description */
231
                        AETE_ALIGN_WORD();
232
                        AETE_ALIGN_WORD();
232
                        AETE_WRITE_WORD(0);
233
                        AETE_WRITE_WORD(0);
233
                        /* IMAGE_DIRECT_PARAM: */
234
                        /* IMAGE_DIRECT_PARAM: */
234
                        AETE_WRITE_DWORD(typeImageReference); /* typeImageReference='#ImR' */
235
                        AETE_WRITE_DWORD(typeImageReference); /* typeImageReference='#ImR' */
235
                        AETE_WRITE_PSTR(""); /* direct parm description */
236
                        AETE_WRITE_PSTR(""); /* direct parm description */
236
                        AETE_ALIGN_WORD();
237
                        AETE_ALIGN_WORD();
237
                        AETE_WRITE_WORD(0xB000);
238
                        AETE_WRITE_WORD(0xB000);
238
 
239
 
239
                        numprops = 0;
240
                        numprops = 0;
240
                        if (pparm->ctl_used[0] || pparm->map_used[0]) numprops++;
241
                        if (pparm->ctl_used[0] || pparm->map_used[0]) numprops++;
241
                        if (pparm->ctl_used[1] || pparm->map_used[0]) numprops++;
242
                        if (pparm->ctl_used[1] || pparm->map_used[0]) numprops++;
242
                        if (pparm->ctl_used[2] || pparm->map_used[1]) numprops++;
243
                        if (pparm->ctl_used[2] || pparm->map_used[1]) numprops++;
243
                        if (pparm->ctl_used[3] || pparm->map_used[1]) numprops++;
244
                        if (pparm->ctl_used[3] || pparm->map_used[1]) numprops++;
244
                        if (pparm->ctl_used[4] || pparm->map_used[2]) numprops++;
245
                        if (pparm->ctl_used[4] || pparm->map_used[2]) numprops++;
245
                        if (pparm->ctl_used[5] || pparm->map_used[2]) numprops++;
246
                        if (pparm->ctl_used[5] || pparm->map_used[2]) numprops++;
246
                        if (pparm->ctl_used[6] || pparm->map_used[3]) numprops++;
247
                        if (pparm->ctl_used[6] || pparm->map_used[3]) numprops++;
247
                        if (pparm->ctl_used[7] || pparm->map_used[3]) numprops++;
248
                        if (pparm->ctl_used[7] || pparm->map_used[3]) numprops++;
248
                        AETE_WRITE_WORD(numprops);
249
                        AETE_WRITE_WORD(numprops);
249
                        {
250
                        {
250
                                // Standalone filters don't need RGBA expressions
251
                                // Standalone filters don't need RGBA expressions
251
                                /*
252
                                /*
252
                                AETE_WRITE_PSTR("R");
253
                                AETE_WRITE_PSTR("R");
253
                                AETE_ALIGN_WORD();
254
                                AETE_ALIGN_WORD();
254
                                AETE_WRITE_DWORD(PARAM_R_KEY);
255
                                AETE_WRITE_DWORD(PARAM_R_KEY);
255
                                AETE_WRITE_DWORD(typeText);
256
                                AETE_WRITE_DWORD(typeText);
256
                                AETE_WRITE_PSTR("R channel expression");
257
                                AETE_WRITE_PSTR("R channel expression");
257
                                AETE_ALIGN_WORD();
258
                                AETE_ALIGN_WORD();
258
                                AETE_WRITE_WORD(0x8000);
259
                                AETE_WRITE_WORD(0x8000);
259
 
260
 
260
                                AETE_WRITE_PSTR("G");
261
                                AETE_WRITE_PSTR("G");
261
                                AETE_ALIGN_WORD();
262
                                AETE_ALIGN_WORD();
262
                                AETE_WRITE_DWORD(PARAM_G_KEY);
263
                                AETE_WRITE_DWORD(PARAM_G_KEY);
263
                                AETE_WRITE_DWORD(typeText);
264
                                AETE_WRITE_DWORD(typeText);
264
                                AETE_WRITE_PSTR("G channel expression");
265
                                AETE_WRITE_PSTR("G channel expression");
265
                                AETE_ALIGN_WORD();
266
                                AETE_ALIGN_WORD();
266
                                AETE_WRITE_WORD(0x8000);
267
                                AETE_WRITE_WORD(0x8000);
267
 
268
 
268
                                AETE_WRITE_PSTR("B");
269
                                AETE_WRITE_PSTR("B");
269
                                AETE_ALIGN_WORD();
270
                                AETE_ALIGN_WORD();
270
                                AETE_WRITE_DWORD(PARAM_B_KEY);
271
                                AETE_WRITE_DWORD(PARAM_B_KEY);
271
                                AETE_WRITE_DWORD(typeText);
272
                                AETE_WRITE_DWORD(typeText);
272
                                AETE_WRITE_PSTR("B channel expression");
273
                                AETE_WRITE_PSTR("B channel expression");
273
                                AETE_ALIGN_WORD();
274
                                AETE_ALIGN_WORD();
274
                                AETE_WRITE_WORD(0x8000);
275
                                AETE_WRITE_WORD(0x8000);
275
 
276
 
276
                                AETE_WRITE_PSTR("A");
277
                                AETE_WRITE_PSTR("A");
277
                                AETE_ALIGN_WORD();
278
                                AETE_ALIGN_WORD();
278
                                AETE_WRITE_DWORD(PARAM_A_KEY);
279
                                AETE_WRITE_DWORD(PARAM_A_KEY);
279
                                AETE_WRITE_DWORD(typeText);
280
                                AETE_WRITE_DWORD(typeText);
280
                                AETE_WRITE_PSTR("A channel expression");
281
                                AETE_WRITE_PSTR("A channel expression");
281
                                AETE_ALIGN_WORD();
282
                                AETE_ALIGN_WORD();
282
                                AETE_WRITE_WORD(0x8000);
283
                                AETE_WRITE_WORD(0x8000);
283
                                */
284
                                */
284
 
285
 
285
                                aeteptr = _aete_property(aeteptr, pparm, 0, 0, PARAM_CTL0_KEY);
286
                                aeteptr = _aete_property(aeteptr, pparm, 0, 0, PARAM_CTL0_KEY);
286
                                aeteptr = _aete_property(aeteptr, pparm, 1, 0, PARAM_CTL1_KEY);
287
                                aeteptr = _aete_property(aeteptr, pparm, 1, 0, PARAM_CTL1_KEY);
287
                                aeteptr = _aete_property(aeteptr, pparm, 2, 1, PARAM_CTL2_KEY);
288
                                aeteptr = _aete_property(aeteptr, pparm, 2, 1, PARAM_CTL2_KEY);
288
                                aeteptr = _aete_property(aeteptr, pparm, 3, 1, PARAM_CTL3_KEY);
289
                                aeteptr = _aete_property(aeteptr, pparm, 3, 1, PARAM_CTL3_KEY);
289
                                aeteptr = _aete_property(aeteptr, pparm, 4, 2, PARAM_CTL4_KEY);
290
                                aeteptr = _aete_property(aeteptr, pparm, 4, 2, PARAM_CTL4_KEY);
290
                                aeteptr = _aete_property(aeteptr, pparm, 5, 2, PARAM_CTL5_KEY);
291
                                aeteptr = _aete_property(aeteptr, pparm, 5, 2, PARAM_CTL5_KEY);
291
                                aeteptr = _aete_property(aeteptr, pparm, 6, 3, PARAM_CTL6_KEY);
292
                                aeteptr = _aete_property(aeteptr, pparm, 6, 3, PARAM_CTL6_KEY);
292
                                aeteptr = _aete_property(aeteptr, pparm, 7, 3, PARAM_CTL7_KEY);
293
                                aeteptr = _aete_property(aeteptr, pparm, 7, 3, PARAM_CTL7_KEY);
293
                        }
294
                        }
294
                }
295
                }
295
 
296
 
296
                /* non-filter plug-in class here */
297
                /* non-filter plug-in class here */
297
                AETE_WRITE_WORD(0); /* 0 classes */
298
                AETE_WRITE_WORD(0); /* 0 classes */
298
                {}
299
                {}
299
                AETE_WRITE_WORD(0); /* 0 comparison ops (not supported) */
300
                AETE_WRITE_WORD(0); /* 0 comparison ops (not supported) */
300
                {}
301
                {}
301
                AETE_WRITE_WORD(0); /* 0 enumerations */
302
                AETE_WRITE_WORD(0); /* 0 enumerations */
302
                {}
303
                {}
303
        }
304
        }
304
        AETE_WRITE_DWORD(0); /* padding (FIXME: do we need that? Adobe's Windows filters don't) */
305
        AETE_WRITE_DWORD(0); /* padding (FIXME: do we need that? Adobe's Windows filters don't) */
305
 
306
 
306
        return (unsigned char*)aeteptr - (unsigned char*)beginptr; // length of stuff written
307
        return (unsigned char*)aeteptr - (unsigned char*)beginptr; // length of stuff written
307
}
308
}
308
 
309
 
309
void obfusc(unsigned char *pparm, size_t size) {
310
void obfusc(unsigned char *pparm, size_t size) {
310
        size_t i;
311
        size_t i;
311
        unsigned char *p;
312
        unsigned char *p;
312
        uint32_t x32;
313
        uint32_t x32;
313
 
314
 
314
        x32 = 0x95D4A68F; // Hardcoded seed
315
        x32 = 0x95D4A68F; // Hardcoded seed
315
        for (i = size, p = pparm; i--;) {
316
        for (i = size, p = pparm; i--;) {
316
                // https://de.wikipedia.org/wiki/Xorshift
317
                // https://de.wikipedia.org/wiki/Xorshift
317
                *p++ ^= (x32 ^= (x32 ^= (x32 ^= x32 << 13) >> 17) << 5);
318
                *p++ ^= (x32 ^= (x32 ^= (x32 ^= x32 << 13) >> 17) << 5);
318
        }
319
        }
319
}
320
}
320
 
321