diff options
author | Roger Leigh <rleigh@debian.org> | 2008-10-26 16:11:41 +0000 |
---|---|---|
committer | Roger Leigh <rleigh@debian.org> | 2008-10-26 16:11:41 +0000 |
commit | dfae5860833782af557deb35e286d7e186fe3cf5 (patch) | |
tree | e3b4282ae08e120f78cd0c097f7cb3b570e94da2 /src/main/bit-ops.c | |
parent | 3b59bb0a607ec27ea60f07d1cd5d1bbb4483c832 (diff) |
Imported Upstream version 4.3.99+cvs20050702
Diffstat (limited to 'src/main/bit-ops.c')
-rw-r--r-- | src/main/bit-ops.c | 1199 |
1 files changed, 1199 insertions, 0 deletions
diff --git a/src/main/bit-ops.c b/src/main/bit-ops.c new file mode 100644 index 0000000..5cff81d --- /dev/null +++ b/src/main/bit-ops.c @@ -0,0 +1,1199 @@ +/* + * "$Id: bit-ops.c,v 1.8 2005/06/29 01:42:34 rlk Exp $" + * + * Softweave calculator for Gutenprint. + * + * Copyright 2000 Charles Briscoe-Smith <cpbs@debian.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * This file must include only standard C header files. The core code must + * compile on generic platforms that don't support glib, gimp, gtk, etc. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <string.h> +#include <gutenprint/gutenprint.h> +#include "gutenprint-internal.h" +#include <gutenprint/gutenprint-intl-internal.h> +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif + +void +stp_fold(const unsigned char *line, + int single_length, + unsigned char *outbuf) +{ + int i; + memset(outbuf, 0, single_length * 2); + for (i = 0; i < single_length; i++) + { + unsigned char l0 = line[0]; + unsigned char l1 = line[single_length]; + if (l0 || l1) + { + outbuf[0] = + ((l0 & (1 << 7)) >> 1) + + ((l0 & (1 << 6)) >> 2) + + ((l0 & (1 << 5)) >> 3) + + ((l0 & (1 << 4)) >> 4) + + ((l1 & (1 << 7)) >> 0) + + ((l1 & (1 << 6)) >> 1) + + ((l1 & (1 << 5)) >> 2) + + ((l1 & (1 << 4)) >> 3); + outbuf[1] = + ((l0 & (1 << 3)) << 3) + + ((l0 & (1 << 2)) << 2) + + ((l0 & (1 << 1)) << 1) + + ((l0 & (1 << 0)) << 0) + + ((l1 & (1 << 3)) << 4) + + ((l1 & (1 << 2)) << 3) + + ((l1 & (1 << 1)) << 2) + + ((l1 & (1 << 0)) << 1); + } + line++; + outbuf += 2; + } +} + +static void +stpi_split_2_1(int length, + const unsigned char *in, + unsigned char *outhi, + unsigned char *outlo) +{ + unsigned char *outs[2]; + int i; + int row = 0; + int limit = length; + outs[0] = outhi; + outs[1] = outlo; + memset(outs[1], 0, limit); + for (i = 0; i < limit; i++) + { + unsigned char inbyte = in[i]; + outs[0][i] = 0; + if (inbyte == 0) + continue; + /* For some reason gcc isn't unrolling this, even with -funroll-loops */ + if (inbyte & 1) + { + outs[row][i] |= 1 & inbyte; + row = row ^ 1; + } + if (inbyte & (1 << 1)) + { + outs[row][i] |= (1 << 1) & inbyte; + row = row ^ 1; + } + if (inbyte & (1 << 2)) + { + outs[row][i] |= (1 << 2) & inbyte; + row = row ^ 1; + } + if (inbyte & (1 << 3)) + { + outs[row][i] |= (1 << 3) & inbyte; + row = row ^ 1; + } + if (inbyte & (1 << 4)) + { + outs[row][i] |= (1 << 4) & inbyte; + row = row ^ 1; + } + if (inbyte & (1 << 5)) + { + outs[row][i] |= (1 << 5) & inbyte; + row = row ^ 1; + } + if (inbyte & (1 << 6)) + { + outs[row][i] |= (1 << 6) & inbyte; + row = row ^ 1; + } + if (inbyte & (1 << 7)) + { + outs[row][i] |= (1 << 7) & inbyte; + row = row ^ 1; + } + } +} + +static void +stp_split_2_2(int length, + const unsigned char *in, + unsigned char *outhi, + unsigned char *outlo) +{ + unsigned char *outs[2]; + int i; + unsigned row = 0; + int limit = length * 2; + outs[0] = outhi; + outs[1] = outlo; + memset(outs[1], 0, limit); + for (i = 0; i < limit; i++) + { + unsigned char inbyte = in[i]; + outs[0][i] = 0; + if (inbyte == 0) + continue; + /* For some reason gcc isn't unrolling this, even with -funroll-loops */ + if (inbyte & 3) + { + outs[row][i] |= (3 & inbyte); + row = row ^ 1; + } + if (inbyte & (3 << 2)) + { + outs[row][i] |= ((3 << 2) & inbyte); + row = row ^ 1; + } + if (inbyte & (3 << 4)) + { + outs[row][i] |= ((3 << 4) & inbyte); + row = row ^ 1; + } + if (inbyte & (3 << 6)) + { + outs[row][i] |= ((3 << 6) & inbyte); + row = row ^ 1; + } + } +} + +void +stp_split_2(int length, + int bits, + const unsigned char *in, + unsigned char *outhi, + unsigned char *outlo) +{ + if (bits == 2) + stp_split_2_2(length, in, outhi, outlo); + else + stpi_split_2_1(length, in, outhi, outlo); +} + +static void +stpi_split_4_1(int length, + const unsigned char *in, + unsigned char *out0, + unsigned char *out1, + unsigned char *out2, + unsigned char *out3) +{ + unsigned char *outs[4]; + int i; + int row = 0; + int limit = length; + outs[0] = out0; + outs[1] = out1; + outs[2] = out2; + outs[3] = out3; + memset(outs[1], 0, limit); + memset(outs[2], 0, limit); + memset(outs[3], 0, limit); + for (i = 0; i < limit; i++) + { + unsigned char inbyte = in[i]; + outs[0][i] = 0; + if (inbyte == 0) + continue; + /* For some reason gcc isn't unrolling this, even with -funroll-loops */ + if (inbyte & 1) + { + outs[row][i] |= 1 & inbyte; + row = (row + 1) & 3; + } + if (inbyte & (1 << 1)) + { + outs[row][i] |= (1 << 1) & inbyte; + row = (row + 1) & 3; + } + if (inbyte & (1 << 2)) + { + outs[row][i] |= (1 << 2) & inbyte; + row = (row + 1) & 3; + } + if (inbyte & (1 << 3)) + { + outs[row][i] |= (1 << 3) & inbyte; + row = (row + 1) & 3; + } + if (inbyte & (1 << 4)) + { + outs[row][i] |= (1 << 4) & inbyte; + row = (row + 1) & 3; + } + if (inbyte & (1 << 5)) + { + outs[row][i] |= (1 << 5) & inbyte; + row = (row + 1) & 3; + } + if (inbyte & (1 << 6)) + { + outs[row][i] |= (1 << 6) & inbyte; + row = (row + 1) & 3; + } + if (inbyte & (1 << 7)) + { + outs[row][i] |= (1 << 7) & inbyte; + row = (row + 1) & 3; + } + } +} + +static void +stpi_split_4_2(int length, + const unsigned char *in, + unsigned char *out0, + unsigned char *out1, + unsigned char *out2, + unsigned char *out3) +{ + unsigned char *outs[4]; + int i; + int row = 0; + int limit = length * 2; + outs[0] = out0; + outs[1] = out1; + outs[2] = out2; + outs[3] = out3; + memset(outs[1], 0, limit); + memset(outs[2], 0, limit); + memset(outs[3], 0, limit); + for (i = 0; i < limit; i++) + { + unsigned char inbyte = in[i]; + outs[0][i] = 0; + if (inbyte == 0) + continue; + /* For some reason gcc isn't unrolling this, even with -funroll-loops */ + if (inbyte & 3) + { + outs[row][i] |= 3 & inbyte; + row = (row + 1) & 3; + } + if (inbyte & (3 << 2)) + { + outs[row][i] |= (3 << 2) & inbyte; + row = (row + 1) & 3; + } + if (inbyte & (3 << 4)) + { + outs[row][i] |= (3 << 4) & inbyte; + row = (row + 1) & 3; + } + if (inbyte & (3 << 6)) + { + outs[row][i] |= (3 << 6) & inbyte; + row = (row + 1) & 3; + } + } +} + +void +stp_split_4(int length, + int bits, + const unsigned char *in, + unsigned char *out0, + unsigned char *out1, + unsigned char *out2, + unsigned char *out3) +{ + if (bits == 2) + stpi_split_4_2(length, in, out0, out1, out2, out3); + else + stpi_split_4_1(length, in, out0, out1, out2, out3); +} + + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define SH20 0 +#define SH21 8 +#else +#define SH20 8 +#define SH21 0 +#endif + +static void +stpi_unpack_2_1(int length, + const unsigned char *in, + unsigned char *out0, + unsigned char *out1) +{ + unsigned char tempin, bit, temp0, temp1; + + if (length <= 0) + return; + for (bit = 128, temp0 = 0, temp1 = 0; + length > 0; + length --) + { + tempin = *in++; + + if (tempin & 128) + temp0 |= bit; + if (tempin & 64) + temp1 |= bit; + bit >>= 1; + if (tempin & 32) + temp0 |= bit; + if (tempin & 16) + temp1 |= bit; + bit >>= 1; + if (tempin & 8) + temp0 |= bit; + if (tempin & 4) + temp1 |= bit; + bit >>= 1; + if (tempin & 2) + temp0 |= bit; + if (tempin & 1) + temp1 |= bit; + + if (bit > 1) + bit >>= 1; + else + { + bit = 128; + *out0++ = temp0; + *out1++ = temp1; + + temp0 = 0; + temp1 = 0; + } + } + + if (bit < 128) + { + *out0++ = temp0; + *out1++ = temp1; + } +} + +static void +stpi_unpack_2_2(int length, + const unsigned char *in, + unsigned char *out0, + unsigned char *out1) +{ + if (length <= 0) + return; + + for (;length;length --) + { + unsigned char ti0, ti1; + ti0 = in[0]; + ti1 = in[1]; + + *out0++ = (ti0 & 0xc0) << 0 + | (ti0 & 0x0c) << 2 + | (ti1 & 0xc0) >> 4 + | (ti1 & 0x0c) >> 2; + *out1++ = (ti0 & 0x30) << 2 + | (ti0 & 0x03) << 4 + | (ti1 & 0x30) >> 2 + | (ti1 & 0x03) >> 0; + in += 2; + } +} + +void +stp_unpack_2(int length, + int bits, + const unsigned char *in, + unsigned char *outlo, + unsigned char *outhi) +{ + if (bits == 1) + stpi_unpack_2_1(length, in, outlo, outhi); + else + stpi_unpack_2_2(length, in, outlo, outhi); +} + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define SH40 0 +#define SH41 8 +#define SH42 16 +#define SH43 24 +#else +#define SH40 24 +#define SH41 16 +#define SH42 8 +#define SH43 0 +#endif + +static void +stpi_unpack_4_1(int length, + const unsigned char *in, + unsigned char *out0, + unsigned char *out1, + unsigned char *out2, + unsigned char *out3) +{ + unsigned char tempin, bit, temp0, temp1, temp2, temp3; + + if (length <= 0) + return; + for (bit = 128, temp0 = 0, temp1 = 0, temp2 = 0, temp3 = 0; + length > 0; + length --) + { + tempin = *in++; + + if (tempin & 128) + temp0 |= bit; + if (tempin & 64) + temp1 |= bit; + if (tempin & 32) + temp2 |= bit; + if (tempin & 16) + temp3 |= bit; + bit >>= 1; + if (tempin & 8) + temp0 |= bit; + if (tempin & 4) + temp1 |= bit; + if (tempin & 2) + temp2 |= bit; + if (tempin & 1) + temp3 |= bit; + + if (bit > 1) + bit >>= 1; + else + { + bit = 128; + *out0++ = temp0; + *out1++ = temp1; + *out2++ = temp2; + *out3++ = temp3; + + temp0 = 0; + temp1 = 0; + temp2 = 0; + temp3 = 0; + } + } + + if (bit < 128) + { + *out0++ = temp0; + *out1++ = temp1; + *out2++ = temp2; + *out3++ = temp3; + } +} + +static void +stpi_unpack_4_2(int length, + const unsigned char *in, + unsigned char *out0, + unsigned char *out1, + unsigned char *out2, + unsigned char *out3) +{ + unsigned char tempin, + shift, + temp0, + temp1, + temp2, + temp3; + + length *= 2; + + for (shift = 0, temp0 = 0, temp1 = 0, temp2 = 0, temp3 = 0; + length > 0; + length --) + { + /* + * Note - we can't use (tempin & N) >> (shift - M) since negative + * right-shifts are not always implemented. + */ + + tempin = *in++; + + if (tempin & 192) + temp0 |= (tempin & 192) >> shift; + if (tempin & 48) + temp1 |= ((tempin & 48) << 2) >> shift; + if (tempin & 12) + temp2 |= ((tempin & 12) << 4) >> shift; + if (tempin & 3) + temp3 |= ((tempin & 3) << 6) >> shift; + + if (shift < 6) + shift += 2; + else + { + shift = 0; + *out0++ = temp0; + *out1++ = temp1; + *out2++ = temp2; + *out3++ = temp3; + + temp0 = 0; + temp1 = 0; + temp2 = 0; + temp3 = 0; + } + } + + if (shift) + { + *out0++ = temp0; + *out1++ = temp1; + *out2++ = temp2; + *out3++ = temp3; + } +} + +void +stp_unpack_4(int length, + int bits, + const unsigned char *in, + unsigned char *out0, + unsigned char *out1, + unsigned char *out2, + unsigned char *out3) +{ + if (bits == 1) + stpi_unpack_4_1(length, in, out0, out1, out2, out3); + else + stpi_unpack_4_2(length, in, out0, out1, out2, out3); +} + +static void +stpi_unpack_8_1(int length, + const unsigned char *in, + unsigned char *out0, + unsigned char *out1, + unsigned char *out2, + unsigned char *out3, + unsigned char *out4, + unsigned char *out5, + unsigned char *out6, + unsigned char *out7) +{ + unsigned char tempin, bit, temp0, temp1, temp2, temp3, temp4, temp5, temp6, + temp7; + + if (length <= 0) + return; + + for (bit = 128, temp0 = 0, temp1 = 0, temp2 = 0, + temp3 = 0, temp4 = 0, temp5 = 0, temp6 = 0, temp7 = 0; + length > 0; + length --) + { + tempin = *in++; + + if (tempin & 128) + temp0 |= bit; + if (tempin & 64) + temp1 |= bit; + if (tempin & 32) + temp2 |= bit; + if (tempin & 16) + temp3 |= bit; + if (tempin & 8) + temp4 |= bit; + if (tempin & 4) + temp5 |= bit; + if (tempin & 2) + temp6 |= bit; + if (tempin & 1) + temp7 |= bit; + + if (bit > 1) + bit >>= 1; + else + { + bit = 128; + *out0++ = temp0; + *out1++ = temp1; + *out2++ = temp2; + *out3++ = temp3; + *out4++ = temp4; + *out5++ = temp5; + *out6++ = temp6; + *out7++ = temp7; + + temp0 = 0; + temp1 = 0; + temp2 = 0; + temp3 = 0; + temp4 = 0; + temp5 = 0; + temp6 = 0; + temp7 = 0; + } + } + + if (bit < 128) + { + *out0++ = temp0; + *out1++ = temp1; + *out2++ = temp2; + *out3++ = temp3; + *out4++ = temp4; + *out5++ = temp5; + *out6++ = temp6; + *out7++ = temp7; + } +} + +static void +stpi_unpack_8_2(int length, + const unsigned char *in, + unsigned char *out0, + unsigned char *out1, + unsigned char *out2, + unsigned char *out3, + unsigned char *out4, + unsigned char *out5, + unsigned char *out6, + unsigned char *out7) +{ + unsigned char tempin, + shift, + temp0, + temp1, + temp2, + temp3, + temp4, + temp5, + temp6, + temp7; + + + for (shift = 0, temp0 = 0, temp1 = 0, + temp2 = 0, temp3 = 0, temp4 = 0, temp5 = 0, temp6 = 0, temp7 = 0; + length > 0; + length --) + { + /* + * Note - we can't use (tempin & N) >> (shift - M) since negative + * right-shifts are not always implemented. + */ + + tempin = *in++; + + if (tempin & 192) + temp0 |= (tempin & 192) >> shift; + if (tempin & 48) + temp1 |= ((tempin & 48) << 2) >> shift; + if (tempin & 12) + temp2 |= ((tempin & 12) << 4) >> shift; + if (tempin & 3) + temp3 |= ((tempin & 3) << 6) >> shift; + + tempin = *in++; + + if (tempin & 192) + temp4 |= (tempin & 192) >> shift; + if (tempin & 48) + temp5 |= ((tempin & 48) << 2) >> shift; + if (tempin & 12) + temp6 |= ((tempin & 12) << 4) >> shift; + if (tempin & 3) + temp7 |= ((tempin & 3) << 6) >> shift; + + if (shift < 6) + shift += 2; + else + { + shift = 0; + *out0++ = temp0; + *out1++ = temp1; + *out2++ = temp2; + *out3++ = temp3; + *out4++ = temp4; + *out5++ = temp5; + *out6++ = temp6; + *out7++ = temp7; + + temp0 = 0; + temp1 = 0; + temp2 = 0; + temp3 = 0; + temp4 = 0; + temp5 = 0; + temp6 = 0; + temp7 = 0; + } + } + + if (shift) + { + *out0++ = temp0; + *out1++ = temp1; + *out2++ = temp2; + *out3++ = temp3; + *out4++ = temp4; + *out5++ = temp5; + *out6++ = temp6; + *out7++ = temp7; + } +} + +void +stp_unpack_8(int length, + int bits, + const unsigned char *in, + unsigned char *out0, + unsigned char *out1, + unsigned char *out2, + unsigned char *out3, + unsigned char *out4, + unsigned char *out5, + unsigned char *out6, + unsigned char *out7) +{ + if (bits == 1) + stpi_unpack_8_1(length, in, out0, out1, out2, out3, + out4, out5, out6, out7); + else + stpi_unpack_8_2(length, in, out0, out1, out2, out3, + out4, out5, out6, out7); +} + + +static void +stpi_unpack_16_1(int length, + const unsigned char *in, + unsigned char *out0, + unsigned char *out1, + unsigned char *out2, + unsigned char *out3, + unsigned char *out4, + unsigned char *out5, + unsigned char *out6, + unsigned char *out7, + unsigned char *out8, + unsigned char *out9, + unsigned char *out10, + unsigned char *out11, + unsigned char *out12, + unsigned char *out13, + unsigned char *out14, + unsigned char *out15) +{ + unsigned char tempin, bit; + unsigned char temp[16]; + + if (length <= 0) + return; + + memset(temp, 0, 16); + + for (bit = 128; length > 0; length--) + { + tempin = *in++; + + if (tempin & 128) + temp[0] |= bit; + if (tempin & 64) + temp[1] |= bit; + if (tempin & 32) + temp[2] |= bit; + if (tempin & 16) + temp[3] |= bit; + if (tempin & 8) + temp[4] |= bit; + if (tempin & 4) + temp[5] |= bit; + if (tempin & 2) + temp[6] |= bit; + if (tempin & 1) + temp[7] |= bit; + + tempin = *in++; + + if (tempin & 128) + temp[8] |= bit; + if (tempin & 64) + temp[9] |= bit; + if (tempin & 32) + temp[10] |= bit; + if (tempin & 16) + temp[11] |= bit; + if (tempin & 8) + temp[12] |= bit; + if (tempin & 4) + temp[13] |= bit; + if (tempin & 2) + temp[14] |= bit; + if (tempin & 1) + temp[15] |= bit; + + if (bit > 1) + bit >>= 1; + else + { + bit = 128; + *out0++ = temp[0]; + *out1++ = temp[1]; + *out2++ = temp[2]; + *out3++ = temp[3]; + *out4++ = temp[4]; + *out5++ = temp[5]; + *out6++ = temp[6]; + *out7++ = temp[7]; + *out8++ = temp[8]; + *out9++ = temp[9]; + *out10++ = temp[10]; + *out11++ = temp[11]; + *out12++ = temp[12]; + *out13++ = temp[13]; + *out14++ = temp[14]; + *out15++ = temp[15]; + + memset(temp, 0, 16); + } + } + + if (bit < 128) + { + *out0++ = temp[0]; + *out1++ = temp[1]; + *out2++ = temp[2]; + *out3++ = temp[3]; + *out4++ = temp[4]; + *out5++ = temp[5]; + *out6++ = temp[6]; + *out7++ = temp[7]; + *out8++ = temp[8]; + *out9++ = temp[9]; + *out10++ = temp[10]; + *out11++ = temp[11]; + *out12++ = temp[12]; + *out13++ = temp[13]; + *out14++ = temp[14]; + *out15++ = temp[15]; + } +} + +static void +stpi_unpack_16_2(int length, + const unsigned char *in, + unsigned char *out0, + unsigned char *out1, + unsigned char *out2, + unsigned char *out3, + unsigned char *out4, + unsigned char *out5, + unsigned char *out6, + unsigned char *out7, + unsigned char *out8, + unsigned char *out9, + unsigned char *out10, + unsigned char *out11, + unsigned char *out12, + unsigned char *out13, + unsigned char *out14, + unsigned char *out15) +{ + unsigned char tempin, shift; + unsigned char temp[16]; + + if (length <= 0) + return; + + memset(temp, 0, 16); + + for (shift = 0; length > 0; length--) + { + /* + * Note - we can't use (tempin & N) >> (shift - M) since negative + * right-shifts are not always implemented. + */ + + tempin = *in++; + + if (tempin & 192) + temp[0] |= (tempin & 192) >> shift; + if (tempin & 48) + temp[1] |= ((tempin & 48) << 2) >> shift; + if (tempin & 12) + temp[2] |= ((tempin & 12) << 4) >> shift; + if (tempin & 3) + temp[3] |= ((tempin & 3) << 6) >> shift; + + tempin = *in++; + + if (tempin & 192) + temp[4] |= (tempin & 192) >> shift; + if (tempin & 48) + temp[5] |= ((tempin & 48) << 2) >> shift; + if (tempin & 12) + temp[6] |= ((tempin & 12) << 4) >> shift; + if (tempin & 3) + temp[7] |= ((tempin & 3) << 6) >> shift; + + tempin = *in++; + + if (tempin & 192) + temp[8] |= (tempin & 192) >> shift; + if (tempin & 48) + temp[9] |= ((tempin & 48) << 2) >> shift; + if (tempin & 12) + temp[10] |= ((tempin & 12) << 4) >> shift; + if (tempin & 3) + temp[11] |= ((tempin & 3) << 6) >> shift; + + tempin = *in++; + + if (tempin & 192) + temp[12] |= (tempin & 192) >> shift; + if (tempin & 48) + temp[13] |= ((tempin & 48) << 2) >> shift; + if (tempin & 12) + temp[14] |= ((tempin & 12) << 4) >> shift; + if (tempin & 3) + temp[15] |= ((tempin & 3) << 6) >> shift; + + if (shift < 6) + shift += 2; + else + { + shift = 0; + *out0++ = temp[0]; + *out1++ = temp[1]; + *out2++ = temp[2]; + *out3++ = temp[3]; + *out4++ = temp[4]; + *out5++ = temp[5]; + *out6++ = temp[6]; + *out7++ = temp[7]; + *out8++ = temp[8]; + *out9++ = temp[9]; + *out10++ = temp[10]; + *out11++ = temp[11]; + *out12++ = temp[12]; + *out13++ = temp[13]; + *out14++ = temp[14]; + *out15++ = temp[15]; + + memset(temp, 0, 16); + } + } + + if (shift) + { + *out0++ = temp[0]; + *out1++ = temp[1]; + *out2++ = temp[2]; + *out3++ = temp[3]; + *out4++ = temp[4]; + *out5++ = temp[5]; + *out6++ = temp[6]; + *out7++ = temp[7]; + *out8++ = temp[8]; + *out9++ = temp[9]; + *out10++ = temp[10]; + *out11++ = temp[11]; + *out12++ = temp[12]; + *out13++ = temp[13]; + *out14++ = temp[14]; + *out15++ = temp[15]; + } +} + +void +stp_unpack_16(int length, + int bits, + const unsigned char *in, + unsigned char *out0, + unsigned char *out1, + unsigned char *out2, + unsigned char *out3, + unsigned char *out4, + unsigned char *out5, + unsigned char *out6, + unsigned char *out7, + unsigned char *out8, + unsigned char *out9, + unsigned char *out10, + unsigned char *out11, + unsigned char *out12, + unsigned char *out13, + unsigned char *out14, + unsigned char *out15) +{ + if (bits == 1) + stpi_unpack_16_1(length, in, + out0, out1, out2, out3, out4, out5, out6, out7, + out8, out9, out10, out11, out12, out13, out14, out15); + else + stpi_unpack_16_2(length, in, + out0, out1, out2, out3, out4, out5, out6, out7, + out8, out9, out10, out11, out12, out13, out14, out15); +} + +static void +find_first_and_last(const unsigned char *line, int length, + int *first, int *last) +{ + int i; + int found_first = 0; + if (!first || !last) + return; + *first = 0; + *last = 0; + for (i = 0; i < length; i++) + { + if (line[i] == 0) + { + if (!found_first) + (*first)++; + } + else + { + *last = i; + found_first = 1; + } + } +} + +int +stp_pack_uncompressed(stp_vars_t *v, + const unsigned char *line, + int length, + unsigned char *comp_buf, + unsigned char **comp_ptr, + int *first, + int *last) +{ + find_first_and_last(line, length, first, last); + memcpy(comp_buf, line, length); + *comp_ptr = comp_buf + length; + if (first > last) + return 0; + else + return 1; +} + +int +stp_pack_tiff(stp_vars_t *v, + const unsigned char *line, + int length, + unsigned char *comp_buf, + unsigned char **comp_ptr, + int *first, + int *last) +{ + const unsigned char *start; /* Start of compressed data */ + unsigned char repeat; /* Repeating char */ + int count; /* Count of compressed bytes */ + int tcount; /* Temporary count < 128 */ + register const unsigned char *xline = line; + register int xlength = length; + find_first_and_last(line, length, first, last); + + /* + * Compress using TIFF "packbits" run-length encoding... + */ + + (*comp_ptr) = comp_buf; + + while (xlength > 0) + { + /* + * Get a run of non-repeated chars... + */ + + start = xline; + xline += 2; + xlength -= 2; + + while (xlength > 0 && (xline[-2] != xline[-1] || xline[-1] != xline[0])) + { + xline ++; + xlength --; + } + + xline -= 2; + xlength += 2; + + /* + * Output the non-repeated sequences (max 128 at a time). + */ + + count = xline - start; + while (count > 0) + { + tcount = count > 128 ? 128 : count; + + (*comp_ptr)[0] = tcount - 1; + memcpy((*comp_ptr) + 1, start, tcount); + + (*comp_ptr) += tcount + 1; + start += tcount; + count -= tcount; + } + + if (xlength <= 0) + break; + + /* + * Find the repeated sequences... + */ + + start = xline; + repeat = xline[0]; + + xline ++; + xlength --; + + if (xlength > 0) + { + int ylength = xlength; + while (ylength && *xline == repeat) + { + xline ++; + ylength --; + } + xlength = ylength; + } + + /* + * Output the repeated sequences (max 128 at a time). + */ + + count = xline - start; + while (count > 0) + { + tcount = count > 128 ? 128 : count; + + (*comp_ptr)[0] = 1 - tcount; + (*comp_ptr)[1] = repeat; + + (*comp_ptr) += 2; + count -= tcount; + } + } + if (first && last && *first > *last) + return 0; + else + return 1; +} |