1/*
2 * "$Id: bit-ops.c,v 1.14 2009/06/07 15:21:22 rlk Exp $"
3 *
4 *   Softweave calculator for Gutenprint.
5 *
6 *   Copyright 2000 Charles Briscoe-Smith <cpbs@debian.org>
7 *
8 *   This program is free software; you can redistribute it and/or modify it
9 *   under the terms of the GNU General Public License as published by the Free
10 *   Software Foundation; either version 2 of the License, or (at your option)
11 *   any later version.
12 *
13 *   This program is distributed in the hope that it will be useful, but
14 *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 *   for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22
23/*
24 * This file must include only standard C header files.  The core code must
25 * compile on generic platforms that don't support glib, gimp, gtk, etc.
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include <string.h>
32#include <gutenprint/gutenprint.h>
33#include "gutenprint-internal.h"
34#include <gutenprint/gutenprint-intl-internal.h>
35#ifdef HAVE_LIMITS_H
36#include <limits.h>
37#endif
38
39void
40stp_fold(const unsigned char *line,
41	 int single_length,
42	 unsigned char *outbuf)
43{
44  int i;
45  memset(outbuf, 0, single_length * 2);
46  for (i = 0; i < single_length; i++)
47    {
48      unsigned char l0 = line[0];
49      unsigned char l1 = line[single_length];
50      if (l0 || l1)
51	{
52	  outbuf[0] =		/* B7 A7 B6 A6 B5 A5 B4 A4 */
53	    ((l0 & (1 << 7)) >> 1) +
54	    ((l0 & (1 << 6)) >> 2) +
55	    ((l0 & (1 << 5)) >> 3) +
56	    ((l0 & (1 << 4)) >> 4) +
57	    ((l1 & (1 << 7)) >> 0) +
58	    ((l1 & (1 << 6)) >> 1) +
59	    ((l1 & (1 << 5)) >> 2) +
60	    ((l1 & (1 << 4)) >> 3);
61	  outbuf[1] =		/* B3 A3 B2 A2 B1 A1 B0 A0 */
62	    ((l0 & (1 << 3)) << 3) +
63	    ((l0 & (1 << 2)) << 2) +
64	    ((l0 & (1 << 1)) << 1) +
65	    ((l0 & (1 << 0)) << 0) +
66	    ((l1 & (1 << 3)) << 4) +
67	    ((l1 & (1 << 2)) << 3) +
68	    ((l1 & (1 << 1)) << 2) +
69	    ((l1 & (1 << 0)) << 1);
70	}
71      line++;
72      outbuf += 2;
73    }
74}
75
76void
77stp_fold_3bit(const unsigned char *line,
78                int single_length,
79                unsigned char *outbuf)
80{
81  int i;
82  memset(outbuf, 0, single_length * 3);
83  for (i = 0; i < single_length; i++)
84    {
85      unsigned char l0 = line[0];
86      unsigned char l1 = line[single_length];
87      unsigned char l2 = line[single_length * 2];
88      if (l0 || l1 || l2)
89	{
90	  outbuf[0] =		/* C7 B7 A7 C6 B6 A6 C5 B5  */
91	    ((l0 & (1 << 7)) >> 2) |
92	    ((l0 & (1 << 6)) >> 4) |
93	    ((l1 & (1 << 7)) >> 1) |
94	    ((l1 & (1 << 6)) >> 3) |
95	    ((l1 & (1 << 5)) >> 5) |
96	    ((l2 & (1 << 7)) << 0) |
97	    ((l2 & (1 << 6)) >> 2) |
98	    ((l2 & (1 << 5)) >> 4);
99	  outbuf[1] =		/* A5 C4 B4 A4 C3 B3 A3 C2 */
100	    ((l0 & (1 << 5)) << 2) |
101	    ((l0 & (1 << 4)) << 0) |
102	    ((l0 & (1 << 3)) >> 2) |
103	    ((l1 & (1 << 4)) << 1) |
104	    ((l1 & (1 << 3)) >> 1) |
105	    ((l2 & (1 << 4)) << 2) |
106	    ((l2 & (1 << 3)) << 0) |
107	    ((l2 & (1 << 2)) >> 2);
108	  outbuf[2] =		/* B2 A2 C1 B1 A1 C0 B0 A0 */
109	    ((l0 & (1 << 2)) << 4) |
110	    ((l0 & (1 << 1)) << 2) |
111	    ((l0 & (1 << 0)) << 0) |
112	    ((l1 & (1 << 2)) << 5) |
113	    ((l1 & (1 << 1)) << 3) |
114	    ((l1 & (1 << 0)) << 1) |
115	    ((l2 & (1 << 1)) << 4) |
116	    ((l2 & (1 << 0)) << 2);
117	}
118    line++;
119    outbuf += 3;
120  }
121}
122
123void
124stp_fold_3bit_323(const unsigned char *line,
125		  int single_length,
126		  unsigned char *outbuf)
127{
128  const unsigned char *last= line + single_length;
129  memset(outbuf, 0, single_length * 3);
130  for (; line < last; line += 3)
131    {
132      unsigned char A0 = line[0];
133      unsigned char B0 = line[single_length];
134      unsigned char C0 = line[2*single_length];
135      unsigned char A1 = (line < last - 2) ? line[1] : 0;
136      unsigned char B1 = (line < last - 2) ? line[single_length + 1] : 0;
137      unsigned char C1 = (line < last - 2) ? line[(single_length * 2) + 1] : 0;
138      unsigned char A2 = (line < last - 1) ? line[2] : 0;
139      unsigned char B2 = (line < last - 1) ? line[single_length + 2] : 0;
140      unsigned char C2 = (line < last - 1) ? line[(single_length * 2) + 2] : 0;
141
142      if (A0 || A1 || A2 || B0 || B1 || B2 || C0 || C1 || C2)
143	{
144	  /* Missing: C0_6, C0_3, C0_0, C1_5, C1_2, C2_7, C2_4, C2_1 ??? */
145	  outbuf[0] =		/* C0_7 B0_7 A0_7 B0_6 A0_6 C0_5 B0_5 A0_5 */
146	    ((C0 & (1 << 7)) >> 0) |
147	    ((B0 & (1 << 7)) >> 1) |
148	    ((A0 & (1 << 7)) >> 2) |
149	    ((B0 & (1 << 6)) >> 2) |
150	    ((A0 & (1 << 6)) >> 3) |
151	    ((C0 & (1 << 5)) >> 3) |
152	    ((B0 & (1 << 5)) >> 4) |
153	    ((A0 & (1 << 5)) >> 5);
154	  outbuf[1] =		/* C0_4 B0_4 A0_4 B0_3 A0_3 C0_2 B0_2 A0_2 */
155	    ((C0 & (1 << 4)) << 3) |
156	    ((B0 & (1 << 4)) << 2) |
157	    ((A0 & (1 << 4)) << 1) |
158	    ((B0 & (1 << 3)) << 1) |
159	    ((A0 & (1 << 3)) << 0) |
160	    ((C0 & (1 << 2)) >> 0) |
161	    ((B0 & (1 << 2)) >> 1) |
162	    ((A0 & (1 << 2)) >> 2);
163	  outbuf[2] =		/* C0_1 B0_1 A0_1 B0_0 A0_0 C1_7 B1_7 A1_7 */
164	    ((C0 & (1 << 1)) << 6) |
165	    ((B0 & (1 << 1)) << 5) |
166	    ((A0 & (1 << 1)) << 4) |
167	    ((B0 & (1 << 0)) << 4) |
168	    ((A0 & (1 << 0)) << 3) |
169	    ((C1 & (1 << 7)) >> 5) |
170	    ((B1 & (1 << 7)) >> 6) |
171	    ((A1 & (1 << 7)) >> 7);
172	  outbuf[3] =		/* C1_6 B1_6 A1_6 B1_5 A1_5 C1_4 B1_4 A1_4 */
173	    ((C1 & (1 << 6)) << 1) |
174	    ((B1 & (1 << 6)) << 0) |
175	    ((A1 & (1 << 6)) >> 1) |
176	    ((B1 & (1 << 5)) >> 1) |
177	    ((A1 & (1 << 5)) >> 2) |
178	    ((C1 & (1 << 4)) >> 2) |
179	    ((B1 & (1 << 4)) >> 3) |
180	    ((A1 & (1 << 4)) >> 4);
181	  outbuf[4] =		/* C1_3 B1_3 A1_3 B1_2 A1_2 C1_1 B1_1 A1_1 */
182	    ((C1 & (1 << 3)) << 4) |
183	    ((B1 & (1 << 3)) << 3) |
184	    ((A1 & (1 << 3)) << 2) |
185	    ((B1 & (1 << 2)) << 2) |
186	    ((A1 & (1 << 2)) << 1) |
187	    ((C1 & (1 << 1)) << 1) |
188	    ((B1 & (1 << 1)) >> 0) |
189	    ((A1 & (1 << 1)) >> 1);
190	  outbuf[5] =		/* C1_0 B1_0 A1_0 B2_7 A2_7 C2_6 B2_6 A2_6 */
191	    ((C1 & (1 << 0)) << 7) |
192	    ((B1 & (1 << 0)) << 6) |
193	    ((A1 & (1 << 0)) << 5) |
194	    ((B2 & (1 << 7)) >> 3) |
195	    ((A2 & (1 << 7)) >> 4) |
196	    ((C2 & (1 << 6)) >> 4) |
197	    ((B2 & (1 << 6)) >> 5) |
198	    ((A2 & (1 << 6)) >> 6);
199	  outbuf[6] =		/* C2_5 B2_5 A2_5 B2_4 A2_4 C2_3 B2_3 A2_3 */
200	    ((C2 & (1 << 5)) << 2) |
201	    ((B2 & (1 << 5)) << 1) |
202	    ((A2 & (1 << 5)) << 0) |
203	    ((B2 & (1 << 4)) >> 0) |
204	    ((A2 & (1 << 4)) >> 1) |
205	    ((C2 & (1 << 3)) >> 1) |
206	    ((B2 & (1 << 3)) >> 2) |
207	    ((A2 & (1 << 3)) >> 3);
208	  outbuf[7] =		/* C2_2 B2_2 A2_2 B2_1 A2_1 C2_0 B2_0 A2_0 */
209	    ((C2 & (1 << 2)) << 5) |
210	    ((B2 & (1 << 2)) << 4) |
211	    ((A2 & (1 << 2)) << 3) |
212	    ((B2 & (1 << 1)) << 3) |
213	    ((A2 & (1 << 1)) << 2) |
214	    ((C2 & (1 << 0)) << 2) |
215	    ((B2 & (1 << 0)) << 1) |
216	    ((A2 & (1 << 0)) << 0);
217	}
218      outbuf += 8;
219    }
220}
221
222void
223stp_fold_4bit(const unsigned char *line,
224                int single_length,
225                unsigned char *outbuf)
226{
227  int i;
228  memset(outbuf, 0, single_length * 4);
229  for (i = 0; i < single_length; i++)
230    {
231      unsigned char l0 = line[0];
232      unsigned char l1 = line[single_length];
233      unsigned char l2 = line[single_length*2];
234      unsigned char l3 = line[single_length*3];
235      if (l0 || l1 || l2 || l3)
236	{
237	  outbuf[0] =		/* D7 C7 B7 A7 D6 C6 B6 A6 */
238            ((l3 & (1 << 7)) >> 0)|
239            ((l2 & (1 << 7)) >> 1)|
240            ((l1 & (1 << 7)) >> 2)|
241            ((l0 & (1 << 7)) >> 3)|
242            ((l3 & (1 << 6)) >> 3)|
243            ((l2 & (1 << 6)) >> 4)|
244            ((l1 & (1 << 6)) >> 5)|
245            ((l0 & (1 << 6)) >> 6);
246
247	  outbuf[1] =		/* D5 C5 B5 A5 D4 C4 B4 A4 */
248            ((l3 & (1 << 5)) << 2)|
249            ((l2 & (1 << 5)) << 1)|
250            ((l1 & (1 << 5)) << 0)|
251            ((l0 & (1 << 5)) >> 1)|
252            ((l3 & (1 << 4)) >> 1)|
253            ((l2 & (1 << 4)) >> 2)|
254            ((l1 & (1 << 4)) >> 3)|
255            ((l0 & (1 << 4)) >> 4);
256
257	  outbuf[2] =		/* D3 C3 B3 A3 D2 C2 B2 A2 */
258            ((l3 & (1 << 3)) << 4)|
259            ((l2 & (1 << 3)) << 3)|
260            ((l1 & (1 << 3)) << 2)|
261            ((l0 & (1 << 3)) << 1)|
262            ((l3 & (1 << 2)) << 1)|
263            ((l2 & (1 << 2)) << 0)|
264            ((l1 & (1 << 2)) >> 1)|
265            ((l0 & (1 << 2)) >> 2);
266
267	  outbuf[3] =		/* D1 C1 B1 A1 D0 C0 B0 A0 */
268            ((l3 & (1 << 1)) << 6)|
269            ((l2 & (1 << 1)) << 5)|
270            ((l1 & (1 << 1)) << 4)|
271            ((l0 & (1 << 1)) << 3)|
272            ((l3 & (1 << 0)) << 3)|
273            ((l2 & (1 << 0)) << 2)|
274            ((l1 & (1 << 0)) << 1)|
275            ((l0 & (1 << 0)) << 0);
276	}
277      line++;
278      outbuf += 4;
279    }
280}
281
282#define SPLIT_MASK(k, b) (((1 << (b)) - 1) << ((k) * (b)))
283
284#define SPLIT_STEP(k, b, i, o, in, r, inc, rl)	\
285do						\
286  {						\
287    if (in & SPLIT_MASK(k, b))			\
288      {						\
289	o[r][i] |= SPLIT_MASK(k, b) & in;	\
290	r += inc;				\
291	if (r >= rl)				\
292	  r = 0;				\
293      }						\
294  } while (0)
295
296void
297stp_split(int length,
298	  int bits,
299	  int n,
300	  const unsigned char *in,
301	  int increment,
302	  unsigned char **outs)
303{
304  int row = 0;
305  int limit = length * bits;
306  int rlimit = n * increment;
307  int i;
308  for (i = 1; i < n; i++)
309    memset(outs[i * increment], 0, limit);
310
311  if (bits == 1)
312    {
313      for (i = 0; i < limit; i++)
314	{
315	  unsigned char inbyte = in[i];
316	  outs[0][i] = 0;
317	  if (inbyte == 0)
318	    continue;
319	  /* For some reason gcc isn't unrolling this, even with -funroll-loops */
320	  SPLIT_STEP(0, 1, i, outs, inbyte, row, increment, rlimit);
321	  SPLIT_STEP(1, 1, i, outs, inbyte, row, increment, rlimit);
322	  SPLIT_STEP(2, 1, i, outs, inbyte, row, increment, rlimit);
323	  SPLIT_STEP(3, 1, i, outs, inbyte, row, increment, rlimit);
324	  SPLIT_STEP(4, 1, i, outs, inbyte, row, increment, rlimit);
325	  SPLIT_STEP(5, 1, i, outs, inbyte, row, increment, rlimit);
326	  SPLIT_STEP(6, 1, i, outs, inbyte, row, increment, rlimit);
327	  SPLIT_STEP(7, 1, i, outs, inbyte, row, increment, rlimit);
328	}
329    }
330  else
331    {
332      for (i = 0; i < limit; i++)
333	{
334	  unsigned char inbyte = in[i];
335	  outs[0][i] = 0;
336	  if (inbyte == 0)
337	    continue;
338	  /* For some reason gcc isn't unrolling this, even with -funroll-loops */
339	  SPLIT_STEP(0, 2, i, outs, inbyte, row, increment, rlimit);
340	  SPLIT_STEP(1, 2, i, outs, inbyte, row, increment, rlimit);
341	  SPLIT_STEP(2, 2, i, outs, inbyte, row, increment, rlimit);
342	  SPLIT_STEP(3, 2, i, outs, inbyte, row, increment, rlimit);
343	}
344    }
345}
346
347void
348stp_split_2(int length,
349	    int bits,
350	    const unsigned char *in,
351	    unsigned char *outhi,
352	    unsigned char *outlo)
353{
354  unsigned char *outs[2];
355  outs[0] = outhi;
356  outs[1] = outlo;
357  stp_split(length, bits, 2, in, 1, outs);
358}
359
360void
361stp_split_4(int length,
362	    int bits,
363	    const unsigned char *in,
364	    unsigned char *out0,
365	    unsigned char *out1,
366	    unsigned char *out2,
367	    unsigned char *out3)
368{
369  unsigned char *outs[4];
370  outs[0] = out0;
371  outs[1] = out1;
372  outs[2] = out2;
373  outs[3] = out3;
374  stp_split(length, bits, 4, in, 1, outs);
375}
376
377
378static void
379stpi_unpack_2_1(int length,
380		const unsigned char *in,
381		unsigned char **outs)
382{
383  unsigned char	tempin, bit, temp0, temp1;
384
385  if (length <= 0)
386    return;
387  for (bit = 128, temp0 = 0, temp1 = 0;
388       length > 0;
389       length --)
390    {
391      tempin = *in++;
392
393      if (tempin & 128)
394        temp0 |= bit;
395      if (tempin & 64)
396        temp1 |= bit;
397      bit >>= 1;
398      if (tempin & 32)
399        temp0 |= bit;
400      if (tempin & 16)
401        temp1 |= bit;
402      bit >>= 1;
403      if (tempin & 8)
404        temp0 |= bit;
405      if (tempin & 4)
406        temp1 |= bit;
407      bit >>= 1;
408      if (tempin & 2)
409        temp0 |= bit;
410      if (tempin & 1)
411        temp1 |= bit;
412
413      if (bit > 1)
414        bit >>= 1;
415      else
416      {
417        bit     = 128;
418	*outs[0]++ = temp0;
419	*outs[1]++ = temp1;
420
421	temp0   = 0;
422	temp1   = 0;
423      }
424    }
425
426  if (bit < 128)
427    {
428      *outs[0]++ = temp0;
429      *outs[1]++ = temp1;
430    }
431}
432
433static void
434stpi_unpack_2_2(int length,
435		const unsigned char *in,
436		unsigned char **outs)
437{
438  if (length <= 0)
439    return;
440
441  for (;length;length --)
442    {
443      unsigned char ti0, ti1;
444      ti0 = in[0];
445      ti1 = in[1];
446
447      *outs[0]++  = (ti0 & 0xc0) << 0
448	| (ti0 & 0x0c) << 2
449	| (ti1 & 0xc0) >> 4
450	| (ti1 & 0x0c) >> 2;
451      *outs[1]++  = (ti0 & 0x30) << 2
452	| (ti0 & 0x03) << 4
453	| (ti1 & 0x30) >> 2
454	| (ti1 & 0x03) >> 0;
455      in += 2;
456    }
457}
458
459static void
460stpi_unpack_4_1(int length,
461		 const unsigned char *in,
462		 unsigned char **outs)
463{
464  unsigned char	tempin, bit, temp0, temp1, temp2, temp3;
465
466  if (length <= 0)
467    return;
468  for (bit = 128, temp0 = 0, temp1 = 0, temp2 = 0, temp3 = 0;
469       length > 0;
470       length --)
471    {
472      tempin = *in++;
473
474      if (tempin & 128)
475        temp0 |= bit;
476      if (tempin & 64)
477        temp1 |= bit;
478      if (tempin & 32)
479        temp2 |= bit;
480      if (tempin & 16)
481        temp3 |= bit;
482      bit >>= 1;
483      if (tempin & 8)
484        temp0 |= bit;
485      if (tempin & 4)
486        temp1 |= bit;
487      if (tempin & 2)
488        temp2 |= bit;
489      if (tempin & 1)
490        temp3 |= bit;
491
492      if (bit > 1)
493        bit >>= 1;
494      else
495      {
496        bit     = 128;
497	*outs[0]++ = temp0;
498	*outs[1]++ = temp1;
499	*outs[2]++ = temp2;
500	*outs[3]++ = temp3;
501
502	temp0   = 0;
503	temp1   = 0;
504	temp2   = 0;
505	temp3   = 0;
506      }
507    }
508
509  if (bit < 128)
510    {
511      *outs[0]++ = temp0;
512      *outs[1]++ = temp1;
513      *outs[2]++ = temp2;
514      *outs[3]++ = temp3;
515    }
516}
517
518static void
519stpi_unpack_4_2(int length,
520		 const unsigned char *in,
521		 unsigned char **outs)
522{
523  unsigned char	tempin,
524		shift,
525		temp0,
526		temp1,
527		temp2,
528		temp3;
529
530  length *= 2;
531
532  for (shift = 0, temp0 = 0, temp1 = 0, temp2 = 0, temp3 = 0;
533       length > 0;
534       length --)
535    {
536     /*
537      * Note - we can't use (tempin & N) >> (shift - M) since negative
538      * right-shifts are not always implemented.
539      */
540
541      tempin = *in++;
542
543      if (tempin & 192)
544        temp0 |= (tempin & 192) >> shift;
545      if (tempin & 48)
546        temp1 |= ((tempin & 48) << 2) >> shift;
547      if (tempin & 12)
548        temp2 |= ((tempin & 12) << 4) >> shift;
549      if (tempin & 3)
550        temp3 |= ((tempin & 3) << 6) >> shift;
551
552      if (shift < 6)
553        shift += 2;
554      else
555      {
556        shift   = 0;
557	*outs[0]++ = temp0;
558	*outs[1]++ = temp1;
559	*outs[2]++ = temp2;
560	*outs[3]++ = temp3;
561
562	temp0   = 0;
563	temp1   = 0;
564	temp2   = 0;
565	temp3   = 0;
566      }
567    }
568
569  if (shift)
570    {
571      *outs[0]++ = temp0;
572      *outs[1]++ = temp1;
573      *outs[2]++ = temp2;
574      *outs[3]++ = temp3;
575    }
576}
577
578static void
579stpi_unpack_8_1(int length,
580		const unsigned char *in,
581		unsigned char **outs)
582{
583  unsigned char	tempin, bit, temp0, temp1, temp2, temp3, temp4, temp5, temp6,
584    temp7;
585
586  if (length <= 0)
587    return;
588
589  for (bit = 128, temp0 = 0, temp1 = 0, temp2 = 0,
590       temp3 = 0, temp4 = 0, temp5 = 0, temp6 = 0, temp7 = 0;
591       length > 0;
592       length --)
593    {
594      tempin = *in++;
595
596      if (tempin & 128)
597        temp0 |= bit;
598      if (tempin & 64)
599        temp1 |= bit;
600      if (tempin & 32)
601        temp2 |= bit;
602      if (tempin & 16)
603        temp3 |= bit;
604      if (tempin & 8)
605        temp4 |= bit;
606      if (tempin & 4)
607        temp5 |= bit;
608      if (tempin & 2)
609        temp6 |= bit;
610      if (tempin & 1)
611        temp7 |= bit;
612
613      if (bit > 1)
614        bit >>= 1;
615      else
616      {
617        bit     = 128;
618	*outs[0]++ = temp0;
619	*outs[1]++ = temp1;
620	*outs[2]++ = temp2;
621	*outs[3]++ = temp3;
622	*outs[4]++ = temp4;
623	*outs[5]++ = temp5;
624	*outs[6]++ = temp6;
625	*outs[7]++ = temp7;
626
627	temp0   = 0;
628	temp1   = 0;
629	temp2   = 0;
630	temp3   = 0;
631	temp4   = 0;
632	temp5   = 0;
633	temp6   = 0;
634	temp7   = 0;
635      }
636    }
637
638  if (bit < 128)
639    {
640      *outs[0]++ = temp0;
641      *outs[1]++ = temp1;
642      *outs[2]++ = temp2;
643      *outs[3]++ = temp3;
644      *outs[4]++ = temp4;
645      *outs[5]++ = temp5;
646      *outs[6]++ = temp6;
647      *outs[7]++ = temp7;
648    }
649}
650
651static void
652stpi_unpack_8_2(int length,
653		const unsigned char *in,
654		unsigned char **outs)
655{
656  unsigned char	tempin,
657		shift,
658		temp0,
659		temp1,
660		temp2,
661		temp3,
662		temp4,
663		temp5,
664		temp6,
665		temp7;
666
667
668  for (shift = 0, temp0 = 0, temp1 = 0,
669       temp2 = 0, temp3 = 0, temp4 = 0, temp5 = 0, temp6 = 0, temp7 = 0;
670       length > 0;
671       length --)
672    {
673     /*
674      * Note - we can't use (tempin & N) >> (shift - M) since negative
675      * right-shifts are not always implemented.
676      */
677
678      tempin = *in++;
679
680      if (tempin & 192)
681        temp0 |= (tempin & 192) >> shift;
682      if (tempin & 48)
683        temp1 |= ((tempin & 48) << 2) >> shift;
684      if (tempin & 12)
685        temp2 |= ((tempin & 12) << 4) >> shift;
686      if (tempin & 3)
687        temp3 |= ((tempin & 3) << 6) >> shift;
688
689      tempin = *in++;
690
691      if (tempin & 192)
692        temp4 |= (tempin & 192) >> shift;
693      if (tempin & 48)
694        temp5 |= ((tempin & 48) << 2) >> shift;
695      if (tempin & 12)
696        temp6 |= ((tempin & 12) << 4) >> shift;
697      if (tempin & 3)
698        temp7 |= ((tempin & 3) << 6) >> shift;
699
700      if (shift < 6)
701        shift += 2;
702      else
703      {
704        shift   = 0;
705	*outs[0]++ = temp0;
706	*outs[1]++ = temp1;
707	*outs[2]++ = temp2;
708	*outs[3]++ = temp3;
709	*outs[4]++ = temp4;
710	*outs[5]++ = temp5;
711	*outs[6]++ = temp6;
712	*outs[7]++ = temp7;
713
714	temp0   = 0;
715	temp1   = 0;
716	temp2   = 0;
717	temp3   = 0;
718	temp4   = 0;
719	temp5   = 0;
720	temp6   = 0;
721	temp7   = 0;
722      }
723    }
724
725  if (shift)
726    {
727      *outs[0]++ = temp0;
728      *outs[1]++ = temp1;
729      *outs[2]++ = temp2;
730      *outs[3]++ = temp3;
731      *outs[4]++ = temp4;
732      *outs[5]++ = temp5;
733      *outs[6]++ = temp6;
734      *outs[7]++ = temp7;
735    }
736}
737
738static void
739stpi_unpack_16_1(int length,
740		 const unsigned char *in,
741		 unsigned char **outs)
742{
743  unsigned char	tempin, bit;
744  unsigned char temp[16];
745  int j;
746
747  if (length <= 0)
748    return;
749
750  memset(temp, 0, 16);
751
752  for (bit = 128; length > 0; length--)
753    {
754      tempin = *in++;
755
756      if (tempin & 128)
757        temp[0] |= bit;
758      if (tempin & 64)
759        temp[1] |= bit;
760      if (tempin & 32)
761        temp[2] |= bit;
762      if (tempin & 16)
763        temp[3] |= bit;
764      if (tempin & 8)
765        temp[4] |= bit;
766      if (tempin & 4)
767        temp[5] |= bit;
768      if (tempin & 2)
769        temp[6] |= bit;
770      if (tempin & 1)
771        temp[7] |= bit;
772
773      tempin = *in++;
774
775      if (tempin & 128)
776	temp[8] |= bit;
777      if (tempin & 64)
778	temp[9] |= bit;
779      if (tempin & 32)
780	temp[10] |= bit;
781      if (tempin & 16)
782	temp[11] |= bit;
783      if (tempin & 8)
784	temp[12] |= bit;
785      if (tempin & 4)
786	temp[13] |= bit;
787      if (tempin & 2)
788	temp[14] |= bit;
789      if (tempin & 1)
790	temp[15] |= bit;
791
792      if (bit > 1)
793        bit >>= 1;
794      else
795	{
796	  bit     = 128;
797	  for (j = 0; j < 16; j++)
798	    *outs[j]++ = temp[j];
799
800	  memset(temp, 0, 16);
801	}
802    }
803
804  if (bit < 128)
805    for (j = 0; j < 16; j++)
806      *outs[j]++ = temp[j];
807}
808
809static void
810stpi_unpack_16_2(int length,
811		 const unsigned char *in,
812		 unsigned char **outs)
813{
814  unsigned char	tempin, shift;
815  unsigned char temp[16];
816  int j;
817
818  if (length <= 0)
819    return;
820
821  memset(temp, 0, 16);
822
823  for (shift = 0; length > 0; length--)
824    {
825      /*
826       * Note - we can't use (tempin & N) >> (shift - M) since negative
827       * right-shifts are not always implemented.
828       */
829
830      tempin = *in++;
831
832      if (tempin & 192)
833        temp[0] |= (tempin & 192) >> shift;
834      if (tempin & 48)
835        temp[1] |= ((tempin & 48) << 2) >> shift;
836      if (tempin & 12)
837        temp[2] |= ((tempin & 12) << 4) >> shift;
838      if (tempin & 3)
839        temp[3] |= ((tempin & 3) << 6) >> shift;
840
841      tempin = *in++;
842
843      if (tempin & 192)
844        temp[4] |= (tempin & 192) >> shift;
845      if (tempin & 48)
846        temp[5] |= ((tempin & 48) << 2) >> shift;
847      if (tempin & 12)
848        temp[6] |= ((tempin & 12) << 4) >> shift;
849      if (tempin & 3)
850        temp[7] |= ((tempin & 3) << 6) >> shift;
851
852      if (length-- > 0)
853	{
854	  tempin = *in++;
855
856	  if (tempin & 192)
857	    temp[8] |= (tempin & 192) >> shift;
858	  if (tempin & 48)
859	    temp[9] |= ((tempin & 48) << 2) >> shift;
860	  if (tempin & 12)
861	    temp[10] |= ((tempin & 12) << 4) >> shift;
862	  if (tempin & 3)
863	    temp[11] |= ((tempin & 3) << 6) >> shift;
864
865	  tempin = *in++;
866
867	  if (tempin & 192)
868	    temp[12] |= (tempin & 192) >> shift;
869	  if (tempin & 48)
870	    temp[13] |= ((tempin & 48) << 2) >> shift;
871	  if (tempin & 12)
872	    temp[14] |= ((tempin & 12) << 4) >> shift;
873	  if (tempin & 3)
874	    temp[15] |= ((tempin & 3) << 6) >> shift;
875	}
876
877      if (shift < 6)
878        shift += 2;
879      else
880	{
881	  shift   = 0;
882	  for (j = 0; j < 16; j++)
883	    *outs[j]++ = temp[j];
884
885	  memset(temp, 0, 16);
886	}
887    }
888
889  if (shift)
890    for (j = 0; j < 16; j++)
891      *outs[j]++ = temp[j];
892}
893
894void
895stp_unpack(int length,
896	   int bits,
897	   int n,
898	   const unsigned char *in,
899	   unsigned char **outs)
900{
901  unsigned char **touts;
902  int i;
903  if (n < 2)
904    return;
905  touts = stp_malloc(sizeof(unsigned char *) * n);
906  for (i = 0; i < n; i++)
907    touts[i] = outs[i];
908  if (bits == 1)
909    switch (n)
910      {
911      case 2:
912	stpi_unpack_2_1(length, in, touts);
913	break;
914      case 4:
915	stpi_unpack_4_1(length, in, touts);
916	break;
917      case 8:
918	stpi_unpack_8_1(length, in, touts);
919	break;
920      case 16:
921	stpi_unpack_16_1(length, in, touts);
922	break;
923      }
924  else
925    switch (n)
926      {
927      case 2:
928	stpi_unpack_2_2(length, in, touts);
929	break;
930      case 4:
931	stpi_unpack_4_2(length, in, touts);
932	break;
933      case 8:
934	stpi_unpack_8_2(length, in, touts);
935	break;
936      case 16:
937	stpi_unpack_16_2(length, in, touts);
938	break;
939      }
940  stp_free(touts);
941}
942
943void
944stp_unpack_2(int length,
945	     int bits,
946	     const unsigned char *in,
947	     unsigned char *outhi,
948	     unsigned char *outlo)
949{
950  unsigned char *outs[2];
951  outs[0] = outhi;
952  outs[1] = outlo;
953  stp_unpack(length, bits, 2, in, outs);
954}
955
956void
957stp_unpack_4(int length,
958	     int bits,
959	     const unsigned char *in,
960	     unsigned char *out0,
961	     unsigned char *out1,
962	     unsigned char *out2,
963	     unsigned char *out3)
964{
965  unsigned char *outs[4];
966  outs[0] = out0;
967  outs[1] = out1;
968  outs[2] = out2;
969  outs[3] = out3;
970  stp_unpack(length, bits, 4, in, outs);
971}
972
973void
974stp_unpack_8(int length,
975	     int bits,
976	     const unsigned char *in,
977	     unsigned char *out0,
978	     unsigned char *out1,
979	     unsigned char *out2,
980	     unsigned char *out3,
981	     unsigned char *out4,
982	     unsigned char *out5,
983	     unsigned char *out6,
984	     unsigned char *out7)
985{
986  unsigned char *outs[8];
987  outs[0] = out0;
988  outs[1] = out1;
989  outs[2] = out2;
990  outs[3] = out3;
991  outs[4] = out4;
992  outs[5] = out5;
993  outs[6] = out6;
994  outs[7] = out7;
995  stp_unpack(length, bits, 8, in, outs);
996}
997
998void
999stp_unpack_16(int length,
1000	      int bits,
1001	      const unsigned char *in,
1002	      unsigned char *out0,
1003	      unsigned char *out1,
1004	      unsigned char *out2,
1005	      unsigned char *out3,
1006	      unsigned char *out4,
1007	      unsigned char *out5,
1008	      unsigned char *out6,
1009	      unsigned char *out7,
1010	      unsigned char *out8,
1011	      unsigned char *out9,
1012	      unsigned char *out10,
1013	      unsigned char *out11,
1014	      unsigned char *out12,
1015	      unsigned char *out13,
1016	      unsigned char *out14,
1017	      unsigned char *out15)
1018{
1019  unsigned char *outs[16];
1020  outs[0] = out0;
1021  outs[1] = out1;
1022  outs[2] = out2;
1023  outs[3] = out3;
1024  outs[4] = out4;
1025  outs[5] = out5;
1026  outs[6] = out6;
1027  outs[7] = out7;
1028  outs[8] = out8;
1029  outs[9] = out9;
1030  outs[10] = out10;
1031  outs[11] = out11;
1032  outs[12] = out12;
1033  outs[13] = out13;
1034  outs[14] = out14;
1035  outs[15] = out15;
1036  stp_unpack(length, bits, 16, in, outs);
1037}
1038
1039static void
1040find_first_and_last(const unsigned char *line, int length,
1041		    int *first, int *last)
1042{
1043  int i;
1044  int found_first = 0;
1045  if (!first || !last)
1046    return;
1047  *first = 0;
1048  *last = 0;
1049  for (i = 0; i < length; i++)
1050    {
1051      if (line[i] == 0)
1052	{
1053	  if (!found_first)
1054	    (*first)++;
1055	}
1056      else
1057	{
1058	  *last = i;
1059	  found_first = 1;
1060	}
1061    }
1062}
1063
1064int
1065stp_pack_uncompressed(stp_vars_t *v,
1066		      const unsigned char *line,
1067		      int length,
1068		      unsigned char *comp_buf,
1069		      unsigned char **comp_ptr,
1070		      int *first,
1071		      int *last)
1072{
1073  find_first_and_last(line, length, first, last);
1074  memcpy(comp_buf, line, length);
1075  *comp_ptr = comp_buf + length;
1076  if (first && last && *first > *last)
1077    return 0;
1078  else
1079    return 1;
1080}
1081
1082int
1083stp_pack_tiff(stp_vars_t *v,
1084	      const unsigned char *line,
1085	      int length,
1086	      unsigned char *comp_buf,
1087	      unsigned char **comp_ptr,
1088	      int *first,
1089	      int *last)
1090{
1091  const unsigned char *start;		/* Start of compressed data */
1092  unsigned char repeat;			/* Repeating char */
1093  int count;			/* Count of compressed bytes */
1094  int tcount;			/* Temporary count < 128 */
1095  register const unsigned char *xline = line;
1096  register int xlength = length;
1097  find_first_and_last(line, length, first, last);
1098
1099  /*
1100   * Compress using TIFF "packbits" run-length encoding...
1101   */
1102
1103  (*comp_ptr) = comp_buf;
1104
1105  while (xlength > 0)
1106    {
1107      /*
1108       * Get a run of non-repeated chars...
1109       */
1110
1111      start  = xline;
1112      xline   += 2;
1113      xlength -= 2;
1114
1115      while (xlength > 0 && (xline[-2] != xline[-1] || xline[-1] != xline[0]))
1116	{
1117	  xline ++;
1118	  xlength --;
1119	}
1120
1121      xline   -= 2;
1122      xlength += 2;
1123
1124      /*
1125       * Output the non-repeated sequences (max 128 at a time).
1126       */
1127
1128      count = xline - start;
1129      while (count > 0)
1130	{
1131	  tcount = count > 128 ? 128 : count;
1132
1133	  (*comp_ptr)[0] = tcount - 1;
1134	  memcpy((*comp_ptr) + 1, start, tcount);
1135
1136	  (*comp_ptr) += tcount + 1;
1137	  start    += tcount;
1138	  count    -= tcount;
1139	}
1140
1141      if (xlength <= 0)
1142	break;
1143
1144      /*
1145       * Find the repeated sequences...
1146       */
1147
1148      start  = xline;
1149      repeat = xline[0];
1150
1151      xline ++;
1152      xlength --;
1153
1154      if (xlength > 0)
1155	{
1156	  int ylength = xlength;
1157	  while (ylength && *xline == repeat)
1158	    {
1159	      xline ++;
1160	      ylength --;
1161	    }
1162	  xlength = ylength;
1163	}
1164
1165      /*
1166       * Output the repeated sequences (max 128 at a time).
1167       */
1168
1169      count = xline - start;
1170      while (count > 0)
1171	{
1172	  tcount = count > 128 ? 128 : count;
1173
1174	  (*comp_ptr)[0] = 1 - tcount;
1175	  (*comp_ptr)[1] = repeat;
1176
1177	  (*comp_ptr) += 2;
1178	  count    -= tcount;
1179	}
1180    }
1181  if (first && last && *first > *last)
1182    return 0;
1183  else
1184    return 1;
1185}
1186