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