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 |