1 49 package com.lowagie.text.pdf.codec; 50 51 import com.lowagie.text.pdf.ByteBuffer; 52 53 56 public class CCITTG4Encoder { 57 private int rowbytes; 58 private int rowpixels; 59 private int bit = 8; 60 private int data; 61 private byte[] refline; 62 private ByteBuffer outBuf = new ByteBuffer(1024); 63 private byte[] dataBp; 64 private int offsetData; 65 private int sizeData; 66 67 71 public CCITTG4Encoder(int width) { 72 rowpixels = width; 73 rowbytes = (rowpixels + 7) / 8; 74 refline = new byte[rowbytes]; 75 } 76 77 83 public void fax4Encode(byte[] data, int offset, int size) { 84 dataBp = data; 85 offsetData = offset; 86 sizeData = size; 87 while (sizeData > 0) { 88 Fax3Encode2DRow(); 89 System.arraycopy(dataBp, offsetData, refline, 0, rowbytes); 90 offsetData += rowbytes; 91 sizeData -= rowbytes; 92 } 93 } 94 95 96 103 public static byte[] compress(byte[] data, int width, int height) { 104 CCITTG4Encoder g4 = new CCITTG4Encoder(width); 105 g4.fax4Encode(data, 0, g4.rowbytes * height); 106 return g4.close(); 107 } 108 109 114 public void fax4Encode(byte[] data, int height) { 115 fax4Encode(data, 0, rowbytes * height); 116 } 117 118 private void putcode(int[] table) { 119 putBits(table[CODE], table[LENGTH]); 120 } 121 122 private void putspan(int span, int[][] tab) { 123 int code, length; 124 125 while (span >= 2624) { 126 int[] te = tab[63 + (2560>>6)]; 127 code = te[CODE]; 128 length = te[LENGTH]; 129 putBits(code, length); 130 span -= te[RUNLEN]; 131 } 132 if (span >= 64) { 133 int[] te = tab[63 + (span>>6)]; 134 code = te[CODE]; 135 length = te[LENGTH]; 136 putBits(code, length); 137 span -= te[RUNLEN]; 138 } 139 code = tab[span][CODE]; 140 length = tab[span][LENGTH]; 141 putBits(code, length); 142 } 143 144 private void putBits(int bits, int length) { 145 while (length > bit) { 146 data |= bits >> (length - bit); 147 length -= bit; 148 outBuf.append((byte)data); 149 data = 0; 150 bit = 8; 151 } 152 data |= (bits & msbmask[length]) << (bit - length); 153 bit -= length; 154 if (bit == 0) { 155 outBuf.append((byte)data); 156 data = 0; 157 bit = 8; 158 } 159 } 160 161 private void Fax3Encode2DRow() { 162 int a0 = 0; 163 int a1 = (pixel(dataBp, offsetData, 0) != 0 ? 0 : finddiff(dataBp, offsetData, 0, rowpixels, 0)); 164 int b1 = (pixel(refline, 0, 0) != 0 ? 0 : finddiff(refline, 0, 0, rowpixels, 0)); 165 int a2, b2; 166 167 for (;;) { 168 b2 = finddiff2(refline, 0, b1, rowpixels, pixel(refline, 0,b1)); 169 if (b2 >= a1) { 170 int d = b1 - a1; 171 if (!(-3 <= d && d <= 3)) { 172 a2 = finddiff2(dataBp, offsetData, a1, rowpixels, pixel(dataBp, offsetData,a1)); 173 putcode(horizcode); 174 if (a0+a1 == 0 || pixel(dataBp, offsetData, a0) == 0) { 175 putspan(a1-a0, TIFFFaxWhiteCodes); 176 putspan(a2-a1, TIFFFaxBlackCodes); 177 } else { 178 putspan(a1-a0, TIFFFaxBlackCodes); 179 putspan(a2-a1, TIFFFaxWhiteCodes); 180 } 181 a0 = a2; 182 } else { 183 putcode(vcodes[d+3]); 184 a0 = a1; 185 } 186 } else { 187 putcode(passcode); 188 a0 = b2; 189 } 190 if (a0 >= rowpixels) 191 break; 192 a1 = finddiff(dataBp, offsetData, a0, rowpixels, pixel(dataBp, offsetData,a0)); 193 b1 = finddiff(refline, 0, a0, rowpixels, pixel(dataBp, offsetData,a0) ^ 1); 194 b1 = finddiff(refline, 0, b1, rowpixels, pixel(dataBp, offsetData,a0)); 195 } 196 } 197 198 private void Fax4PostEncode() { 199 putBits(EOL, 12); 200 putBits(EOL, 12); 201 if (bit != 8) { 202 outBuf.append((byte)data); 203 data = 0; 204 bit = 8; 205 } 206 } 207 208 212 public byte[] close() { 213 Fax4PostEncode(); 214 return outBuf.toByteArray(); 215 } 216 217 private int pixel(byte[] data, int offset, int bit) { 218 if (bit >= rowpixels) 219 return 0; 220 return ((data[offset + (bit >> 3)] & 0xff) >> (7-((bit)&7))) & 1; 221 } 222 223 private static int find1span(byte[] bp, int offset, int bs, int be) { 224 int bits = be - bs; 225 int n, span; 226 227 int pos = offset + (bs >> 3); 228 231 if (bits > 0 && (n = (bs & 7)) != 0) { 232 span = oneruns[((int)bp[pos] << n) & 0xff]; 233 if (span > 8-n) 234 span = 8-n; 235 if (span > bits) 236 span = bits; 237 if (n+span < 8) 238 return span; 239 bits -= span; 240 pos++; 241 } else 242 span = 0; 243 246 while (bits >= 8) { 247 if (bp[pos] != -1) 248 return (span + oneruns[bp[pos] & 0xff]); 249 span += 8; 250 bits -= 8; 251 pos++; 252 } 253 256 if (bits > 0) { 257 n = oneruns[bp[pos] & 0xff]; 258 span += (n > bits ? bits : n); 259 } 260 return span; 261 } 262 263 private static int find0span(byte[] bp, int offset, int bs, int be) { 264 int bits = be - bs; 265 int n, span; 266 267 int pos = offset + (bs >> 3); 268 271 if (bits > 0 && (n = (bs & 7)) != 0) { 272 span = zeroruns[((int)bp[pos] << n) & 0xff]; 273 if (span > 8-n) 274 span = 8-n; 275 if (span > bits) 276 span = bits; 277 if (n+span < 8) 278 return span; 279 bits -= span; 280 pos++; 281 } else 282 span = 0; 283 286 while (bits >= 8) { 287 if (bp[pos] != 0) 288 return (span + zeroruns[bp[pos] & 0xff]); 289 span += 8; 290 bits -= 8; 291 pos++; 292 } 293 296 if (bits > 0) { 297 n = zeroruns[bp[pos] & 0xff]; 298 span += (n > bits ? bits : n); 299 } 300 return span; 301 } 302 303 private static int finddiff(byte[] bp, int offset, int bs, int be, int color) { 304 return bs + (color != 0 ? find1span(bp, offset, bs, be) : find0span(bp, offset, bs, be)); 305 } 306 307 private static int finddiff2(byte[] bp, int offset, int bs, int be, int color) { 308 return bs < be ? finddiff(bp, offset, bs, be, color) : be; 309 } 310 311 private static byte zeroruns[] = { 312 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 313 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 314 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 315 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 316 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 317 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 318 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 319 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 320 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 322 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 323 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 324 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 325 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 326 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 327 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 328 }; 329 330 private static byte oneruns[] = { 331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 332 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 333 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 334 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 335 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 336 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 337 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 338 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 339 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 340 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 341 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 342 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 343 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 344 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 345 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 346 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8 347 }; 348 349 private static final int LENGTH = 0; 350 private static final int CODE = 1; 351 private static final int RUNLEN = 2; 352 353 private static final int EOL = 0x001; 354 355 356 private static final int G3CODE_EOL = -1; 357 private static final int G3CODE_INVALID = -2; 358 private static final int G3CODE_EOF = -3; 359 private static final int G3CODE_INCOMP = -4; 360 361 private int[][] TIFFFaxWhiteCodes = { 362 { 8, 0x35, 0 }, 363 { 6, 0x7, 1 }, 364 { 4, 0x7, 2 }, 365 { 4, 0x8, 3 }, 366 { 4, 0xB, 4 }, 367 { 4, 0xC, 5 }, 368 { 4, 0xE, 6 }, 369 { 4, 0xF, 7 }, 370 { 5, 0x13, 8 }, 371 { 5, 0x14, 9 }, 372 { 5, 0x7, 10 }, 373 { 5, 0x8, 11 }, 374 { 6, 0x8, 12 }, 375 { 6, 0x3, 13 }, 376 { 6, 0x34, 14 }, 377 { 6, 0x35, 15 }, 378 { 6, 0x2A, 16 }, 379 { 6, 0x2B, 17 }, 380 { 7, 0x27, 18 }, 381 { 7, 0xC, 19 }, 382 { 7, 0x8, 20 }, 383 { 7, 0x17, 21 }, 384 { 7, 0x3, 22 }, 385 { 7, 0x4, 23 }, 386 { 7, 0x28, 24 }, 387 { 7, 0x2B, 25 }, 388 { 7, 0x13, 26 }, 389 { 7, 0x24, 27 }, 390 { 7, 0x18, 28 }, 391 { 8, 0x2, 29 }, 392 { 8, 0x3, 30 }, 393 { 8, 0x1A, 31 }, 394 { 8, 0x1B, 32 }, 395 { 8, 0x12, 33 }, 396 { 8, 0x13, 34 }, 397 { 8, 0x14, 35 }, 398 { 8, 0x15, 36 }, 399 { 8, 0x16, 37 }, 400 { 8, 0x17, 38 }, 401 { 8, 0x28, 39 }, 402 { 8, 0x29, 40 }, 403 { 8, 0x2A, 41 }, 404 { 8, 0x2B, 42 }, 405 { 8, 0x2C, 43 }, 406 { 8, 0x2D, 44 }, 407 { 8, 0x4, 45 }, 408 { 8, 0x5, 46 }, 409 { 8, 0xA, 47 }, 410 { 8, 0xB, 48 }, 411 { 8, 0x52, 49 }, 412 { 8, 0x53, 50 }, 413 { 8, 0x54, 51 }, 414 { 8, 0x55, 52 }, 415 { 8, 0x24, 53 }, 416 { 8, 0x25, 54 }, 417 { 8, 0x58, 55 }, 418 { 8, 0x59, 56 }, 419 { 8, 0x5A, 57 }, 420 { 8, 0x5B, 58 }, 421 { 8, 0x4A, 59 }, 422 { 8, 0x4B, 60 }, 423 { 8, 0x32, 61 }, 424 { 8, 0x33, 62 }, 425 { 8, 0x34, 63 }, 426 { 5, 0x1B, 64 }, 427 { 5, 0x12, 128 }, 428 { 6, 0x17, 192 }, 429 { 7, 0x37, 256 }, 430 { 8, 0x36, 320 }, 431 { 8, 0x37, 384 }, 432 { 8, 0x64, 448 }, 433 { 8, 0x65, 512 }, 434 { 8, 0x68, 576 }, 435 { 8, 0x67, 640 }, 436 { 9, 0xCC, 704 }, 437 { 9, 0xCD, 768 }, 438 { 9, 0xD2, 832 }, 439 { 9, 0xD3, 896 }, 440 { 9, 0xD4, 960 }, 441 { 9, 0xD5, 1024 }, 442 { 9, 0xD6, 1088 }, 443 { 9, 0xD7, 1152 }, 444 { 9, 0xD8, 1216 }, 445 { 9, 0xD9, 1280 }, 446 { 9, 0xDA, 1344 }, 447 { 9, 0xDB, 1408 }, 448 { 9, 0x98, 1472 }, 449 { 9, 0x99, 1536 }, 450 { 9, 0x9A, 1600 }, 451 { 6, 0x18, 1664 }, 452 { 9, 0x9B, 1728 }, 453 { 11, 0x8, 1792 }, 454 { 11, 0xC, 1856 }, 455 { 11, 0xD, 1920 }, 456 { 12, 0x12, 1984 }, 457 { 12, 0x13, 2048 }, 458 { 12, 0x14, 2112 }, 459 { 12, 0x15, 2176 }, 460 { 12, 0x16, 2240 }, 461 { 12, 0x17, 2304 }, 462 { 12, 0x1C, 2368 }, 463 { 12, 0x1D, 2432 }, 464 { 12, 0x1E, 2496 }, 465 { 12, 0x1F, 2560 }, 466 { 12, 0x1, G3CODE_EOL }, 467 { 9, 0x1, G3CODE_INVALID }, 468 { 10, 0x1, G3CODE_INVALID }, 469 { 11, 0x1, G3CODE_INVALID }, 470 { 12, 0x0, G3CODE_INVALID } 471 }; 472 473 private int[][] TIFFFaxBlackCodes = { 474 { 10, 0x37, 0 }, 475 { 3, 0x2, 1 }, 476 { 2, 0x3, 2 }, 477 { 2, 0x2, 3 }, 478 { 3, 0x3, 4 }, 479 { 4, 0x3, 5 }, 480 { 4, 0x2, 6 }, 481 { 5, 0x3, 7 }, 482 { 6, 0x5, 8 }, 483 { 6, 0x4, 9 }, 484 { 7, 0x4, 10 }, 485 { 7, 0x5, 11 }, 486 { 7, 0x7, 12 }, 487 { 8, 0x4, 13 }, 488 { 8, 0x7, 14 }, 489 { 9, 0x18, 15 }, 490 { 10, 0x17, 16 }, 491 { 10, 0x18, 17 }, 492 { 10, 0x8, 18 }, 493 { 11, 0x67, 19 }, 494 { 11, 0x68, 20 }, 495 { 11, 0x6C, 21 }, 496 { 11, 0x37, 22 }, 497 { 11, 0x28, 23 }, 498 { 11, 0x17, 24 }, 499 { 11, 0x18, 25 }, 500 { 12, 0xCA, 26 }, 501 { 12, 0xCB, 27 }, 502 { 12, 0xCC, 28 }, 503 { 12, 0xCD, 29 }, 504 { 12, 0x68, 30 }, 505 { 12, 0x69, 31 }, 506 { 12, 0x6A, 32 }, 507 { 12, 0x6B, 33 }, 508 { 12, 0xD2, 34 }, 509 { 12, 0xD3, 35 }, 510 { 12, 0xD4, 36 }, 511 { 12, 0xD5, 37 }, 512 { 12, 0xD6, 38 }, 513 { 12, 0xD7, 39 }, 514 { 12, 0x6C, 40 }, 515 { 12, 0x6D, 41 }, 516 { 12, 0xDA, 42 }, 517 { 12, 0xDB, 43 }, 518 { 12, 0x54, 44 }, 519 { 12, 0x55, 45 }, 520 { 12, 0x56, 46 }, 521 { 12, 0x57, 47 }, 522 { 12, 0x64, 48 }, 523 { 12, 0x65, 49 }, 524 { 12, 0x52, 50 }, 525 { 12, 0x53, 51 }, 526 { 12, 0x24, 52 }, 527 { 12, 0x37, 53 }, 528 { 12, 0x38, 54 }, 529 { 12, 0x27, 55 }, 530 { 12, 0x28, 56 }, 531 { 12, 0x58, 57 }, 532 { 12, 0x59, 58 }, 533 { 12, 0x2B, 59 }, 534 { 12, 0x2C, 60 }, 535 { 12, 0x5A, 61 }, 536 { 12, 0x66, 62 }, 537 { 12, 0x67, 63 }, 538 { 10, 0xF, 64 }, 539 { 12, 0xC8, 128 }, 540 { 12, 0xC9, 192 }, 541 { 12, 0x5B, 256 }, 542 { 12, 0x33, 320 }, 543 { 12, 0x34, 384 }, 544 { 12, 0x35, 448 }, 545 { 13, 0x6C, 512 }, 546 { 13, 0x6D, 576 }, 547 { 13, 0x4A, 640 }, 548 { 13, 0x4B, 704 }, 549 { 13, 0x4C, 768 }, 550 { 13, 0x4D, 832 }, 551 { 13, 0x72, 896 }, 552 { 13, 0x73, 960 }, 553 { 13, 0x74, 1024 }, 554 { 13, 0x75, 1088 }, 555 { 13, 0x76, 1152 }, 556 { 13, 0x77, 1216 }, 557 { 13, 0x52, 1280 }, 558 { 13, 0x53, 1344 }, 559 { 13, 0x54, 1408 }, 560 { 13, 0x55, 1472 }, 561 { 13, 0x5A, 1536 }, 562 { 13, 0x5B, 1600 }, 563 { 13, 0x64, 1664 }, 564 { 13, 0x65, 1728 }, 565 { 11, 0x8, 1792 }, 566 { 11, 0xC, 1856 }, 567 { 11, 0xD, 1920 }, 568 { 12, 0x12, 1984 }, 569 { 12, 0x13, 2048 }, 570 { 12, 0x14, 2112 }, 571 { 12, 0x15, 2176 }, 572 { 12, 0x16, 2240 }, 573 { 12, 0x17, 2304 }, 574 { 12, 0x1C, 2368 }, 575 { 12, 0x1D, 2432 }, 576 { 12, 0x1E, 2496 }, 577 { 12, 0x1F, 2560 }, 578 { 12, 0x1, G3CODE_EOL }, 579 { 9, 0x1, G3CODE_INVALID }, 580 { 10, 0x1, G3CODE_INVALID }, 581 { 11, 0x1, G3CODE_INVALID }, 582 { 12, 0x0, G3CODE_INVALID } 583 }; 584 585 private int[] horizcode = 586 { 3, 0x1, 0 }; 587 private int[] passcode = 588 { 4, 0x1, 0 }; 589 private int[][] vcodes = { 590 { 7, 0x03, 0 }, 591 { 6, 0x03, 0 }, 592 { 3, 0x03, 0 }, 593 { 1, 0x1, 0 }, 594 { 3, 0x2, 0 }, 595 { 6, 0x02, 0 }, 596 { 7, 0x02, 0 } 597 }; 598 private int[] msbmask = 599 { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; 600 } 601 | Popular Tags |