1 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <assert.h> 7 #ifdef WIN32 8 #include <windows.h> 9 #else 10 #include <unistd.h> 11 #endif 12 13 #include "toonz.h" 14 #include "tmsg.h" 15 #include "file.h" 16 #include "img.h" 17 #include "tmachine.h" 18 #include "../infoRegionP.h" 19 #include "ImageP/filetzr.h" 20 21 #if !defined(TNZ_LITTLE_ENDIAN) 22 TNZ_LITTLE_ENDIAN undefined!! 23 #endif 24 25 #if TNZ_LITTLE_ENDIAN 26 #define TZR_MAGIC ('T' | 'Z' << 8 | 'R' << 16 | 'A' << 24) 27 #else 28 #define TZR_MAGIC ('T' << 24 | 'Z' << 16 | 'R' << 8 | 'A') 29 #endif 30 31 #ifdef NOTES 32 33 numbers are always big endian (most significant byte first) 34 floats and doubles are IEEE, sign and exponent first (1+8+23 and 1+11+52) 35 36 4 bytes: 'T' 'Z' 'R' 'A' (0x545a5241 big endian or 0x41525a54 little endian) 37 1 byte: type of file (0 is not valid) 38 1 byte: ST1 (subtype, must be 0 if not used) 39 1 byte: ST2 (") 40 1 byte: ST3 (") 41 (types form a tree, numbers should increase chronologically) 42 43 type 1: fast 44 ST1 1: lineart CM (1 ink, 2 colors (transparent and opaque), 4 bits ramp) 45 ST2 1: RLE compression (see image section) 46 47 3 bytes: image lx 48 3 bytes: image ly 49 3 bytes: image offset from start of file 50 tagged fields (fill up the space before the image): 51 1 byte field tag 52 if (tag >= 128) 53 2 bytes field length(=n) 54 n bytes field value 55 else 56 1 byte field length(=n) 57 n bytes field value 58 image: 59 rle encoded 1 line at a time (to allow for subsampling) 60 rle encoding of 1 line: 61 2 or 3 bytes: length in bytes of encoded line 62 (2 if image lx <= 8*1024, 3 otherwise) 63 1 nibble at a time, most significative nibble first: 64 if (0x0 <= nibble[0] <= 0xE) 65 nibble[0] is the tone value (0 is black) 66 if (nibble[0] == 0xF) 67 if (0x0 <= nibble[1] <= 0x7) 68 nibble[1] is the count of nibbles which follow (may be zero) 69 nibble[2...] number of white pixels in a run - 1, big endian 70 if (nibble[1] == 0x8) 71 toggle between transparent (0) and opaque (1) (starts with 0) 72 if (nibble[1] == 0xF) 73 if (nibble[2] == 0xE) 74 end of encoding 75 if (nibble[2] == 0xF) 76 nibble[3] is last pixel tone value, end of encoding 77 if line ends at odd nibble, a 0x0 nibble is appended 78 79 80 32: 81 82 1 nibble at a time, most significative nibble first: 83 84 if (0x0 <= nibble[1]|nibble[0] <= 0xFE) 85 nibble[1]|nibble[0] is the tone value (0 is black) 86 if (nibble[1]|nibble[0] == 0xFF) 87 if (0x0 <= nibble[2] <= 0x7) 88 nibble[2] is the count of nibbles which follow (may be zero) 89 nibble[3...] number of white pixels in a run - 1, big endian 90 if (nibble[2] == 0x8) 91 toggle between transparent (0) and opaque (1) (starts with 0) 92 if (nibble[2] == 0xF) 93 if (nibble[3] == 0xE) 94 end of encoding 95 if (nibble[3] == 0xF) 96 nibble[4]|nibble[5] is last pixel tone value, end of encoding 97 if line ends at odd nibble, a 0x0 nibble is appended 98 99 #endif 100 101 typedef enum 102 { 103 TAG_NONE = 0, 104 105 TAG_DPI = 1, /* size 16: double[2] (x_dpi, y_dpi) */ 106 TAG_HPOS = 2, /* size 8: double */ 107 108 TAG_HOW_MANY = 256 109 } 110 TAG_TYPE; 111 112 #define TAGS_BUFLEN 65536 113 114 #define READ_BYTES_OR_ERROR(buf, n, file) \ 115 { \ 116 if (fread((buf), 1, (n), (file)) < (n)) goto error; \ 117 } 118 119 #define BYTES_TO_FLOAT(b, f) \ 120 { \ 121 UCHAR *fr = (b); \ 122 UCHAR *to = (UCHAR *)&(f); \ 123 if (TNZ_LITTLE_ENDIAN) { \ 124 to[0] = fr[3]; \ 125 to[1] = fr[2]; \ 126 to[2] = fr[1]; \ 127 to[3] = fr[0]; \ 128 } else { \ 129 to[0] = fr[0]; \ 130 to[1] = fr[1]; \ 131 to[2] = fr[2]; \ 132 to[3] = fr[3]; \ 133 } \ 134 } 135 136 #define FLOAT_TO_BYTES(f, b) \ 137 { \ 138 UCHAR *fr = (UCHAR *)&(f); \ 139 UCHAR *to = (b); \ 140 if (TNZ_LITTLE_ENDIAN) { \ 141 to[0] = fr[3]; \ 142 to[1] = fr[2]; \ 143 to[2] = fr[1]; \ 144 to[3] = fr[0]; \ 145 } else { \ 146 to[0] = fr[0]; \ 147 to[1] = fr[1]; \ 148 to[2] = fr[2]; \ 149 to[3] = fr[3]; \ 150 } \ 151 } 152 153 #define BYTES_TO_DOUBLE(b, d) \ 154 { \ 155 UCHAR *fr = (b); \ 156 UCHAR *to = (UCHAR *)&(d); \ 157 if (TNZ_LITTLE_ENDIAN) { \ 158 to[0] = fr[7]; \ 159 to[1] = fr[6]; \ 160 to[2] = fr[5]; \ 161 to[3] = fr[4]; \ 162 to[4] = fr[3]; \ 163 to[5] = fr[2]; \ 164 to[6] = fr[1]; \ 165 to[7] = fr[0]; \ 166 } else { \ 167 to[0] = fr[0]; \ 168 to[1] = fr[1]; \ 169 to[2] = fr[2]; \ 170 to[3] = fr[3]; \ 171 to[4] = fr[4]; \ 172 to[5] = fr[5]; \ 173 to[6] = fr[6]; \ 174 to[7] = fr[7]; \ 175 } \ 176 } 177 178 #define DOUBLE_TO_BYTES(d, b) \ 179 { \ 180 UCHAR *fr = (UCHAR *)&(d); \ 181 UCHAR *to = (b); \ 182 if (TNZ_LITTLE_ENDIAN) { \ 183 to[0] = fr[7]; \ 184 to[1] = fr[6]; \ 185 to[2] = fr[5]; \ 186 to[3] = fr[4]; \ 187 to[4] = fr[3]; \ 188 to[5] = fr[2]; \ 189 to[6] = fr[1]; \ 190 to[7] = fr[0]; \ 191 } else { \ 192 to[0] = fr[0]; \ 193 to[1] = fr[1]; \ 194 to[2] = fr[2]; \ 195 to[3] = fr[3]; \ 196 to[4] = fr[4]; \ 197 to[5] = fr[5]; \ 198 to[6] = fr[6]; \ 199 to[7] = fr[7]; \ 200 } \ 201 } 202 203 static void *Tzr_buffer; 204 static int Tzr_buffer_bytes; 205 206 static int Next_img_read_tzr_cmapped = FALSE; 207 static int Read_cmapped = FALSE; 208 #define SET_READ_CMAPPED \ 209 { \ 210 Read_cmapped = Next_img_read_tzr_cmapped; \ 211 Next_img_read_tzr_cmapped = FALSE; \ 212 } 213 214 /*---------------------------------------------------------------------------*/ 215 216 int tzr_safe_bytes_for_1_1_1_pixels (int n_pix) 217 { 218 /* un colore con cambio colore, un colore con cambio colore */ 219 /* = 2 + 2 + 2 + 2 nibble = 4 bytes per 2 pixel */ 220 221 return 2 * n_pix + 2; 222 } 223 224 /*---------------------------------------------------------------------------*/ 225 226 int tzr_safe_bytes_for_2_1_1_pixels (int n_pix) 227 { 228 /* un colore con cambio colore, un colore con cambio colore */ 229 /* = 2 + 4 + 2 + 4 nibble = 6 bytes per 2 pixel */ 230 231 return 4 * n_pix + 2; 232 } 233 234 /*---------------------------------------------------------------------------*/ 235 236 #define GET_INVAL \ 237 { \ 238 inval = *in++; \ 239 remain--; \ 240 } 241 #define PUT_OUTVAL \ 242 { *out++ = (UCHAR)outval; } 243 244 /*---------------------------------------------------------------------------*/ 245 246 int tzr_encode_cm16_1_1_1 (USHORT *buf_in, int buf_in_len, 247 UCHAR *buf_out) 248 { 249 int count, prevremain, remain; 250 UINT inval, outval; 251 UINT lastval, lastcol__; 252 UINT colmask, maxtone; 253 UINT incol__, tone; 254 USHORT *in, save; 255 UCHAR *out; 256 257 maxtone = 0xF; 258 colmask = 0x07F0; 259 260 remain = buf_in_len; 261 lastval = maxtone; 262 lastcol__ = 0; 263 264 in = buf_in; 265 out = buf_out; 266 267 if (buf_in_len <= 1) { 268 if (buf_in_len < 0) return 0; 269 if (buf_in_len == 0) { 270 outval = 0xFF; 271 PUT_OUTVAL 272 outval = 0xE0; 273 PUT_OUTVAL 274 } else { 275 GET_INVAL 276 if (inval & colmask) { 277 outval = 0xF8; 278 PUT_OUTVAL 279 } 280 outval = 0xFF; 281 PUT_OUTVAL 282 outval = 0xF0 | inval & 0xF; 283 PUT_OUTVAL 284 } 285 return out - buf_out; 286 } 287 288 save = buf_in[buf_in_len - 1]; 289 buf_in[buf_in_len - 1] = buf_in[buf_in_len - 2] ^ colmask; 290 291 GET_INVAL 292 293 check_colpen_on_out0: 294 incol__ = inval & colmask; 295 if (incol__) incol__ = 0x10; 296 if (incol__ == lastcol__) goto check_tone_on_out0; 297 lastcol__ = incol__; 298 if (!remain) goto end_toonz1_encoding_on_out0; 299 300 outval = (0xF << 4) | 0x8; 301 PUT_OUTVAL 302 303 check_tone_on_out0: 304 tone = inval & maxtone; 305 if (tone == maxtone) { 306 lastval = inval; 307 prevremain = remain; 308 do 309 GET_INVAL 310 while (inval == lastval); 311 count = prevremain - remain - 1; 312 if (count <= 0xF) 313 if (count == 0) { 314 outval = (0xF << 4) | 0x0; 315 PUT_OUTVAL 316 goto check_colpen_on_out0; 317 } else { 318 outval = (0xF << 4) | 0x1; 319 PUT_OUTVAL 320 outval = count << 4; 321 goto check_colpen_on_out1; 322 } 323 else if (count <= 0xFF) { 324 outval = (0xF << 4) | 0x2; 325 PUT_OUTVAL 326 outval = count; 327 PUT_OUTVAL 328 goto check_colpen_on_out0; 329 } else if (count <= 0xFFF) { 330 outval = (0xF << 4) | 0x3; 331 PUT_OUTVAL 332 outval = count >> 4; 333 PUT_OUTVAL 334 outval = count << 4; 335 goto check_colpen_on_out1; 336 } else if (count <= 0xFFFF) { 337 outval = (0xF << 4) | 0x4; 338 PUT_OUTVAL 339 outval = count >> 8; 340 PUT_OUTVAL 341 outval = count; 342 PUT_OUTVAL 343 goto check_colpen_on_out0; 344 } else if (count <= 0xFFFFF) { 345 outval = (0xF << 4) | 0x5; 346 PUT_OUTVAL 347 outval = count >> 12; 348 PUT_OUTVAL 349 outval = count >> 4; 350 PUT_OUTVAL 351 outval = count << 4; 352 goto check_colpen_on_out1; 353 } else if (count <= 0xFFFFFF) { 354 outval = (0xF << 4) | 0x6; 355 PUT_OUTVAL 356 outval = count >> 16; 357 PUT_OUTVAL 358 outval = count >> 8; 359 PUT_OUTVAL 360 outval = count; 361 PUT_OUTVAL 362 goto check_colpen_on_out0; 363 } else if (count <= 0xFFFFFFF) { 364 outval = (0xF << 4) | 0x7; 365 PUT_OUTVAL 366 outval = count >> 20; 367 PUT_OUTVAL 368 outval = count >> 12; 369 PUT_OUTVAL 370 outval = count >> 4; 371 PUT_OUTVAL 372 outval = count << 4; 373 goto check_colpen_on_out1; 374 } else { 375 buf_in[buf_in_len - 1] = save; 376 return 0; 377 } 378 } else { 379 outval = tone << 4; 380 GET_INVAL 381 /*goto check_colpen_on_out1;*/ 382 } 383 384 check_colpen_on_out1: 385 incol__ = inval & colmask; 386 if (incol__) incol__ = 0x10; 387 if (incol__ == lastcol__) goto check_tone_on_out1; 388 lastcol__ = incol__; 389 if (!remain) goto end_toonz1_encoding_on_out1; 390 391 outval |= 0xF; 392 PUT_OUTVAL 393 outval = 0x8 << 4; 394 395 check_tone_on_out1: 396 tone = inval & maxtone; 397 if (tone == maxtone) { 398 lastval = inval; 399 prevremain = remain; 400 do 401 GET_INVAL 402 while (inval == lastval); 403 count = prevremain - remain - 1; 404 outval |= 0xF; 405 PUT_OUTVAL 406 if (count <= 0xF) 407 if (count == 0) { 408 outval = 0x0 << 4; 409 goto check_colpen_on_out1; 410 } else { 411 outval = (0x1 << 4) | count; 412 PUT_OUTVAL 413 goto check_colpen_on_out0; 414 } 415 else if (count <= 0xFF) { 416 outval = (0x2 << 4) | (count >> 4); 417 PUT_OUTVAL 418 outval = count << 4; 419 goto check_colpen_on_out1; 420 } else if (count <= 0xFFF) { 421 outval = (0x3 << 4) | (count >> 8); 422 PUT_OUTVAL 423 outval = count; 424 PUT_OUTVAL 425 goto check_colpen_on_out0; 426 } else if (count <= 0xFFFF) { 427 outval = (0x4 << 4) | (count >> 12); 428 PUT_OUTVAL 429 outval = count >> 4; 430 PUT_OUTVAL 431 outval = count << 4; 432 goto check_colpen_on_out1; 433 } else if (count <= 0xFFFFF) { 434 outval = (0x5 << 4) | (count >> 16); 435 PUT_OUTVAL 436 outval = count >> 8; 437 PUT_OUTVAL 438 outval = count; 439 PUT_OUTVAL 440 goto check_colpen_on_out0; 441 } else if (count <= 0xFFFFFF) { 442 outval = (0x6 << 4) | (count >> 20); 443 PUT_OUTVAL 444 outval = count >> 12; 445 PUT_OUTVAL 446 outval = count >> 4; 447 PUT_OUTVAL 448 outval = count << 4; 449 goto check_colpen_on_out1; 450 } else if (count <= 0xFFFFFFF) { 451 outval = (0x7 << 4) | (count >> 24); 452 PUT_OUTVAL 453 outval = count >> 16; 454 PUT_OUTVAL 455 outval = count >> 8; 456 PUT_OUTVAL 457 outval = count; 458 PUT_OUTVAL 459 goto check_colpen_on_out0; 460 } else { 461 buf_in[buf_in_len - 1] = save; 462 return 0; 463 } 464 } else { 465 outval |= tone; 466 PUT_OUTVAL 467 GET_INVAL 468 goto check_colpen_on_out0; 469 } 470 471 end_toonz1_encoding_on_out0: 472 if ((save & colmask) != (in[-2] & colmask)) { 473 outval = 0xF8; 474 PUT_OUTVAL 475 } 476 outval = 0xFF; 477 PUT_OUTVAL 478 outval = 0xF0 | save & 0xF; 479 PUT_OUTVAL 480 buf_in[buf_in_len - 1] = save; 481 return out - buf_out; 482 483 end_toonz1_encoding_on_out1: 484 if ((save & colmask) != (in[-2] & colmask)) { 485 outval |= 0xF; 486 PUT_OUTVAL 487 outval = 0x80; 488 } 489 outval |= 0xF; 490 PUT_OUTVAL 491 outval = 0xFF; 492 PUT_OUTVAL 493 outval = (save & 0xF) << 4; 494 PUT_OUTVAL 495 buf_in[buf_in_len - 1] = save; 496 return out - buf_out; 497 } 498 499 /*---------------------------------------------------------------------------*/ 500 501 int tzr_encode_cm24_2_1_1 (ULONG *buf_in, int buf_in_len, 502 UCHAR *buf_out) 503 { 504 int count, prevremain, remain; 505 UINT inval, outval; 506 UINT lastval, lastcol__; 507 UINT colmask, maxtone; 508 UINT incol__, tone; 509 ULONG *in, save; 510 UCHAR *out; 511 512 maxtone = 0xFF; 513 colmask = 0x0FF00; 514 515 remain = buf_in_len; 516 lastval = maxtone; 517 lastcol__ = 0; 518 519 in = buf_in; 520 out = buf_out; 521 522 if (buf_in_len <= 1) { 523 if (buf_in_len < 0) return 0; 524 if (buf_in_len == 0) { 525 outval = 0xFFFF; 526 PUT_OUTVAL 527 outval = 0xFE; 528 PUT_OUTVAL 529 } else { 530 GET_INVAL 531 if (inval & colmask) { 532 outval = 0xF8; 533 PUT_OUTVAL 534 } 535 outval = 0xFF; 536 PUT_OUTVAL 537 if ((inval & 0xF) == 0xF) inval--; 538 outval = 0xF0 | inval & 0xF; 539 PUT_OUTVAL 540 outval = (inval & 0xF0) >> 4; 541 } 542 return out - buf_out; 543 } 544 545 save = buf_in[buf_in_len - 1]; 546 buf_in[buf_in_len - 1] = buf_in[buf_in_len - 2] ^ colmask; 547 548 GET_INVAL 549 550 check_colpen_on_out0: 551 incol__ = inval & colmask; 552 if (incol__) incol__ = 0x100; 553 if (incol__ == lastcol__) goto check_tone_on_out0; 554 lastcol__ = incol__; 555 if (!remain) goto end_toonz1_encoding_and_save_on_out0; 556 557 outval = 0xFF; 558 PUT_OUTVAL 559 outval = 0x8 << 4; 560 goto check_tone_on_out1; 561 562 check_tone_on_out0: 563 tone = inval & maxtone; 564 if (tone == maxtone) { 565 lastval = inval; 566 prevremain = remain; 567 do 568 GET_INVAL 569 while (inval == lastval); 570 count = prevremain - remain - 1; 571 if (count <= 0xF) 572 if (count == 0) { 573 outval = 0xFF; 574 PUT_OUTVAL 575 outval = 0x0 << 4; 576 goto check_colpen_on_out1; 577 } else { 578 outval = 0xFF; 579 PUT_OUTVAL 580 outval = (0x1 << 4) | count; 581 PUT_OUTVAL 582 goto check_colpen_on_out0; 583 } 584 else if (count <= 0xFF) { 585 outval = 0xFF; 586 PUT_OUTVAL 587 outval = (0x2 << 4) | (count >> 4); 588 PUT_OUTVAL 589 outval = (count & 0xF) << 4; 590 goto check_colpen_on_out1; 591 } else if (count <= 0xFFF) { 592 outval = 0xFF; 593 PUT_OUTVAL 594 outval = (0x3 << 4) | (count >> 8); 595 PUT_OUTVAL 596 outval = count & 0xFF; 597 PUT_OUTVAL 598 goto check_colpen_on_out0; 599 } else if (count <= 0xFFFF) { 600 outval = 0xFF; 601 PUT_OUTVAL 602 outval = (0x4 << 4) | (count >> 12); 603 PUT_OUTVAL 604 outval = (count & 0xFF0) >> 4; 605 PUT_OUTVAL 606 outval = (count & 0xF) << 4; 607 goto check_colpen_on_out1; 608 } else if (count <= 0xFFFFF) { 609 outval = 0xFF; 610 PUT_OUTVAL 611 outval = (0x5 << 4) | (count >> 16); 612 PUT_OUTVAL 613 outval = (count & 0xFF0) >> 4; 614 PUT_OUTVAL 615 outval = (count & 0xFF000) >> 12; 616 PUT_OUTVAL 617 goto check_colpen_on_out0; 618 } else if (count <= 0xFFFFFF) { 619 outval = 0xFF; 620 PUT_OUTVAL 621 outval = (0x6 << 4) | (count >> 20); 622 PUT_OUTVAL 623 outval = (count & 0xFF0) >> 4; 624 PUT_OUTVAL 625 outval = (count & 0xFF000) >> 12; 626 PUT_OUTVAL 627 outval = (count & 0xF00000) >> 16; 628 goto check_colpen_on_out1; 629 } else if (count <= 0xFFFFFFF) { 630 outval = 0xFF; 631 PUT_OUTVAL 632 outval = (0x7 << 4) | (count >> 24); 633 PUT_OUTVAL 634 outval = (count & 0xFF0) >> 4; 635 PUT_OUTVAL 636 outval = (count & 0xFF000) >> 12; 637 PUT_OUTVAL 638 outval = (count & 0xFF00000) >> 20; 639 PUT_OUTVAL 640 goto check_colpen_on_out0; 641 } else { 642 buf_in[buf_in_len - 1] = save; 643 return 0; 644 } 645 } else { 646 /*if ((tone & 0xF)==0xF) tone--;*/ 647 outval = (((tone & 0xF) << 4) | ((tone & 0xF0)) >> 4); 648 PUT_OUTVAL 649 GET_INVAL 650 goto check_colpen_on_out0; 651 } 652 653 check_colpen_on_out1: 654 incol__ = inval & colmask; 655 if (incol__) incol__ = 0x100; 656 if (incol__ == lastcol__) goto check_tone_on_out1; 657 lastcol__ = incol__; 658 if (!remain) goto end_toonz1_encoding_and_save_on_out1; 659 660 outval |= 0xF; 661 PUT_OUTVAL 662 outval = (0xF << 4) | 0x8; 663 PUT_OUTVAL 664 goto check_tone_on_out0; 665 666 check_tone_on_out1: 667 tone = inval & maxtone; 668 if (tone == maxtone) { 669 lastval = inval; 670 prevremain = remain; 671 do 672 GET_INVAL 673 while (inval == lastval); 674 count = prevremain - remain - 1; 675 outval |= 0xF; 676 PUT_OUTVAL 677 outval = 0xF << 4; 678 if (count <= 0xF) 679 if (count == 0) { 680 outval |= 0x0; 681 PUT_OUTVAL 682 goto check_colpen_on_out0; 683 } else { 684 outval |= 0x1; 685 PUT_OUTVAL 686 outval = count << 4; 687 goto check_colpen_on_out1; 688 } 689 else if (count <= 0xFF) { 690 outval |= 0x2; 691 PUT_OUTVAL 692 outval = count; 693 PUT_OUTVAL 694 goto check_colpen_on_out0; 695 } else if (count <= 0xFFF) { 696 outval |= 0x3; 697 PUT_OUTVAL 698 outval = count >> 4; 699 PUT_OUTVAL 700 outval = (count & 0XF) << 4; 701 goto check_colpen_on_out1; 702 } else if (count <= 0xFFFF) { 703 outval |= 0x4; 704 PUT_OUTVAL 705 outval = count >> 8; 706 PUT_OUTVAL 707 outval = count & 0XFF; 708 PUT_OUTVAL 709 goto check_colpen_on_out0; 710 } else if (count <= 0xFFFFF) { 711 outval |= 0x5; 712 PUT_OUTVAL 713 outval = count >> 12; 714 PUT_OUTVAL 715 outval = (count & 0XFF0) >> 4; 716 PUT_OUTVAL 717 outval = (count & 0XF) << 4; 718 goto check_colpen_on_out1; 719 } else if (count <= 0xFFFFFF) { 720 outval |= 0x6; 721 PUT_OUTVAL 722 outval = count >> 16; 723 PUT_OUTVAL 724 outval = (count & 0XFF00) >> 8; 725 PUT_OUTVAL 726 outval = count & 0XFF; 727 PUT_OUTVAL 728 goto check_colpen_on_out0; 729 } else if (count <= 0xFFFFFFF) { 730 outval |= 0x7; 731 PUT_OUTVAL 732 outval = count >> 20; 733 PUT_OUTVAL 734 outval = (count & 0XFF000) >> 12; 735 PUT_OUTVAL 736 outval = (count & 0XFF0) >> 4; 737 PUT_OUTVAL 738 outval = (count & 0XF) << 4; 739 goto check_colpen_on_out1; 740 } else { 741 buf_in[buf_in_len - 1] = save; 742 return 0; 743 } 744 } else { 745 /*if ((tone & 0xF)==0xF) tone--;*/ 746 outval |= tone & 0xF; 747 PUT_OUTVAL 748 outval = (tone & 0xF0); 749 /*PUT_OUTVAL*/ 750 GET_INVAL 751 goto check_colpen_on_out1; 752 } 753 754 end_toonz1_encoding_and_save_on_out0: 755 if ((save & colmask) != (in[-2] & colmask)) { 756 outval = 0xFF; 757 PUT_OUTVAL 758 outval = 0x8 << 4; 759 goto end_toonz1_encoding_on_out1; 760 } 761 762 end_toonz1_encoding_on_out0: 763 764 outval = 0xFF; 765 PUT_OUTVAL 766 outval = 0xFF; 767 PUT_OUTVAL 768 outval = (save & 0xF) << 4; 769 outval |= (save & 0xF0) >> 4; 770 PUT_OUTVAL 771 buf_in[buf_in_len - 1] = save; 772 return out - buf_out; 773 774 end_toonz1_encoding_and_save_on_out1: 775 if ((save & colmask) != (in[-2] & colmask)) { 776 outval |= 0xF; 777 PUT_OUTVAL 778 outval = (0xF << 4) | 0x80; 779 PUT_OUTVAL 780 goto end_toonz1_encoding_on_out0; 781 } 782 end_toonz1_encoding_on_out1: 783 784 outval |= 0xF; 785 PUT_OUTVAL 786 outval = 0xFF; 787 PUT_OUTVAL 788 outval = (0xF << 4) | (save & 0xF); 789 PUT_OUTVAL 790 outval = (save & 0xF0); 791 PUT_OUTVAL 792 buf_in[buf_in_len - 1] = save; 793 return out - buf_out; 794 795 } 796 797 /*---------------------------------------------------------------------------*/ 798 799 static TBOOL write_tzr_1_1_1 (char *filename, FILE *file, IMAGE *image) 800 { 801 int lx, ly, wrap, safe_bytes, enc, enclen_bytes, bytes, y; 802 USHORT *buffer, *line; 803 UCHAR *tzr_buf; 804 805 lx = image->pixmap.xsize; 806 ly = image->pixmap.ysize; 807 wrap = lx; 808 enclen_bytes = 2 + (lx > 8 * 1024); 809 safe_bytes = enclen_bytes + tzr_safe_bytes_for_1_1_1_pixels(lx); 810 tzr_buf = Tzr_buffer; 811 if (safe_bytes > Tzr_buffer_bytes) { 812 TREALLOC(tzr_buf, safe_bytes) 813 Tzr_buffer = tzr_buf; 814 if (Tzr_buffer) 815 Tzr_buffer_bytes = safe_bytes; 816 else { 817 Tzr_buffer_bytes = 0; 818 return FALSE; 819 } 820 } 821 buffer = image->pixmap.buffer; 822 for (line = buffer, y = 0; y < ly; line += wrap, y++) { 823 enc = tzr_encode_cm16_1_1_1(line, lx, tzr_buf + enclen_bytes); 824 if (enclen_bytes == 2) { 825 tzr_buf[0] = (enc >> 8) & 0xFF; 826 tzr_buf[1] = enc & 0xFF; 827 } else { 828 tzr_buf[0] = (enc >> 16) & 0xFF; 829 tzr_buf[1] = (enc >> 8) & 0xFF; 830 tzr_buf[2] = enc & 0xFF; 831 } 832 bytes = enclen_bytes + enc; 833 if (fwrite(tzr_buf, 1, bytes, file) != bytes) return FALSE; 834 } 835 return TRUE; 836 } 837 838 /*---------------------------------------------------------------------------*/ 839 840 static TBOOL write_tzr_2_1_1 (char *filename, FILE *file, IMAGE *image) 841 { 842 int lx, ly, wrap, safe_bytes, enc, enclen_bytes, bytes, y; 843 ULONG *buffer, *line; 844 UCHAR *tzr_buf; 845 846 lx = image->pixmap.xsize; 847 ly = image->pixmap.ysize; 848 wrap = lx; 849 enclen_bytes = 2 + (lx > 8 * 1024); 850 safe_bytes = enclen_bytes + tzr_safe_bytes_for_2_1_1_pixels(lx); 851 tzr_buf = Tzr_buffer; 852 if (safe_bytes > Tzr_buffer_bytes) { 853 TREALLOC(tzr_buf, safe_bytes) 854 Tzr_buffer = tzr_buf; 855 if (Tzr_buffer) 856 Tzr_buffer_bytes = safe_bytes; 857 else { 858 Tzr_buffer_bytes = 0; 859 return FALSE; 860 } 861 } 862 buffer = (ULONG *)image->pixmap.buffer; 863 for (line = buffer, y = 0; y < ly; line += wrap, y++) { 864 int i; 865 enc = tzr_encode_cm24_2_1_1(line, lx, tzr_buf + enclen_bytes); 866 /*for (i=0; i<enc; i+=4) 867 printf("*** %x %x %x %x\n", tzr_buf[enclen_bytes+i], 868 tzr_buf[enclen_bytes+i+1], 869 tzr_buf[enclen_bytes+i+2], 870 tzr_buf[enclen_bytes+i+3]); */ 871 if (enclen_bytes == 2) { 872 tzr_buf[0] = (enc >> 8) & 0xFF; 873 tzr_buf[1] = enc & 0xFF; 874 } else { 875 tzr_buf[0] = (enc >> 16) & 0xFF; 876 tzr_buf[1] = (enc >> 8) & 0xFF; 877 tzr_buf[2] = enc & 0xFF; 878 } 879 bytes = enclen_bytes + enc; 880 if (fwrite(tzr_buf, 1, bytes, file) != bytes) return FALSE; 881 } 882 return TRUE; 883 } 884 885 /*---------------------------------------------------------------------------*/ 886 887 static TBOOL write_tzr_header (char *filename, FILE *file, IMAGE *image, 888 UINT tzr_type) 889 { 890 UCHAR buf[100 + TAGS_BUFLEN]; 891 ULONG *buf32; 892 int lx, ly, img_offs = 0, img_offs_offs = 0, pos = 0; 893 double x_dpi, y_dpi, h_pos; 894 895 switch (tzr_type) { 896 CASE 0x01010100 : __OR 0x02010100 : lx = image->pixmap.xsize; 897 ly = image->pixmap.ysize; 898 buf32 = (ULONG *)buf; 899 *buf32 = TZR_MAGIC; 900 buf[4] = (tzr_type >> 24) & 0xFF; 901 buf[5] = (tzr_type >> 16) & 0xFF; 902 buf[6] = (tzr_type >> 8) & 0xFF; 903 buf[7] = tzr_type & 0xFF; 904 buf[8] = (lx >> 16) & 0xFF; 905 buf[9] = (lx >> 8) & 0xFF; 906 buf[10] = lx & 0xFF; 907 buf[11] = (ly >> 16) & 0xFF; 908 buf[12] = (ly >> 8) & 0xFF; 909 buf[13] = ly & 0xFF; 910 img_offs_offs = 14; 911 pos = img_offs_offs + 3; 912 913 DEFAULT: 914 assert(FALSE); 915 } 916 if (image->pixmap.x_dpi && image->pixmap.y_dpi) { 917 buf[pos] = TAG_DPI; 918 buf[pos + 1] = 8 + 8; 919 x_dpi = image->pixmap.x_dpi; 920 y_dpi = image->pixmap.y_dpi; 921 DOUBLE_TO_BYTES(x_dpi, buf + pos + 2) 922 DOUBLE_TO_BYTES(y_dpi, buf + pos + 10) 923 pos += 1 + 1 + 8 + 8; 924 } 925 if (image->pixmap.h_pos) { 926 buf[pos] = TAG_HPOS; 927 buf[pos + 1] = 8; 928 h_pos = image->pixmap.h_pos; 929 DOUBLE_TO_BYTES(h_pos, buf + pos + 2) 930 pos += 1 + 1 + 8; 931 } 932 img_offs = pos; 933 buf[img_offs_offs] = (img_offs >> 16) & 0xFF; 934 buf[img_offs_offs + 1] = (img_offs >> 8) & 0xFF; 935 buf[img_offs_offs + 2] = img_offs & 0xFF; 936 if (fwrite(buf, 1, img_offs, file) != img_offs) return FALSE; 937 938 return TRUE; 939 } 940 941 /*---------------------------------------------------------------------------*/ 942 943 TBOOL img_write_tzr (char *filename, IMAGE *image) 944 { 945 FILE *file; 946 UCHAR buf[256]; 947 UINT tzr_type; 948 949 file = fopen(filename, "wb"); 950 if (!file) return FALSE; 951 switch (image->type) { 952 CASE CMAPPED : tzr_type = 0x01010100; 953 CASE CMAPPED24 : tzr_type = 0x02010100; 954 DEFAULT: 955 tmsg_error("bad image type for .tzr files"); 956 goto error; 957 } 958 if (!write_tzr_header(filename, file, image, tzr_type)) goto error; 959 switch (tzr_type) { 960 CASE 0x01010100 : if (!write_tzr_1_1_1(filename, file, image)) goto error; 961 CASE 0x02010100 : if (!write_tzr_2_1_1(filename, file, image)) goto error; 962 DEFAULT: 963 goto error; 964 } 965 fclose(file); 966 return TRUE; 967 968 error: 969 if (file) fclose(file); 970 return FALSE; 971 } 972 973 /*---------------------------------------------------------------------------*/ 974 975 int tzr_decode_1_1_1_cm16 (UCHAR *buf_in, int *buf_in_len, 976 USHORT *buf_out) 977 { 978 UCHAR *in; 979 USHORT *out; 980 int count; 981 UINT inval, in0, in1; 982 UINT outval, maxtone, outval_maxtone; 983 984 #define GET_IN0 (inval = *in++, in1 = inval & 0xF, in0 = inval >> 4) 985 986 maxtone = 0xF; 987 outval = 0; 988 outval_maxtone = outval | maxtone; 989 count = 0; 990 991 in = buf_in; 992 out = buf_out; 993 994 goto start_from_in0; 995 996 count_out_and_start_from_in0: 997 outval_maxtone = outval | maxtone; 998 *out++ = outval_maxtone; 999 while (count--) *out++ = outval_maxtone; 1000 1001 start_from_in0: 1002 if (GET_IN0 == 0xF) { 1003 switch (in1) { 1004 CASE 0x0 : *out++ = outval | maxtone; 1005 goto start_from_in0; 1006 1007 CASE 0x1 : count = GET_IN0; 1008 goto count_out_and_start_from_in1; 1009 1010 CASE 0x2 : count = *in++; 1011 goto count_out_and_start_from_in0; 1012 1013 CASE 0x3 : count = *in++ << 4; 1014 count += GET_IN0; 1015 goto count_out_and_start_from_in1; 1016 1017 CASE 0x4 : count = *in++ << 8; 1018 count += *in++; 1019 goto count_out_and_start_from_in0; 1020 1021 CASE 0x5 : count = *in++ << 12; 1022 count += *in++ << 4; 1023 count += GET_IN0; 1024 goto count_out_and_start_from_in1; 1025 1026 CASE 0x6 : count = *in++ << 16; 1027 count += *in++ << 8; 1028 count += *in++; 1029 goto count_out_and_start_from_in0; 1030 1031 CASE 0x7 : count = *in++ << 20; 1032 count += *in++ << 12; 1033 count += *in++ << 4; 1034 count += GET_IN0; 1035 goto count_out_and_start_from_in1; 1036 1037 CASE 0x8 : outval ^= 0x10; 1038 goto start_from_in0; 1039 1040 CASE 0xF : switch (GET_IN0) { 1041 CASE 0xE : CASE 0xF : *out++ = outval | in1; 1042 DEFAULT: 1043 goto rle_decoding_error; 1044 } 1045 goto end_rle_decoding; 1046 1047 DEFAULT: 1048 goto rle_decoding_error; 1049 } 1050 } else { 1051 *out++ = outval | in0; 1052 goto start_from_in1; 1053 } 1054 1055 count_out_and_start_from_in1: 1056 outval_maxtone = outval | maxtone; 1057 *out++ = outval_maxtone; 1058 while (count--) *out++ = outval_maxtone; 1059 1060 start_from_in1: 1061 if (in1 == 0xF) { 1062 switch (GET_IN0) { 1063 CASE 0x0 : *out++ = outval | maxtone; 1064 goto start_from_in1; 1065 1066 CASE 0x1 : count = in1; 1067 goto count_out_and_start_from_in0; 1068 1069 CASE 0x2 : count = in1 << 4; 1070 count += GET_IN0; 1071 goto count_out_and_start_from_in1; 1072 1073 CASE 0x3 : count = in1 << 8; 1074 count += *in++; 1075 goto count_out_and_start_from_in0; 1076 1077 CASE 0x4 : count = in1 << 12; 1078 count += *in++ << 4; 1079 count += GET_IN0; 1080 goto count_out_and_start_from_in1; 1081 1082 CASE 0x5 : count = in1 << 16; 1083 count += *in++ << 8; 1084 count += *in++; 1085 goto count_out_and_start_from_in0; 1086 1087 CASE 0x6 : count = in1 << 20; 1088 count += *in++ << 12; 1089 count += *in++ << 4; 1090 count += GET_IN0; 1091 goto count_out_and_start_from_in1; 1092 1093 CASE 0x7 : count = in1 << 24; 1094 count += *in++ << 16; 1095 count += *in++ << 8; 1096 count += *in++; 1097 goto count_out_and_start_from_in0; 1098 1099 CASE 0x8 : outval ^= 0x10; 1100 goto start_from_in1; 1101 1102 CASE 0xF : switch (in1) { 1103 CASE 0xE : CASE 0xF : *out++ = outval | *in++ >> 4; 1104 DEFAULT: 1105 goto rle_decoding_error; 1106 } 1107 goto end_rle_decoding; 1108 1109 DEFAULT: 1110 return 0; 1111 } 1112 } else { 1113 *out++ = outval | in1; 1114 goto start_from_in0; 1115 } 1116 1117 end_rle_decoding: 1118 if (buf_in_len) *buf_in_len = in - buf_in; 1119 return out - buf_out; 1120 1121 rle_decoding_error: 1122 if (buf_in_len) *buf_in_len = 0; 1123 return 0; 1124 } 1125 1126 /*---------------------------------------------------------------------------*/ 1127 1128 int tzr_decode_2_1_1_cm24 (UCHAR *buf_in, int *buf_in_len, 1129 ULONG *buf_out) 1130 { 1131 UCHAR *in; 1132 ULONG *out; 1133 int count; 1134 UINT inval, in0, in1, aux; 1135 UINT outval, maxtone, outval_maxtone; 1136 1137 #define GET_IN0 (inval = *in++, in1 = inval & 0xF, in0 = inval >> 4) 1138 1139 maxtone = 0xFF; 1140 outval = 0; 1141 outval_maxtone = outval | maxtone; 1142 count = 0; 1143 1144 in = buf_in; 1145 out = buf_out; 1146 1147 goto start_from_in0; 1148 1149 count_out_and_start_from_in0: 1150 outval_maxtone = outval | maxtone; 1151 *out++ = outval_maxtone; 1152 while (count--) *out++ = outval_maxtone; 1153 start_from_in0: 1154 GET_IN0; 1155 if (inval == 0xFF) { 1156 GET_IN0; 1157 switch (in0) { 1158 CASE 0x0 : *out++ = outval | maxtone; 1159 goto start_from_in1; 1160 1161 CASE 0x1 : count = in1; 1162 goto count_out_and_start_from_in0; 1163 1164 CASE 0x2 : count = in1 << 4; 1165 count += GET_IN0; 1166 goto count_out_and_start_from_in1; 1167 1168 CASE 0x3 : count = in1 << 8; 1169 count += *in++; 1170 goto count_out_and_start_from_in0; 1171 1172 CASE 0x4 : count = in1 << 12; 1173 count += *in++ << 4; 1174 count += GET_IN0; 1175 goto count_out_and_start_from_in1; 1176 1177 CASE 0x5 : count = in1 << 16; 1178 count += *in++ << 8; 1179 count += *in++; 1180 goto count_out_and_start_from_in0; 1181 1182 CASE 0x6 : count = in1 << 20; 1183 count += *in++ << 12; 1184 count += *in++ << 4; 1185 count += GET_IN0; 1186 goto count_out_and_start_from_in1; 1187 1188 CASE 0x7 : count = in1 << 24; 1189 count += *in++ << 16; 1190 count += *in++ << 8; 1191 count += *in++; 1192 goto count_out_and_start_from_in0; 1193 1194 CASE 0x8 : outval ^= 0x100; 1195 goto start_from_in1; 1196 1197 CASE 0xF : switch (in1) { 1198 CASE 0xE : CASE 0xF : GET_IN0; 1199 *out++ = outval | ((in1 << 4) | in0); 1200 DEFAULT: 1201 goto rle_decoding_error; 1202 } 1203 goto end_rle_decoding; 1204 1205 DEFAULT: 1206 goto rle_decoding_error; 1207 } 1208 } else { 1209 *out++ = outval | ((in1 << 4) | in0); 1210 goto start_from_in0; 1211 } 1212 1213 count_out_and_start_from_in1: 1214 outval_maxtone = outval | maxtone; 1215 *out++ = outval_maxtone; 1216 while (count--) *out++ = outval_maxtone; 1217 1218 start_from_in1: 1219 aux = in1; 1220 GET_IN0; 1221 if (in0 == 0xF && aux == 0xF) { 1222 switch (in1) { 1223 CASE 0x0 : *out++ = outval | maxtone; 1224 goto start_from_in0; 1225 1226 CASE 0x1 : GET_IN0; 1227 count = in0; 1228 goto count_out_and_start_from_in1; 1229 1230 CASE 0x2 : count = *in++; 1231 goto count_out_and_start_from_in0; 1232 1233 CASE 0x3 : count = *in++ << 4; 1234 count += GET_IN0; 1235 goto count_out_and_start_from_in1; 1236 1237 CASE 0x4 : count = *in++ << 8; 1238 count += *in++; 1239 goto count_out_and_start_from_in0; 1240 1241 CASE 0x5 : count = *in++ << 12; 1242 count += *in++ << 4; 1243 count += GET_IN0; 1244 goto count_out_and_start_from_in1; 1245 1246 CASE 0x6 : count = *in++ << 16; 1247 count += *in++ << 8; 1248 count += *in++; 1249 goto count_out_and_start_from_in0; 1250 1251 CASE 0x7 : count = *in++ << 20; 1252 count += *in++ << 12; 1253 count += *in++ << 4; 1254 count += GET_IN0; 1255 goto count_out_and_start_from_in1; 1256 1257 CASE 0x8 : outval ^= 0x100; 1258 goto start_from_in0; 1259 1260 CASE 0xF : switch (GET_IN0) { 1261 UINT aux; 1262 CASE 0xE : CASE 0xF : aux = in1; 1263 GET_IN0; 1264 1265 *out++ = outval | (aux | (in0 << 4)); 1266 DEFAULT: 1267 goto rle_decoding_error; 1268 } 1269 goto end_rle_decoding; 1270 1271 DEFAULT: 1272 return 0; 1273 } 1274 } else { 1275 *out++ = outval | ((in0 << 4) | aux); 1276 goto start_from_in1; 1277 } 1278 1279 end_rle_decoding: 1280 if (buf_in_len) *buf_in_len = in - buf_in; 1281 return out - buf_out; 1282 1283 rle_decoding_error: 1284 if (buf_in_len) *buf_in_len = 0; 1285 return 0; 1286 } 1287 1288 /*---------------------------------------------------------------------------*/ 1289 1290 static TBOOL read_tzr_1_1_1 (char *filename, FILE *file, IMAGE *image, 1291 int img_offs, TBOOL cmapped) 1292 { 1293 int lx, ly, wrap, y, x; 1294 USHORT *buf_cm, *line_cm; 1295 LPIXEL *buf_rgbm, *line_rgbm; 1296 int safe_bytes, enclen_bytes, enclen, dec, tzr_dec; 1297 UCHAR *tzr_buf; 1298 UINT tone, color; 1299 LPIXEL val; 1300 1301 if (fseek(file, img_offs, SEEK_SET)) { 1302 tmsg_error("inconsistent data in %s (seek failed)", filename); 1303 return FALSE; 1304 } 1305 lx = image->pixmap.xsize; 1306 ly = image->pixmap.ysize; 1307 wrap = lx; 1308 enclen_bytes = 2 + (lx > 8 * 1024); 1309 safe_bytes = enclen_bytes + tzr_safe_bytes_for_1_1_1_pixels(lx); 1310 tzr_buf = Tzr_buffer; 1311 if (safe_bytes > Tzr_buffer_bytes) { 1312 TREALLOC(tzr_buf, safe_bytes) 1313 Tzr_buffer = tzr_buf; 1314 if (Tzr_buffer) 1315 Tzr_buffer_bytes = safe_bytes; 1316 else { 1317 Tzr_buffer_bytes = 0; 1318 return FALSE; 1319 } 1320 } 1321 if (cmapped) { 1322 buf_cm = image->pixmap.buffer; 1323 for (line_cm = buf_cm, y = 0; y < ly; line_cm += wrap, y++) { 1324 READ_BYTES_OR_ERROR(tzr_buf, enclen_bytes, file) 1325 if (enclen_bytes == 2) 1326 enclen = tzr_buf[0] << 8 | tzr_buf[1]; 1327 else 1328 enclen = tzr_buf[0] << 16 | tzr_buf[1] << 8 | tzr_buf[2]; 1329 READ_BYTES_OR_ERROR(tzr_buf, enclen, file) 1330 dec = tzr_decode_1_1_1_cm16(tzr_buf, &tzr_dec, line_cm); 1331 assert(dec == lx); 1332 assert(tzr_dec == enclen); 1333 } 1334 } else { 1335 buf_rgbm = (LPIXEL *)image->pixmap.buffer; 1336 for (line_rgbm = buf_rgbm, y = 0; y < ly; line_rgbm += wrap, y++) { 1337 READ_BYTES_OR_ERROR(tzr_buf, enclen_bytes, file) 1338 if (enclen_bytes == 2) 1339 enclen = tzr_buf[0] << 8 | tzr_buf[1]; 1340 else 1341 enclen = tzr_buf[0] << 16 | tzr_buf[1] << 8 | tzr_buf[2]; 1342 READ_BYTES_OR_ERROR(tzr_buf, enclen, file) 1343 line_cm = (USHORT *)line_rgbm; 1344 dec = tzr_decode_1_1_1_cm16(tzr_buf, &tzr_dec, line_cm); 1345 assert(dec == lx); 1346 assert(tzr_dec == enclen); 1347 for (x = lx - 1; x >= 0; x--) { 1348 tone = line_cm[x] & 0xF; 1349 color = line_cm[x] & 0x10; 1350 if (color) { 1351 val.r = val.g = val.b = tone * 8; 1352 val.m = 255; 1353 } else { 1354 val.r = val.g = val.b = 0; 1355 val.m = ~(tone * 17); 1356 } 1357 line_rgbm[x] = val; 1358 } 1359 } 1360 } 1361 return TRUE; 1362 1363 error: 1364 return FALSE; 1365 } 1366 1367 /*---------------------------------------------------------------------------*/ 1368 void vaffa(void) 1369 {} 1370 1371 static TBOOL read_tzr_2_1_1 (char *filename, FILE *file, IMAGE *image, 1372 int img_offs, TBOOL cmapped) 1373 { 1374 int lx, ly, wrap, y, x; 1375 ULONG *buf_cm, *line_cm; 1376 LPIXEL *buf_rgbm, *line_rgbm; 1377 int safe_bytes, enclen_bytes, enclen, dec, tzr_dec; 1378 UCHAR *tzr_buf; 1379 UINT tone, color; 1380 LPIXEL val; 1381 1382 if (fseek(file, img_offs, SEEK_SET)) { 1383 tmsg_error("inconsistent data in %s (seek failed)", filename); 1384 return FALSE; 1385 } 1386 lx = image->pixmap.xsize; 1387 ly = image->pixmap.ysize; 1388 wrap = lx; 1389 enclen_bytes = 2 + (lx > 8 * 1024); 1390 safe_bytes = enclen_bytes + tzr_safe_bytes_for_2_1_1_pixels(lx); 1391 tzr_buf = Tzr_buffer; 1392 if (safe_bytes > Tzr_buffer_bytes) { 1393 TREALLOC(tzr_buf, safe_bytes) 1394 Tzr_buffer = tzr_buf; 1395 if (Tzr_buffer) 1396 Tzr_buffer_bytes = safe_bytes; 1397 else { 1398 Tzr_buffer_bytes = 0; 1399 return FALSE; 1400 } 1401 } 1402 if (cmapped) { 1403 int i; 1404 buf_cm = (ULONG *)image->pixmap.buffer; 1405 for (line_cm = buf_cm, y = 0; y < ly; line_cm += wrap, y++) { 1406 READ_BYTES_OR_ERROR(tzr_buf, enclen_bytes, file) 1407 if (enclen_bytes == 2) 1408 enclen = tzr_buf[0] << 8 | tzr_buf[1]; 1409 else 1410 enclen = tzr_buf[0] << 16 | tzr_buf[1] << 8 | tzr_buf[2]; 1411 READ_BYTES_OR_ERROR(tzr_buf, enclen, file) 1412 dec = tzr_decode_2_1_1_cm24(tzr_buf, &tzr_dec, line_cm); 1413 assert(dec == lx); 1414 assert(tzr_dec == enclen); 1415 } 1416 } else { 1417 buf_rgbm = (LPIXEL *)image->pixmap.buffer; 1418 for (line_rgbm = buf_rgbm, y = 0; y < ly; line_rgbm += wrap, y++) { 1419 READ_BYTES_OR_ERROR(tzr_buf, enclen_bytes, file) 1420 if (enclen_bytes == 2) 1421 enclen = tzr_buf[0] << 8 | tzr_buf[1]; 1422 else 1423 enclen = tzr_buf[0] << 16 | tzr_buf[1] << 8 | tzr_buf[2]; 1424 READ_BYTES_OR_ERROR(tzr_buf, enclen, file) 1425 line_cm = (ULONG *)line_rgbm; 1426 dec = tzr_decode_2_1_1_cm24(tzr_buf, &tzr_dec, line_cm); 1427 assert(dec == lx); 1428 assert(tzr_dec == enclen); 1429 for (x = lx - 1; x >= 0; x--) { 1430 tone = line_cm[x] & 0xFF; 1431 color = line_cm[x] & 0x100; 1432 if (color) { 1433 val.r = val.g = val.b = tone >> 1; /* ???? tone * 8;*/ 1434 val.m = 255; 1435 } else { 1436 val.r = val.g = val.b = 0; 1437 val.m = ~(tone); 1438 } 1439 line_rgbm[x] = val; 1440 } 1441 } 1442 } 1443 return TRUE; 1444 1445 error: 1446 return FALSE; 1447 } 1448 1449 /*---------------------------------------------------------------------------*/ 1450 1451 static TBOOL read_region_tzr_1_1_1 (char *filename, FILE *file, IMAGE *image, 1452 int img_offs, TBOOL cmapped, 1453 INFO_REGION *region) 1454 { 1455 int reg_lx, reg_ly, full_lx, full_ly, wrap, y, x, skip, step, k, tmp_x; 1456 USHORT *buf_cm, *line_cm, *tmp_buf; 1457 LPIXEL *buf_rgbm, *line_rgbm; 1458 int safe_bytes, decline_bytes, enclen_bytes, enclen, dec, tzr_dec; 1459 UCHAR *tzr_buf; 1460 UINT tone, color; 1461 LPIXEL val; 1462 1463 if (fseek(file, img_offs, SEEK_SET)) { 1464 tmsg_error("inconsistent data in %s (seek failed)", filename); 1465 return FALSE; 1466 } 1467 full_lx = region->lx_in; 1468 wrap = region->xsize; 1469 step = region->step; 1470 enclen_bytes = 2 + (full_lx > 8 * 1024); 1471 safe_bytes = enclen_bytes + tzr_safe_bytes_for_1_1_1_pixels(full_lx); 1472 decline_bytes = full_lx * sizeof(USHORT); 1473 tzr_buf = Tzr_buffer; 1474 if (safe_bytes + decline_bytes > Tzr_buffer_bytes) { 1475 TREALLOC(tzr_buf, safe_bytes + decline_bytes) 1476 Tzr_buffer = tzr_buf; 1477 if (Tzr_buffer) 1478 Tzr_buffer_bytes = safe_bytes + decline_bytes; 1479 else { 1480 Tzr_buffer_bytes = 0; 1481 return FALSE; 1482 } 1483 } 1484 tmp_buf = (USHORT *)(tzr_buf + safe_bytes); 1485 for (y = 0; y < region->startScanRow; y++) { 1486 READ_BYTES_OR_ERROR(tzr_buf, enclen_bytes, file) 1487 if (enclen_bytes == 2) 1488 enclen = tzr_buf[0] << 8 | tzr_buf[1]; 1489 else 1490 enclen = tzr_buf[0] << 16 | tzr_buf[1] << 8 | tzr_buf[2]; 1491 if (fseek(file, enclen, SEEK_CUR)) goto error; 1492 } 1493 buf_cm = image->pixmap.buffer; 1494 line_cm = buf_cm + region->x_offset + region->y_offset * wrap; 1495 buf_rgbm = (LPIXEL *)image->pixmap.buffer; 1496 line_rgbm = buf_rgbm + region->x_offset + region->y_offset * wrap; 1497 for (y = 0; y < region->scanNrow; y++, line_cm += wrap, line_rgbm += wrap) { 1498 READ_BYTES_OR_ERROR(tzr_buf, enclen_bytes, file) 1499 if (enclen_bytes == 2) 1500 enclen = tzr_buf[0] << 8 | tzr_buf[1]; 1501 else 1502 enclen = tzr_buf[0] << 16 | tzr_buf[1] << 8 | tzr_buf[2]; 1503 READ_BYTES_OR_ERROR(tzr_buf, enclen, file) 1504 dec = tzr_decode_1_1_1_cm16(tzr_buf, &tzr_dec, tmp_buf); 1505 assert(dec == full_lx); 1506 assert(tzr_dec == enclen); 1507 if (cmapped) 1508 for (tmp_x = region->x1, k = 0; k < region->scanNcol; 1509 k++, tmp_x += step) { 1510 line_cm[k] = tmp_buf[tmp_x]; 1511 } 1512 else { 1513 for (tmp_x = region->x1, k = 0; k < region->scanNcol; 1514 k++, tmp_x += step) { 1515 tone = tmp_buf[tmp_x] & 0xF; 1516 color = tmp_buf[tmp_x] & 0x10; 1517 if (color) { 1518 val.r = val.g = val.b = tone * 8; 1519 val.m = 255; 1520 } else { 1521 val.r = val.g = val.b = 0; 1522 val.m = ~(tone * 17); 1523 } 1524 line_rgbm[k] = val; 1525 } 1526 } 1527 if (y != region->scanNrow - 1) 1528 for (skip = 0; skip < step - 1; skip++) { 1529 READ_BYTES_OR_ERROR(tzr_buf, enclen_bytes, file) 1530 if (enclen_bytes == 2) 1531 enclen = tzr_buf[0] << 8 | tzr_buf[1]; 1532 else 1533 enclen = tzr_buf[0] << 16 | tzr_buf[1] << 8 | tzr_buf[2]; 1534 if (fseek(file, enclen, SEEK_CUR)) goto error; 1535 } 1536 } 1537 return TRUE; 1538 1539 error: 1540 return FALSE; 1541 } 1542 1543 /*---------------------------------------------------------------------------*/ 1544 1545 static TBOOL read_region_tzr_2_1_1 (char *filename, FILE *file, IMAGE *image, 1546 int img_offs, TBOOL cmapped, 1547 INFO_REGION *region) 1548 { 1549 int reg_lx, reg_ly, full_lx, full_ly, wrap, y, x, skip, step, k, tmp_x; 1550 ULONG *buf_cm, *line_cm, *tmp_buf; 1551 LPIXEL *buf_rgbm, *line_rgbm; 1552 int safe_bytes, decline_bytes, enclen_bytes, enclen, dec, tzr_dec; 1553 UCHAR *tzr_buf; 1554 UINT tone, color; 1555 LPIXEL val; 1556 1557 if (fseek(file, img_offs, SEEK_SET)) { 1558 tmsg_error("inconsistent data in %s (seek failed)", filename); 1559 return FALSE; 1560 } 1561 full_lx = region->lx_in; 1562 wrap = region->xsize; 1563 step = region->step; 1564 enclen_bytes = 2 + (full_lx > 8 * 1024); 1565 safe_bytes = enclen_bytes + tzr_safe_bytes_for_2_1_1_pixels(full_lx); 1566 decline_bytes = full_lx * sizeof(ULONG); 1567 tzr_buf = Tzr_buffer; 1568 if (safe_bytes + decline_bytes > Tzr_buffer_bytes) { 1569 TREALLOC(tzr_buf, safe_bytes + decline_bytes) 1570 Tzr_buffer = tzr_buf; 1571 if (Tzr_buffer) 1572 Tzr_buffer_bytes = safe_bytes + decline_bytes; 1573 else { 1574 Tzr_buffer_bytes = 0; 1575 return FALSE; 1576 } 1577 } 1578 tmp_buf = (ULONG *)(tzr_buf + safe_bytes); 1579 for (y = 0; y < region->startScanRow; y++) { 1580 READ_BYTES_OR_ERROR(tzr_buf, enclen_bytes, file) 1581 if (enclen_bytes == 2) 1582 enclen = tzr_buf[0] << 8 | tzr_buf[1]; 1583 else 1584 enclen = tzr_buf[0] << 16 | tzr_buf[1] << 8 | tzr_buf[2]; 1585 if (fseek(file, enclen, SEEK_CUR)) goto error; 1586 } 1587 buf_cm = (ULONG *)image->pixmap.buffer; 1588 line_cm = buf_cm + region->x_offset + region->y_offset * wrap; 1589 buf_rgbm = (LPIXEL *)image->pixmap.buffer; 1590 line_rgbm = buf_rgbm + region->x_offset + region->y_offset * wrap; 1591 for (y = 0; y < region->scanNrow; y++, line_cm += wrap, line_rgbm += wrap) { 1592 READ_BYTES_OR_ERROR(tzr_buf, enclen_bytes, file) 1593 if (enclen_bytes == 2) 1594 enclen = tzr_buf[0] << 8 | tzr_buf[1]; 1595 else 1596 enclen = tzr_buf[0] << 16 | tzr_buf[1] << 8 | tzr_buf[2]; 1597 READ_BYTES_OR_ERROR(tzr_buf, enclen, file) 1598 dec = tzr_decode_2_1_1_cm24(tzr_buf, &tzr_dec, tmp_buf); 1599 assert(dec == full_lx); 1600 assert(tzr_dec == enclen); 1601 if (cmapped) 1602 for (tmp_x = region->x1, k = 0; k < region->scanNcol; 1603 k++, tmp_x += step) { 1604 line_cm[k] = tmp_buf[tmp_x]; 1605 } 1606 else { 1607 for (tmp_x = region->x1, k = 0; k < region->scanNcol; 1608 k++, tmp_x += step) { 1609 tone = tmp_buf[tmp_x] & 0xFF; 1610 color = tmp_buf[tmp_x] & 0x100; 1611 if (color) { 1612 val.r = val.g = val.b = tone >> 1 /* ???? tone * 8 */; 1613 val.m = 255; 1614 } else { 1615 val.r = val.g = val.b = 0; 1616 val.m = ~(tone); 1617 } 1618 line_rgbm[k] = val; 1619 } 1620 } 1621 if (y != region->scanNrow - 1) 1622 for (skip = 0; skip < step - 1; skip++) { 1623 READ_BYTES_OR_ERROR(tzr_buf, enclen_bytes, file) 1624 if (enclen_bytes == 2) 1625 enclen = tzr_buf[0] << 8 | tzr_buf[1]; 1626 else 1627 enclen = tzr_buf[0] << 16 | tzr_buf[1] << 8 | tzr_buf[2]; 1628 if (fseek(file, enclen, SEEK_CUR)) goto error; 1629 } 1630 } 1631 return TRUE; 1632 1633 error: 1634 return FALSE; 1635 } 1636 1637 /*---------------------------------------------------------------------------*/ 1638 1639 static TBOOL read_tzr_header (char *filename, FILE *file, IMAGE *image, 1640 UINT *tzr_type, int *p_img_offs, TBOOL cmapped, 1641 TBOOL read_tags) 1642 { 1643 UCHAR buf[TAGS_BUFLEN]; 1644 int lx, ly, img_offs = 0; 1645 int tags_len, file_pos, pos; 1646 double x_dpi, y_dpi, h_pos; 1647 1648 *tzr_type = 0; 1649 READ_BYTES_OR_ERROR(buf, 8, file) 1650 if (*(ULONG *)buf != TZR_MAGIC) { 1651 tmsg_error("bad magic number in %s", filename); 1652 goto error; 1653 } 1654 switch (buf[4 + 0]) { 1655 CASE 1 : switch (buf[4 + 1]) { 1656 CASE 1 : switch (buf[4 + 2]) { 1657 CASE 1 : *tzr_type = 0x01010100; 1658 DEFAULT: 1659 tmsg_error("unsupported file type (%d %d %d) in %s", buf[4 + 0], 1660 buf[4 + 1], buf[4 + 2], filename); 1661 goto error; 1662 } 1663 } 1664 CASE 2 : switch (buf[4 + 1]) { 1665 CASE 1 : switch (buf[4 + 2]) { 1666 CASE 1 : *tzr_type = 0x02010100; 1667 DEFAULT: 1668 tmsg_error("unsupported file type (%d %d %d) in %s", buf[4 + 0], 1669 buf[4 + 1], buf[4 + 2], filename); 1670 goto error; 1671 } 1672 DEFAULT: 1673 tmsg_error("unsupported file type (%d %d) in %s", buf[4 + 0], buf[4 + 1], 1674 filename); 1675 goto error; 1676 } 1677 DEFAULT: 1678 tmsg_error("unsupported file type (%d) in %s", buf[4 + 0], filename); 1679 goto error; 1680 } 1681 switch (*tzr_type) { 1682 CASE 0x01010100 : __OR 0x02010100 : READ_BYTES_OR_ERROR(buf, 9, file) lx = 1683 buf[0] << 16 | buf[1] << 8 | buf[2]; 1684 ly = buf[3] << 16 | buf[4] << 8 | buf[5]; 1685 img_offs = buf[6] << 16 | buf[7] << 8 | buf[8]; 1686 if (*tzr_type == 0x01010100) { 1687 if (cmapped) { 1688 image->type = CMAPPED; 1689 image->cmap.info = Tcm_new_default_info; 1690 } else 1691 image->type = RGB; 1692 } else { 1693 if (cmapped) { 1694 image->type = CMAPPED24; 1695 image->cmap.info = Tcm_24_default_info; 1696 } else 1697 image->type = RGB; 1698 } 1699 image->pixmap.xsize = lx; 1700 image->pixmap.ysize = ly; 1701 image->pixmap.xSBsize = lx; 1702 image->pixmap.ySBsize = ly; 1703 1704 DEFAULT: 1705 assert(0); 1706 } 1707 if (read_tags) { 1708 file_pos = ftell(file); 1709 tags_len = img_offs - file_pos; 1710 if (tags_len > TAGS_BUFLEN) { 1711 tmsg_error("tags section of %s too long", filename); 1712 goto error; 1713 } 1714 if (tags_len) READ_BYTES_OR_ERROR(buf, tags_len, file) 1715 pos = 0; 1716 while (pos < tags_len) { 1717 switch (buf[pos]) { 1718 CASE TAG_DPI : if (buf[pos + 1] != 8 + 8) goto unknown_tag; 1719 BYTES_TO_DOUBLE(buf + pos + 2, x_dpi) 1720 BYTES_TO_DOUBLE(buf + pos + 10, y_dpi) 1721 image->pixmap.x_dpi = x_dpi; 1722 image->pixmap.y_dpi = y_dpi; 1723 pos += 1 + 1 + 8 + 8; 1724 1725 CASE TAG_HPOS : if (buf[pos + 1] != 8) goto unknown_tag; 1726 BYTES_TO_DOUBLE(buf + pos + 2, h_pos) 1727 image->pixmap.h_pos = h_pos; 1728 pos += 1 + 1 + 8; 1729 1730 DEFAULT: 1731 unknown_tag: 1732 if (buf[pos] >= 128) 1733 pos += 1 + 2 + (buf[pos + 1] << 8 | buf[pos + 2]); 1734 else 1735 pos += 1 + 1 + buf[pos + 1]; 1736 } 1737 } 1738 } 1739 *p_img_offs = img_offs; 1740 return TRUE; 1741 1742 error: 1743 return FALSE; 1744 } 1745 1746 /*===========================================================================*/ 1747 1748 void next_img_read_tzr_cmapped (void) 1749 { 1750 Next_img_read_tzr_cmapped = TRUE; 1751 } 1752 1753 /*---------------------------------------------------------------------------*/ 1754 1755 IMAGE *img_read_tzr (char *filename) 1756 { 1757 FILE *file; 1758 IMAGE *image; 1759 UINT tzr_type; 1760 int lx, ly, img_offs; 1761 1762 SET_READ_CMAPPED 1763 1764 file = fopen(filename, "rb"); 1765 if (!file) return NIL; 1766 image = new_img(); 1767 if (!image) goto error; 1768 if (!read_tzr_header(filename, file, image, &tzr_type, &img_offs, 1769 Read_cmapped, TRUE)) 1770 goto error; 1771 lx = image->pixmap.xsize; 1772 ly = image->pixmap.ysize; 1773 if (!allocate_pixmap(image, lx, ly)) goto error; 1774 switch (tzr_type) { 1775 CASE 0x01010100 : if (!read_tzr_1_1_1(filename, file, image, img_offs, 1776 Read_cmapped)) goto error; 1777 1778 CASE 0x02010100 : if (!read_tzr_2_1_1(filename, file, image, img_offs, 1779 Read_cmapped)) goto error; 1780 1781 DEFAULT: 1782 goto error; 1783 } 1784 fclose(file); 1785 return image; 1786 1787 error: 1788 if (image) free_img(image); 1789 if (file) fclose(file); 1790 return NIL; 1791 } 1792 1793 /*---------------------------------------------------------------------------*/ 1794 1795 IMAGE *img_read_region_tzr (char *filename, int x0, int y0, 1796 int x1, int y1, int step) 1797 { 1798 FILE *file; 1799 IMAGE *image; 1800 UINT tzr_type; 1801 int full_lx, full_ly, reg_lx, reg_ly, img_offs; 1802 INFO_REGION region; 1803 int i, pixels; 1804 1805 SET_READ_CMAPPED 1806 1807 file = fopen(filename, "rb"); 1808 if (!file) return NIL; 1809 image = new_img(); 1810 if (!image) goto error; 1811 if (!read_tzr_header(filename, file, image, &tzr_type, &img_offs, 1812 Read_cmapped, TRUE)) 1813 goto error; 1814 full_lx = image->pixmap.xsize; 1815 full_ly = image->pixmap.ysize; 1816 if (x0 == -1) x0 = full_lx - 1; 1817 if (y0 == -1) y0 = full_ly - 1; 1818 reg_lx = (x1 - x0) / step + 1; 1819 reg_ly = (y1 - y0) / step + 1; 1820 if (!allocate_pixmap(image, reg_lx, reg_ly)) goto error; 1821 1822 /* per adesso si fa un clear brutale */ 1823 pixels = reg_lx * reg_ly; 1824 switch (image->type) { 1825 CASE RGB 1826 : for (i = 0; i < pixels; i++)((ULONG *)(image->pixmap.buffer))[i] = 0; 1827 CASE CMAPPED : for (i = 0; i < pixels; 1828 i++)((USHORT *)(image->pixmap.buffer))[i] = 0xF; 1829 CASE CMAPPED24 : for (i = 0; i < pixels; 1830 i++)((ULONG *)(image->pixmap.buffer))[i] = 0xFF; 1831 DEFAULT: 1832 assert(0); 1833 } 1834 1835 getInfoRegion(®ion, x0, y0, x1, y1, step, full_lx, full_ly); 1836 1837 switch (tzr_type) { 1838 CASE 0x01010100 1839 : if (!read_region_tzr_1_1_1(filename, file, image, img_offs, 1840 Read_cmapped, ®ion)) goto error; 1841 1842 CASE 0x02010100 1843 : if (!read_region_tzr_2_1_1(filename, file, image, img_offs, 1844 Read_cmapped, ®ion)) goto error; 1845 1846 DEFAULT: 1847 goto error; 1848 } 1849 fclose(file); 1850 return image; 1851 1852 error: 1853 if (image) free_img(image); 1854 if (file) fclose(file); 1855 return NIL; 1856 } 1857 1858 /*---------------------------------------------------------------------------*/ 1859 1860 IMAGE *img_read_tzr_info (char *filename) 1861 { 1862 FILE *file; 1863 IMAGE *image; 1864 int img_offs; 1865 UINT tzr_type; 1866 1867 file = fopen(filename, "rb"); 1868 if (!file) return NIL; 1869 image = new_img(); 1870 if (!image) goto error; 1871 if (!read_tzr_header(filename, file, image, &tzr_type, &img_offs, 1872 Read_cmapped, TRUE)) 1873 goto error; 1874 fclose(file); 1875 return image; 1876 1877 error: 1878 if (image) free_img(image); 1879 if (file) fclose(file); 1880 return NIL; 1881 } 1882