1 /* Copyright (C) 2001-2019 Artifex Software, Inc.
2 All Rights Reserved.
3
4 This software is provided AS-IS with no warranty, either express or
5 implied.
6
7 This software is distributed under license and may not be copied,
8 modified or distributed except as expressly authorized under the terms
9 of the license contained in the file LICENSE in this distribution.
10
11 Refer to licensing information at http://www.artifex.com or contact
12 Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
13 CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15
16
17 /* Templates for sample lookup and expansion */
18
19 /* This module is allowed to include several times into a single .c file.
20 The following macros to be defined in advance :
21 MULTIPLE_MAPS - 1 if num_components_per_plane > 0 and
22 components use different maps, 0 otherwise.
23 TEMPLATE_sample_unpack_1 - a name for the function
24 TEMPLATE_sample_unpack_2 - a name for the function
25 TEMPLATE_sample_unpack_4 - a name for the function
26 TEMPLATE_sample_unpack_8 - a name for the function
27 */
28
29 #if defined(TEMPLATE_sample_unpack_1) && defined(TEMPLATE_sample_unpack_2) && defined(TEMPLATE_sample_unpack_4) && defined(TEMPLATE_sample_unpack_8)
30
31 #include "valgrind.h"
32
33 #if MULTIPLE_MAPS
34 # define NEXT_MAP map = smap[++smap_index % num_components_per_plane].table.lookup4x1to32
35 # define NEXT_MAP8 map = smap[++smap_index % num_components_per_plane].table.lookup8
36 # define DEFINE_SMAP_INDEX int smap_index = 0;
37 #else
38 # define NEXT_MAP
39 # define NEXT_MAP8
40 # define DEFINE_SMAP_INDEX
41 #endif
42
43 const byte *
TEMPLATE_sample_unpack_1(byte * bptr,int * pdata_x,const byte * data,int data_x,uint dsize,const sample_map * smap,int spread,int num_components_per_plane)44 TEMPLATE_sample_unpack_1(byte * bptr, int *pdata_x, const byte * data, int data_x,
45 uint dsize, const sample_map *smap, int spread,
46 int num_components_per_plane)
47 {
48 const sample_lookup_t * ptab = &smap->table;
49 const byte *psrc = data + (data_x >> 3);
50 int left = dsize - (data_x >> 3);
51 DEFINE_SMAP_INDEX
52
53 #ifdef PACIFY_VALGRIND
54 byte *bend = bptr + left*spread;
55 byte vbits = 0;
56
57 /* Allow for undefined bits at the end */
58 VALGRIND_GET_VBITS(&psrc[left-1], &vbits, 1);
59 /* At least the top bit must be defined. If not,
60 * don't change anything, and let valgrind complain. */
61 if ((vbits & 0x80) == 0) {
62 byte zero = 0;
63 VALGRIND_SET_VBITS(&psrc[left-1], &zero, 1);
64 }
65 #endif
66
67 if (spread == 1) {
68 bits32 *bufp = (bits32 *) bptr;
69 const bits32 *map = &ptab->lookup4x1to32[0];
70 uint b;
71
72 if (left & 1) {
73 b = psrc[0];
74 bufp[0] = map[b >> 4];
75 NEXT_MAP;
76 bufp[1] = map[b & 0xf];
77 NEXT_MAP;
78 psrc++, bufp += 2;
79 }
80 left >>= 1;
81 while (left--) {
82 b = psrc[0];
83 bufp[0] = map[b >> 4];
84 NEXT_MAP;
85 bufp[1] = map[b & 0xf];
86 NEXT_MAP;
87 b = psrc[1];
88 bufp[2] = map[b >> 4];
89 NEXT_MAP;
90 bufp[3] = map[b & 0xf];
91 NEXT_MAP;
92 psrc += 2, bufp += 4;
93 }
94 } else {
95 byte *bufp = bptr;
96 const byte *map = &ptab->lookup8[0];
97
98 while (left--) {
99 uint b = *psrc++;
100
101 *bufp = map[b >> 7];
102 NEXT_MAP8;
103 bufp += spread;
104 *bufp = map[(b >> 6) & 1];
105 NEXT_MAP8;
106 bufp += spread;
107 *bufp = map[(b >> 5) & 1];
108 NEXT_MAP8;
109 bufp += spread;
110 *bufp = map[(b >> 4) & 1];
111 NEXT_MAP8;
112 bufp += spread;
113 *bufp = map[(b >> 3) & 1];
114 NEXT_MAP8;
115 bufp += spread;
116 *bufp = map[(b >> 2) & 1];
117 NEXT_MAP8;
118 bufp += spread;
119 *bufp = map[(b >> 1) & 1];
120 NEXT_MAP8;
121 bufp += spread;
122 *bufp = map[b & 1];
123 NEXT_MAP8;
124 bufp += spread;
125 }
126 }
127 #ifdef PACIFY_VALGRIND
128 /* Put any undefinedness back, and carry it over to the output. */
129 VALGRIND_SET_VBITS(psrc-1, &vbits, 1);
130 {
131 byte ones = 0xff;
132 if (vbits & 0x40)
133 VALGRIND_SET_VBITS(bend - spread*7, &ones, 1);
134 if (vbits & 0x20)
135 VALGRIND_SET_VBITS(bend - spread*6, &ones, 1);
136 if (vbits & 0x10)
137 VALGRIND_SET_VBITS(bend - spread*5, &ones, 1);
138 if (vbits & 0x08)
139 VALGRIND_SET_VBITS(bend - spread*4, &ones, 1);
140 if (vbits & 0x04)
141 VALGRIND_SET_VBITS(bend - spread*3, &ones, 1);
142 if (vbits & 0x02)
143 VALGRIND_SET_VBITS(bend - spread*2, &ones, 1);
144 if (vbits & 0x01)
145 VALGRIND_SET_VBITS(bend - spread*1, &ones, 1);
146 }
147 #endif
148 *pdata_x = data_x & 7;
149 return bptr;
150 }
151
152 #undef NEXT_MAP
153
154 #if MULTIPLE_MAPS
155 # define NEXT_MAP map = smap[++smap_index % num_components_per_plane].table.lookup2x2to16
156 #else
157 # define NEXT_MAP
158 #endif
159
160 const byte *
TEMPLATE_sample_unpack_2(byte * bptr,int * pdata_x,const byte * data,int data_x,uint dsize,const sample_map * smap,int spread,int num_components_per_plane)161 TEMPLATE_sample_unpack_2(byte * bptr, int *pdata_x, const byte * data, int data_x,
162 uint dsize, const sample_map *smap, int spread,
163 int num_components_per_plane)
164 {
165 const sample_lookup_t * ptab = &smap->table;
166 const byte *psrc = data + (data_x >> 2);
167 int left = dsize - (data_x >> 2);
168 DEFINE_SMAP_INDEX
169
170 #ifdef PACIFY_VALGRIND
171 byte *bend = bptr + left*spread;
172 byte vbits = 0;
173
174 /* Allow for undefined bits at the end */
175 VALGRIND_GET_VBITS(&psrc[left-1], &vbits, 1);
176 /* At least the top 2 bits must be defined. If not,
177 * don't change anything, and let valgrind complain. */
178 if ((vbits & 0xC0) == 0) {
179 byte zero = 0;
180 VALGRIND_SET_VBITS(&psrc[left-1], &zero, 1);
181 }
182 #endif
183
184 if (spread == 1) {
185 bits16 *bufp = (bits16 *) bptr;
186 const bits16 *map = &ptab->lookup2x2to16[0];
187
188 while (left--) {
189 uint b = *psrc++;
190
191 *bufp++ = map[b >> 4];
192 NEXT_MAP;
193 *bufp++ = map[b & 0xf];
194 NEXT_MAP;
195 }
196 } else {
197 byte *bufp = bptr;
198 const byte *map = &ptab->lookup8[0];
199
200 while (left--) {
201 unsigned b = *psrc++;
202
203 *bufp = map[b >> 6];
204 NEXT_MAP8;
205 bufp += spread;
206 *bufp = map[(b >> 4) & 3];
207 NEXT_MAP8;
208 bufp += spread;
209 *bufp = map[(b >> 2) & 3];
210 NEXT_MAP8;
211 bufp += spread;
212 *bufp = map[b & 3];
213 NEXT_MAP8;
214 bufp += spread;
215 }
216 }
217 *pdata_x = data_x & 3;
218 #ifdef PACIFY_VALGRIND
219 /* Put any undefinedness back, and carry it over to the output. */
220 VALGRIND_SET_VBITS(psrc-1, &vbits, 1);
221 {
222 byte ones = 0xff;
223 if (vbits & 0x30)
224 VALGRIND_SET_VBITS(bend - spread*3, &ones, 1);
225 if (vbits & 0x0C)
226 VALGRIND_SET_VBITS(bend - spread*2, &ones, 1);
227 if (vbits & 0x03)
228 VALGRIND_SET_VBITS(bend - spread*1, &ones, 1);
229 }
230 #endif
231 return bptr;
232 }
233
234 #undef NEXT_MAP
235
236 const byte *
TEMPLATE_sample_unpack_4(byte * bptr,int * pdata_x,const byte * data,int data_x,uint dsize,const sample_map * smap,int spread,int num_components_per_plane)237 TEMPLATE_sample_unpack_4(byte * bptr, int *pdata_x, const byte * data, int data_x,
238 uint dsize, const sample_map *smap, int spread,
239 int num_components_per_plane)
240 {
241 const sample_lookup_t * ptab = &smap->table;
242 byte *bufp = bptr;
243 const byte *psrc = data + (data_x >> 1);
244 int left = dsize - (data_x >> 1);
245 const byte *map = &ptab->lookup8[0];
246 DEFINE_SMAP_INDEX
247
248 #ifdef PACIFY_VALGRIND
249 byte vbits = 0;
250
251 /* Allow for undefined bits at the end */
252 VALGRIND_GET_VBITS(&psrc[left-1], &vbits, 1);
253 /* At least the top 4 bits must be defined. If not,
254 * don't change anything, and let valgrind complain. */
255 if ((vbits & 0xf0) == 0) {
256 byte zero = 0;
257 VALGRIND_SET_VBITS(&psrc[left-1], &zero, 1);
258 }
259 #endif
260
261 while (left--) {
262 uint b = *psrc++;
263
264 *bufp = map[b >> 4];
265 NEXT_MAP8;
266 bufp += spread;
267 *bufp = map[b & 0xf];
268 NEXT_MAP8;
269 bufp += spread;
270 }
271 #ifdef PACIFY_VALGRIND
272 /* Put any undefinedness back, and carry it over to the output. */
273 VALGRIND_SET_VBITS(psrc-1, &vbits, 1);
274 if ((vbits & 0x0f) != 0) {
275 byte ones = 0xFF;
276 VALGRIND_SET_VBITS(bufp-spread, &ones, 1);
277 }
278 #endif
279 *pdata_x = data_x & 1;
280 return bptr;
281 }
282
283 const byte *
TEMPLATE_sample_unpack_8(byte * bptr,int * pdata_x,const byte * data,int data_x,uint dsize,const sample_map * smap,int spread,int num_components_per_plane)284 TEMPLATE_sample_unpack_8(byte * bptr, int *pdata_x, const byte * data, int data_x,
285 uint dsize, const sample_map *smap, int spread,
286 int num_components_per_plane)
287 {
288 const sample_lookup_t * ptab = &smap->table;
289 byte *bufp = bptr;
290 const byte *psrc = data + data_x;
291 DEFINE_SMAP_INDEX
292
293 *pdata_x = 0;
294 if (spread == 1) {
295 if (MULTIPLE_MAPS ||
296 ptab->lookup8[0] != 0 ||
297 ptab->lookup8[255] != 255
298 ) {
299 uint left = dsize - data_x;
300 const byte *map = &ptab->lookup8[0];
301
302 while (left--) {
303 *bufp++ = map[*psrc++];
304 NEXT_MAP8;
305 }
306 } else { /* No copying needed, and we'll use the data right away. */
307 return psrc;
308 }
309 } else {
310 int left = dsize - data_x;
311 const byte *map = &ptab->lookup8[0];
312
313 for (; left--; psrc++, bufp += spread) {
314 *bufp = map[*psrc];
315 NEXT_MAP8;
316 }
317 }
318 return bptr;
319 }
320
321 #undef NEXT_MAP
322 #undef NEXT_MAP8
323 #undef DEFINE_SMAP_INDEX
324
325 #else
326 int dummy;
327 #endif
328
329