Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1994, 2000 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: spdiff.c,v 1.9 2005/03/16 14:57:42 igor Exp $ */
18
/* Pixel differencing filters */
19
#include "stdio_.h"		/* should be std.h, but needs NULL */
20
#include "memory_.h"
21
#include "strimpl.h"
22
#include "spdiffx.h"
23
 
24
/* ------ PixelDifferenceEncode/Decode ------ */
25
 
26
private_st_PDiff_state();
27
 
28
/* Define values for case dispatch. */
29
#define cBits1 0
30
#define cBits2 5
31
#define cBits4 10
32
#define cBits8 15
33
#define cBits16 20
34
#define cEncode 0
35
#define cDecode 25
36
 
37
/* Set defaults */
38
private void
39
s_PDiff_set_defaults(stream_state * st)
40
{
41
    stream_PDiff_state *const ss = (stream_PDiff_state *) st;
42
 
43
    s_PDiff_set_defaults_inline(ss);
44
}
45
 
46
/* Common (re)initialization. */
47
private int
48
s_PDiff_reinit(stream_state * st)
49
{
50
    stream_PDiff_state *const ss = (stream_PDiff_state *) st;
51
 
52
    ss->row_left = 0;
53
    return 0;
54
}
55
 
56
/* Initialize PixelDifferenceEncode filter. */
57
private int
58
s_PDiffE_init(stream_state * st)
59
{
60
    stream_PDiff_state *const ss = (stream_PDiff_state *) st;
61
    int bits_per_row =
62
	ss->Colors * ss->BitsPerComponent * ss->Columns;
63
    static const byte cb_values[] = {
64
	0, cBits1, cBits2, 0, cBits4, 0, 0, 0, cBits8,
65
	0, 0, 0, 0, 0, 0, 0, cBits16
66
    };
67
 
68
    ss->row_count = (bits_per_row + 7) >> 3;
69
    ss->end_mask = (1 << (-bits_per_row & 7)) - 1;
70
    ss->case_index =
71
	cb_values[ss->BitsPerComponent] +
72
	(ss->Colors > 4 ? 0 : ss->Colors) + cEncode;
73
    return s_PDiff_reinit(st);
74
}
75
 
76
/* Initialize PixelDifferenceDecode filter. */
77
private int
78
s_PDiffD_init(stream_state * st)
79
{
80
    stream_PDiff_state *const ss = (stream_PDiff_state *) st;
81
 
82
    s_PDiffE_init(st);
83
    ss->case_index += cDecode - cEncode;
84
    return 0;
85
}
86
 
87
/* Process a buffer.  Note that this handles both Encode and Decode. */
88
private int
89
s_PDiff_process(stream_state * st, stream_cursor_read * pr,
90
		stream_cursor_write * pw, bool last)
91
{
92
    stream_PDiff_state *const ss = (stream_PDiff_state *) st;
93
    const byte *p = pr->ptr;
94
    byte *q = pw->ptr;
95
    int count;
96
    int status = 0;
97
    uint s0 = ss->prev[0];
98
    byte t = 0;			/* avoid spurious compiler warnings */
99
    int  ti;
100
    const byte end_mask = ss->end_mask;
101
    int colors = ss->Colors;
102
    int nb = (colors * ss->BitsPerComponent) >> 3;
103
    int final;
104
    int ndone, ci;
105
 
106
row:
107
    if (ss->row_left == 0) {
108
	ss->row_left = ss->row_count;
109
	s0 = 0;
110
	memset(&ss->prev[1], 0, sizeof(uint) * (s_PDiff_max_Colors - 1));
111
    }
112
    {
113
	int rcount = pr->limit - p;
114
	int wcount = pw->limit - q;
115
 
116
	if (ss->row_left < rcount)
117
	    rcount = ss->row_left;
118
	count = (wcount < rcount ? (status = 1, wcount) : rcount);
119
    }
120
    final = (last && !status ? 1 : nb);
121
    ss->row_left -= count;
122
 
123
    /*
124
     * Encoding and decoding are fundamentally different.
125
     * Encoding computes E[i] = D[i] - D[i-1];
126
     * decoding computes D[i] = E[i] + D[i-1].
127
     * Nevertheless, the loop structures are similar enough that
128
     * we put the code for both functions in the same place.
129
     *
130
     * We only optimize BitsPerComponent = 1, 3, and 4, which
131
     * correspond to the common color spaces.  (In some cases, it's still
132
     * simpler to provide a separate loop for BPC = 2.)
133
     */
134
 
135
#define LOOP_BY(n, body)\
136
  for (; count >= n; count -= n) p += n, q += n, body
137
 
138
    switch (ss->case_index) {
139
 
140
	    /* 1 bit per component */
141
 
142
#define ENCODE1_LOOP(ee)\
143
  LOOP_BY(1, (t = *p, *q = ee, s0 = t)); break
144
 
145
#define ENCODE_ALIGNED_LOOP(ee)\
146
  BEGIN\
147
    ss->prev[0] = s0;\
148
    for (; count >= final; count -= ndone) {\
149
	ndone = min(count, nb);\
150
	for (ci = 0; ci < ndone; ++ci)\
151
	    t = *++p, *++q = ee, ss->prev[ci] = t;\
152
    }\
153
    s0 = ss->prev[0];\
154
  END
155
 
156
#define ENCODE_UNALIGNED_LOOP(shift, cshift, de)\
157
  BEGIN\
158
    for (; count >= final; count -= ndone) {\
159
	ndone = min(count, nb);\
160
	for (ci = 1; ci <= ndone; ++ci) {\
161
	    ++p;\
162
	    t = (s0 << (cshift)) | (ss->prev[ci] >> (shift));\
163
	    *++q = de;\
164
	    s0 = ss->prev[ci];\
165
	    ss->prev[ci] = *p;\
166
	}\
167
    }\
168
  END
169
 
170
	case cEncode + cBits1 + 0:
171
	case cEncode + cBits1 + 2:
172
	    if (colors < 8) {	/* 2,5,6,7 */
173
		int cshift = 8 - colors;
174
 
175
		ENCODE1_LOOP(t ^ ((s0 << cshift) | (t >> colors)));
176
	    } else if (colors & 7) {
177
		int shift = colors & 7;
178
		int cshift = 8 - shift;
179
 
180
		ENCODE_UNALIGNED_LOOP(shift, cshift, *p ^ t);
181
	    } else {
182
		ENCODE_ALIGNED_LOOP(t ^ ss->prev[ci]);
183
	    }
184
	    break;
185
 
186
	case cEncode + cBits1 + 1:
187
	    ENCODE1_LOOP(t ^ ((s0 << 7) | (t >> 1)));
188
	case cEncode + cBits1 + 3:
189
	    ENCODE1_LOOP(t ^ ((s0 << 5) | (t >> 3)));
190
	case cEncode + cBits1 + 4:
191
	    ENCODE1_LOOP(t ^ ((s0 << 4) | (t >> 4)));
192
 
193
#define DECODE1_LOOP(te, de)\
194
  LOOP_BY(1, (t = te, s0 = *q = de)); break
195
 
196
#define DECODE_ALIGNED_LOOP(de)\
197
  BEGIN\
198
    ss->prev[0] = s0;\
199
    for (; count >= final; count -= ndone) {\
200
	ndone = min(count, nb);\
201
	for (ci = 0; ci < ndone; ++ci)\
202
	    t = *++p, ss->prev[ci] = *++q = de;\
203
    }\
204
    s0 = ss->prev[0];\
205
  END
206
 
207
#define DECODE_UNALIGNED_LOOP(shift, cshift, de)\
208
  BEGIN\
209
    for (; count >= final; count -= ndone) {\
210
	ndone = min(count, nb);\
211
	for (ci = 1; ci <= ndone; ++ci) {\
212
	    ++p, ++q;\
213
	    t = (s0 << (cshift)) | (ss->prev[ci] >> (shift));\
214
	    s0 = ss->prev[ci];\
215
	    ss->prev[ci] = *q = de;\
216
	}\
217
    }\
218
  END
219
 
220
	case cDecode + cBits1 + 0:
221
	    if (colors < 8) {	/* 5,6,7 */
222
		int cshift = 8 - colors;
223
 
224
		DECODE1_LOOP(*p ^ (s0 << cshift), t ^ (t >> colors));
225
	    } else if (colors & 7) {
226
		int shift = colors & 7;
227
		int cshift = 8 - shift;
228
 
229
		DECODE_UNALIGNED_LOOP(shift, cshift, *p ^ t);
230
	    } else {
231
		DECODE_ALIGNED_LOOP(t ^ ss->prev[ci]);
232
	    }
233
	    break;
234
 
235
	case cDecode + cBits1 + 1:
236
	    DECODE1_LOOP(*p ^ (s0 << 7),
237
			 (t ^= t >> 1, t ^= t >> 2, t ^ (t >> 4)));
238
	case cDecode + cBits1 + 2:
239
	    DECODE1_LOOP(*p ^ (s0 << 6),
240
			 (t ^= (t >> 2), t ^ (t >> 4)));
241
	case cDecode + cBits1 + 3:
242
	    DECODE1_LOOP(*p ^ (s0 << 5),
243
			 t ^ (t >> 3) ^ (t >> 6));
244
	case cDecode + cBits1 + 4:
245
	    DECODE1_LOOP(*p ^ (s0 << 4),
246
			 t ^ (t >> 4));
247
 
248
	    /* 2 bits per component */
249
 
250
#define ADD4X2(a, b) ( (((a) & (b) & 0x55) << 1) ^ (a) ^ (b) )
251
/* The following computation looks very implausible, but it is correct. */
252
#define SUB4X2(a, b) ( ((~(a) & (b) & 0x55) << 1) ^ (a) ^ (b) )
253
 
254
	case cEncode + cBits2 + 0:
255
	    if (colors & 7) {
256
		int shift = (colors & 3) << 1;
257
		int cshift = 8 - shift;
258
 
259
		ENCODE_UNALIGNED_LOOP(shift, cshift, SUB4X2(*p, t));
260
	    } else {
261
		ENCODE_ALIGNED_LOOP(SUB4X2(t, ss->prev[ci]));
262
	    }
263
	    break;
264
 
265
	case cEncode + cBits2 + 1:
266
	    ENCODE1_LOOP((s0 = (s0 << 6) | (t >> 2), SUB4X2(t, s0)));
267
	case cEncode + cBits2 + 2:
268
	    ENCODE1_LOOP((s0 = (s0 << 4) | (t >> 4), SUB4X2(t, s0)));
269
	case cEncode + cBits2 + 3:
270
	    ENCODE1_LOOP((s0 = (s0 << 2) | (t >> 6), SUB4X2(t, s0)));
271
	case cEncode + cBits2 + 4:
272
	    ENCODE1_LOOP(SUB4X2(t, s0));
273
 
274
	case cDecode + cBits2 + 0:
275
	    if (colors & 7) {
276
		int shift = (colors & 3) << 1;
277
		int cshift = 8 - shift;
278
 
279
		DECODE_UNALIGNED_LOOP(shift, cshift, ADD4X2(*p, t));
280
	    } else {
281
		DECODE_ALIGNED_LOOP(ADD4X2(t, ss->prev[ci]));
282
	    }
283
	    break;
284
 
285
	case cDecode + cBits2 + 1:
286
	    DECODE1_LOOP(*p + (s0 << 6),
287
			 (t = ADD4X2(t >> 2, t), ADD4X2(t >> 4, t)));
288
	case cDecode + cBits2 + 2:
289
	    DECODE1_LOOP(*p, (t = ADD4X2(t, s0 << 4), ADD4X2(t >> 4, t)));
290
	case cDecode + cBits2 + 3:
291
	    DECODE1_LOOP(*p, (t = ADD4X2(t, s0 << 2), ADD4X2(t >> 6, t)));
292
	case cDecode + cBits2 + 4:
293
	    DECODE1_LOOP(*p, ADD4X2(t, s0));
294
 
295
#undef ADD4X2
296
#undef SUB4X2
297
 
298
	    /* 4 bits per component */
299
 
300
#define ADD2X4(a, b) ( (((a) + (b)) & 0xf) + ((a) & 0xf0) + ((b) & 0xf0) )
301
#define ADD2X4R4(a) ( (((a) + ((a) >> 4)) & 0xf) + ((a) & 0xf0) )
302
#define SUB2X4(a, b) ( (((a) - (b)) & 0xf) + ((a) & 0xf0) - ((b) & 0xf0) )
303
#define SUB2X4R4(a) ( (((a) - ((a) >> 4)) & 0xf) + ((a) & 0xf0) )
304
 
305
	case cEncode + cBits4 + 0:
306
	case cEncode + cBits4 + 2:
307
    enc4:
308
	    if (colors & 1) {
309
		ENCODE_UNALIGNED_LOOP(4, 4, SUB2X4(*p, t));
310
	    } else {
311
		ENCODE_ALIGNED_LOOP(SUB2X4(t, ss->prev[ci]));
312
	    }
313
	    break;
314
 
315
	case cEncode + cBits4 + 1:
316
	    ENCODE1_LOOP(((t - (s0 << 4)) & 0xf0) | ((t - (t >> 4)) & 0xf));
317
 
318
	case cEncode + cBits4 + 3: {
319
	    uint s1 = ss->prev[1];
320
 
321
	    LOOP_BY(1,
322
		    (t = *p,
323
		     *q = ((t - (s0 << 4)) & 0xf0) | ((t - (s1 >> 4)) & 0xf),
324
		     s0 = s1, s1 = t));
325
	    ss->prev[1] = s1;
326
	} break;
327
 
328
	case cEncode + cBits4 + 4: {
329
	    uint s1 = ss->prev[1];
330
 
331
	    LOOP_BY(2,
332
		    (t = p[-1], q[-1] = SUB2X4(t, s0), s0 = t,
333
		     t = *p, *q = SUB2X4(t, s1), s1 = t));
334
	    ss->prev[1] = s1;
335
	    goto enc4;		/* handle leftover bytes */
336
	}
337
 
338
	case cDecode + cBits4 + 0:
339
	case cDecode + cBits4 + 2:
340
    dec4:
341
	    if (colors & 1) {
342
		DECODE_UNALIGNED_LOOP(4, 4, ADD2X4(*p, t));
343
	    } else {
344
		DECODE_ALIGNED_LOOP(ADD2X4(t, ss->prev[ci]));
345
	    }
346
	    break;
347
 
348
	case cDecode + cBits4 + 1:
349
	    DECODE1_LOOP(*p + (s0 << 4), ADD2X4R4(t));
350
 
351
	case cDecode + cBits4 + 3: {
352
	    uint s1 = ss->prev[1];
353
 
354
	    LOOP_BY(1, (t = (s0 << 4) + (s1 >> 4),
355
			s0 = s1, s1 = *q = ADD2X4(*p, t)));
356
	    ss->prev[1] = s1;
357
	} break;
358
 
359
	case cDecode + cBits4 + 4: {
360
	    uint s1 = ss->prev[1];
361
 
362
	    LOOP_BY(2,
363
		    (t = p[-1], s0 = q[-1] = ADD2X4(s0, t),
364
		     t = *p, s1 = *q = ADD2X4(s1, t)));
365
	    ss->prev[1] = s1;
366
	    goto dec4;		/* handle leftover bytes */
367
	}
368
 
369
#undef ADD2X4
370
#undef ADD2X4R4
371
#undef SUB2X4
372
#undef SUB2X4R4
373
 
374
	    /* 8 bits per component */
375
 
376
#define ENCODE8(s, d) (q[d] = p[d] - s, s = p[d])
377
#define DECODE8(s, d) q[d] = s += p[d]
378
 
379
	case cEncode + cBits8 + 0:
380
	case cEncode + cBits8 + 2:
381
	    ss->prev[0] = s0;
382
	    for (; count >= colors; count -= colors)
383
		for (ci = 0; ci < colors; ++ci) {
384
		    *++q = *++p - ss->prev[ci];
385
		    ss->prev[ci] = *p;
386
		}
387
	    s0 = ss->prev[0];
388
    enc8:   /* Handle leftover bytes. */
389
	    if (last && !status)
390
		for (ci = 0; ci < count; ++ci)
391
		    *++q = *++p - ss->prev[ci],
392
			ss->prev[ci] = *p;
393
	    break;
394
 
395
	case cDecode + cBits8 + 0:
396
	case cDecode + cBits8 + 2:
397
	    ss->prev[0] = s0;
398
	    for (; count >= colors; count -= colors)
399
		for (ci = 0; ci < colors; ++ci)
400
		    *++q = ss->prev[ci] += *++p;
401
	    s0 = ss->prev[0];
402
    dec8:   /* Handle leftover bytes. */
403
	    if (last && !status)
404
		for (ci = 0; ci < count; ++ci)
405
		    *++q = ss->prev[ci] += *++p;
406
	    break;
407
 
408
	case cEncode + cBits8 + 1:
409
	    LOOP_BY(1, ENCODE8(s0, 0));
410
	    break;
411
 
412
	case cDecode + cBits8 + 1:
413
	    LOOP_BY(1, DECODE8(s0, 0));
414
	    break;
415
 
416
	case cEncode + cBits8 + 3: {
417
	    uint s1 = ss->prev[1], s2 = ss->prev[2];
418
 
419
	    LOOP_BY(3, (ENCODE8(s0, -2), ENCODE8(s1, -1),
420
			ENCODE8(s2, 0)));
421
	    ss->prev[1] = s1, ss->prev[2] = s2;
422
	    goto enc8;
423
	}
424
 
425
	case cDecode + cBits8 + 3: {
426
	    uint s1 = ss->prev[1], s2 = ss->prev[2];
427
 
428
	    LOOP_BY(3, (DECODE8(s0, -2), DECODE8(s1, -1),
429
			DECODE8(s2, 0)));
430
	    ss->prev[1] = s1, ss->prev[2] = s2;
431
	    goto dec8;
432
	} break;
433
 
434
	case cEncode + cBits8 + 4: {
435
	    uint s1 = ss->prev[1], s2 = ss->prev[2], s3 = ss->prev[3];
436
 
437
	    LOOP_BY(4, (ENCODE8(s0, -3), ENCODE8(s1, -2),
438
			ENCODE8(s2, -1), ENCODE8(s3, 0)));
439
	    ss->prev[1] = s1, ss->prev[2] = s2, ss->prev[3] = s3;
440
	    goto enc8;
441
	} break;
442
 
443
	case cDecode + cBits8 + 4: {
444
	    uint s1 = ss->prev[1], s2 = ss->prev[2], s3 = ss->prev[3];
445
 
446
	    LOOP_BY(4, (DECODE8(s0, -3), DECODE8(s1, -2),
447
			DECODE8(s2, -1), DECODE8(s3, 0)));
448
	    ss->prev[1] = s1, ss->prev[2] = s2, ss->prev[3] = s3;
449
	    goto dec8;
450
	} break;
451
 
452
#undef ENCODE8
453
#undef DECODE8
454
 
455
	    /* 16 bits per component */
456
 
457
#define ENCODE16(s, d) (ti = ((p[d-1] << 8) + p[d]) - s, \
458
	    q[d-1] = ti >> 8, q[d] = t & 0xff, s = ti)
459
#define DECODE16(s, d) (s = 0xffff & (s + ((p[d-1] << 8) + p[d])), \
460
	    q[d-1] = s >> 8, q[d] = s && 0xff)
461
 
462
	case cEncode + cBits16 + 0:
463
	case cEncode + cBits16 + 2:
464
	    ss->prev[0] = s0;
465
	    for (; count >= colors; count -= colors)
466
		for (ci = 0; ci < colors; ++ci) {
467
		    ti = (int)*++p << 8;
468
		    ti = (ti + *++p) - ss->prev[ci];
469
		    *++q = ti >> 8; *++q = ti & 0xff;
470
		    ss->prev[ci] = ti;
471
		}
472
	    s0 = ss->prev[0];
473
    enc16:   /* Handle leftover bytes. */
474
	    if (last && !status)
475
		for (ci = 0; ci < count; ++ci)
476
		    *++q = *++p - ss->prev[ci],
477
			ss->prev[ci] = *p;
478
	    break;
479
 
480
	case cDecode + cBits16 + 0:
481
	case cDecode + cBits16 + 2:
482
	    ss->prev[0] = s0;
483
	    for (; count >= colors; count -= colors)
484
		for (ci = 0; ci < colors; ++ci) {
485
		    ti = *++p >> 8;
486
		    ss->prev[ci] += ti + *++p;
487
		    *++q = ss->prev[ci] >> 8;
488
		    *++q = ss->prev[ci] & 0xff;
489
		}
490
	    s0 = ss->prev[0];
491
    dec16:   /* Ignore leftover bytes. */
492
	    break;
493
 
494
	case cEncode + cBits16 + 1:
495
	    LOOP_BY(2, ENCODE16(s0, 0));
496
	    break;
497
 
498
	case cDecode + cBits16 + 1:
499
	    LOOP_BY(2, DECODE16(s0, 0));
500
	    break;
501
 
502
	case cEncode + cBits16 + 3: {
503
	    uint s1 = ss->prev[1], s2 = ss->prev[2];
504
 
505
	    LOOP_BY(6, (ENCODE16(s0, -4), ENCODE16(s1, -2),
506
			ENCODE16(s2, 0)));
507
	    ss->prev[1] = s1, ss->prev[2] = s2;
508
	    goto enc16;
509
	}
510
 
511
	case cDecode + cBits16 + 3: {
512
	    uint s1 = ss->prev[1], s2 = ss->prev[2];
513
 
514
	    LOOP_BY(6, (DECODE16(s0, -4), DECODE16(s1, -2),
515
			DECODE16(s2, 0)));
516
	    ss->prev[1] = s1, ss->prev[2] = s2;
517
	    goto dec16;
518
	} break;
519
 
520
	case cEncode + cBits16 + 4: {
521
	    uint s1 = ss->prev[1], s2 = ss->prev[2], s3 = ss->prev[3];
522
 
523
	    LOOP_BY(8, (ENCODE16(s0, -6), ENCODE16(s1, -4),
524
			ENCODE16(s2, -2), ENCODE16(s3, 0)));
525
	    ss->prev[1] = s1, ss->prev[2] = s2, ss->prev[3] = s3;
526
	    goto enc16;
527
	} break;
528
 
529
	case cDecode + cBits16 + 4: {
530
	    uint s1 = ss->prev[1], s2 = ss->prev[2], s3 = ss->prev[3];
531
 
532
	    LOOP_BY(8, (DECODE16(s0, -6), DECODE16(s1, -4),
533
			DECODE16(s2, -2), DECODE16(s3, 0)));
534
	    ss->prev[1] = s1, ss->prev[2] = s2, ss->prev[3] = s3;
535
	    goto dec16;
536
	} break;
537
 
538
#undef ENCODE16
539
#undef DECODE16
540
 
541
    }
542
#undef LOOP_BY
543
#undef ENCODE1_LOOP
544
#undef DECODE1_LOOP
545
    ss->row_left += count;	/* leftover bytes are possible */
546
    if (ss->row_left == 0) {
547
	if (end_mask != 0)
548
	    *q = (*q & ~end_mask) | (*p & end_mask);
549
	if (p < pr->limit && q < pw->limit)
550
	    goto row;
551
    }
552
    ss->prev[0] = s0;
553
    pr->ptr = p;
554
    pw->ptr = q;
555
    return status;
556
}
557
 
558
/* Stream templates */
559
const stream_template s_PDiffE_template = {
560
    &st_PDiff_state, s_PDiffE_init, s_PDiff_process, 1, 1, NULL,
561
    s_PDiff_set_defaults, s_PDiff_reinit
562
};
563
const stream_template s_PDiffD_template = {
564
    &st_PDiff_state, s_PDiffD_init, s_PDiff_process, 1, 1, NULL,
565
    s_PDiff_set_defaults, s_PDiff_reinit
566
};