00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #ifdef HAVE_CONFIG_H
00058 # include "config.h"
00059 #endif
00060 #if NEED_GNUG_PRAGMAS
00061 # pragma implementation
00062 #endif
00063
00064
00065
00066
00067
00068
00069
00070 #define IW44IMAGE_IMPLIMENTATION
00071
00072
00073 #include "IW44Image.h"
00074 #include "ZPCodec.h"
00075 #include "GBitmap.h"
00076 #include "GPixmap.h"
00077 #include "IFFByteStream.h"
00078 #include "GRect.h"
00079
00080 #include <stdlib.h>
00081 #include <string.h>
00082 #include <math.h>
00083 #include "MMX.h"
00084 #undef IWTRANSFORM_TIMER
00085 #ifdef IWTRANSFORM_TIMER
00086 #include "GOS.h"
00087 #endif
00088
00089 #include <assert.h>
00090 #include <string.h>
00091 #include <math.h>
00092
00093
00094 #ifdef HAVE_NAMESPACES
00095 namespace DJVU {
00096 # ifdef NOT_DEFINED // Just to fool emacs c++ mode
00097 }
00098 #endif
00099 #endif
00100
00101
00102 #define IWALLOCSIZE 4080
00103 #define IWCODEC_MAJOR 1
00104 #define IWCODEC_MINOR 2
00105 #define DECIBEL_PRUNE 5.0
00106
00107
00109
00111
00112
00113
00114
00115
00116
00117
00118
00119 static const int iw_quant[16] = {
00120 0x004000,
00121 0x008000, 0x008000, 0x010000,
00122 0x010000, 0x010000, 0x020000,
00123 0x020000, 0x020000, 0x040000,
00124 0x040000, 0x040000, 0x080000,
00125 0x040000, 0x040000, 0x080000
00126 };
00127
00128 static const float iw_norm[16] = {
00129 2.627989e+03F,
00130 1.832893e+02F, 1.832959e+02F, 5.114690e+01F,
00131 4.583344e+01F, 4.583462e+01F, 1.279225e+01F,
00132 1.149671e+01F, 1.149712e+01F, 3.218888e+00F,
00133 2.999281e+00F, 2.999476e+00F, 8.733161e-01F,
00134 1.074451e+00F, 1.074511e+00F, 4.289318e-01F
00135 };
00136
00137 static const int iw_border = 3;
00138 static const int iw_shift = 6;
00139 static const int iw_round = (1<<(iw_shift-1));
00140
00141 class IW44Image::Codec::Decode : public IW44Image::Codec
00142 {
00143 public:
00144
00145 Decode(IW44Image::Map &map) : Codec(map) {}
00146
00147 virtual int code_slice(ZPCodec &zp);
00148 };
00149
00151
00153
00154
00155
00156
00157
00158
00159
00160 #ifdef MMX
00161
00162 static const short w9[] = {9,9,9,9};
00163 static const short w1[] = {1,1,1,1};
00164 static const int d8[] = {8,8};
00165 static const int d16[] = {16,16};
00166
00167 static void
00168 mmx_bv_1 ( short* &q, short* e, int s, int s3 )
00169 {
00170 while (q<e && (((long)q)&0x7))
00171 {
00172 int a = (int)q[-s] + (int)q[s];
00173 int b = (int)q[-s3] + (int)q[s3];
00174 *q -= (((a<<3)+a-b+16)>>5);
00175 q ++;
00176 }
00177 while (q+3 < e)
00178 {
00179 MMXar( movq, q-s,mm0);
00180 MMXar( movq, q+s,mm2);
00181 MMXrr( movq, mm0,mm1);
00182 MMXrr( punpcklwd, mm2,mm0);
00183 MMXrr( punpckhwd, mm2,mm1);
00184 MMXar( pmaddwd, w9,mm0);
00185 MMXar( pmaddwd, w9,mm1);
00186 MMXar( movq, q-s3,mm2);
00187 MMXar( movq, q+s3,mm4);
00188 MMXrr( movq, mm2,mm3);
00189 MMXrr( punpcklwd, mm4,mm2);
00190 MMXrr( punpckhwd, mm4,mm3);
00191 MMXar( pmaddwd, w1,mm2);
00192 MMXar( pmaddwd, w1,mm3);
00193 MMXar( paddd, d16,mm0);
00194 MMXar( paddd, d16,mm1);
00195 MMXrr( psubd, mm2,mm0);
00196 MMXrr( psubd, mm3,mm1);
00197 MMXir( psrad, 5,mm0);
00198 MMXar( movq, q,mm7);
00199 MMXir( psrad, 5,mm1);
00200 MMXrr( packssdw, mm1,mm0);
00201 MMXrr( psubw, mm0,mm7);
00202 MMXra( movq, mm7,q);
00203 #if defined(_MSC_VER) && defined(_DEBUG)
00204 MMXemms;
00205 #endif
00206 q += 4;
00207 }
00208 }
00209
00210
00211 static void
00212 mmx_bv_2 ( short* &q, short* e, int s, int s3 )
00213 {
00214 while (q<e && (((long)q)&0x7))
00215 {
00216 int a = (int)q[-s] + (int)q[s];
00217 int b = (int)q[-s3] + (int)q[s3];
00218 *q += (((a<<3)+a-b+8)>>4);
00219 q ++;
00220 }
00221 while (q+3 < e)
00222 {
00223 MMXar( movq, q-s,mm0);
00224 MMXar( movq, q+s,mm2);
00225 MMXrr( movq, mm0,mm1);
00226 MMXrr( punpcklwd, mm2,mm0);
00227 MMXrr( punpckhwd, mm2,mm1);
00228 MMXar( pmaddwd, w9,mm0);
00229 MMXar( pmaddwd, w9,mm1);
00230 MMXar( movq, q-s3,mm2);
00231 MMXar( movq, q+s3,mm4);
00232 MMXrr( movq, mm2,mm3);
00233 MMXrr( punpcklwd, mm4,mm2);
00234 MMXrr( punpckhwd, mm4,mm3);
00235 MMXar( pmaddwd, w1,mm2);
00236 MMXar( pmaddwd, w1,mm3);
00237 MMXar( paddd, d8,mm0);
00238 MMXar( paddd, d8,mm1);
00239 MMXrr( psubd, mm2,mm0);
00240 MMXrr( psubd, mm3,mm1);
00241 MMXir( psrad, 4,mm0);
00242 MMXar( movq, q,mm7);
00243 MMXir( psrad, 4,mm1);
00244 MMXrr( packssdw, mm1,mm0);
00245 MMXrr( paddw, mm0,mm7);
00246 MMXra( movq, mm7,q);
00247 #if defined(_MSC_VER) && defined(_DEBUG)
00248 MMXemms;
00249 #endif
00250 q += 4;
00251 }
00252 }
00253 #endif
00254
00255 static void
00256 filter_bv(short *p, int w, int h, int rowsize, int scale)
00257 {
00258 int y = 0;
00259 int s = scale*rowsize;
00260 int s3 = s+s+s;
00261 h = ((h-1)/scale)+1;
00262 while (y-3 < h)
00263 {
00264
00265 {
00266 short *q = p;
00267 short *e = q+w;
00268 if (y>=3 && y+3<h)
00269 {
00270
00271 #ifdef MMX
00272 if (scale==1 && MMXControl::mmxflag>0)
00273 mmx_bv_1(q, e, s, s3);
00274 #endif
00275 while (q<e)
00276 {
00277 int a = (int)q[-s] + (int)q[s];
00278 int b = (int)q[-s3] + (int)q[s3];
00279 *q -= (((a<<3)+a-b+16)>>5);
00280 q += scale;
00281 }
00282 }
00283 else if (y<h)
00284 {
00285
00286 short *q1 = (y+1<h ? q+s : 0);
00287 short *q3 = (y+3<h ? q+s3 : 0);
00288 if (y>=3)
00289 {
00290 while (q<e)
00291 {
00292 int a = (int)q[-s] + (q1 ? (int)(*q1) : 0);
00293 int b = (int)q[-s3] + (q3 ? (int)(*q3) : 0);
00294 *q -= (((a<<3)+a-b+16)>>5);
00295 q += scale;
00296 if (q1) q1 += scale;
00297 if (q3) q3 += scale;
00298 }
00299 }
00300 else if (y>=1)
00301 {
00302 while (q<e)
00303 {
00304 int a = (int)q[-s] + (q1 ? (int)(*q1) : 0);
00305 int b = (q3 ? (int)(*q3) : 0);
00306 *q -= (((a<<3)+a-b+16)>>5);
00307 q += scale;
00308 if (q1) q1 += scale;
00309 if (q3) q3 += scale;
00310 }
00311 }
00312 else
00313 {
00314 while (q<e)
00315 {
00316 int a = (q1 ? (int)(*q1) : 0);
00317 int b = (q3 ? (int)(*q3) : 0);
00318 *q -= (((a<<3)+a-b+16)>>5);
00319 q += scale;
00320 if (q1) q1 += scale;
00321 if (q3) q3 += scale;
00322 }
00323 }
00324 }
00325 }
00326
00327 {
00328 short *q = p-s3;
00329 short *e = q+w;
00330 if (y>=6 && y<h)
00331 {
00332
00333 #ifdef MMX
00334 if (scale==1 && MMXControl::mmxflag>0)
00335 mmx_bv_2(q, e, s, s3);
00336 #endif
00337 while (q<e)
00338 {
00339 int a = (int)q[-s] + (int)q[s];
00340 int b = (int)q[-s3] + (int)q[s3];
00341 *q += (((a<<3)+a-b+8)>>4);
00342 q += scale;
00343 }
00344 }
00345 else if (y>=3)
00346 {
00347
00348 short *q1 = (y-2<h ? q+s : q-s);
00349 while (q<e)
00350 {
00351 int a = (int)q[-s] + (int)(*q1);
00352 *q += ((a+1)>>1);
00353 q += scale;
00354 q1 += scale;
00355 }
00356 }
00357 }
00358 y += 2;
00359 p += s+s;
00360 }
00361 }
00362
00363 static void
00364 filter_bh(short *p, int w, int h, int rowsize, int scale)
00365 {
00366 int y = 0;
00367 int s = scale;
00368 int s3 = s+s+s;
00369 rowsize *= scale;
00370 while (y<h)
00371 {
00372 short *q = p;
00373 short *e = p+w;
00374 int a0=0, a1=0, a2=0, a3=0;
00375 int b0=0, b1=0, b2=0, b3=0;
00376 if (q<e)
00377 {
00378
00379 if (q+s < e)
00380 a2 = q[s];
00381 if (q+s3 < e)
00382 a3 = q[s3];
00383 b2 = b3 = q[0] - ((((a1+a2)<<3)+(a1+a2)-a0-a3+16) >> 5);
00384 q[0] = b3;
00385 q += s+s;
00386 }
00387 if (q<e)
00388 {
00389
00390 a0 = a1;
00391 a1 = a2;
00392 a2 = a3;
00393 if (q+s3 < e)
00394 a3 = q[s3];
00395 b3 = q[0] - ((((a1+a2)<<3)+(a1+a2)-a0-a3+16) >> 5);
00396 q[0] = b3;
00397 q += s+s;
00398 }
00399 if (q<e)
00400 {
00401
00402 b1 = b2;
00403 b2 = b3;
00404 a0 = a1;
00405 a1 = a2;
00406 a2 = a3;
00407 if (q+s3 < e)
00408 a3 = q[s3];
00409 b3 = q[0] - ((((a1+a2)<<3)+(a1+a2)-a0-a3+16) >> 5);
00410 q[0] = b3;
00411 q[-s3] = q[-s3] + ((b1+b2+1)>>1);
00412 q += s+s;
00413 }
00414 while (q+s3 < e)
00415 {
00416
00417 a0=a1;
00418 a1=a2;
00419 a2=a3;
00420 a3=q[s3];
00421 b0=b1;
00422 b1=b2;
00423 b2=b3;
00424 b3 = q[0] - ((((a1+a2)<<3)+(a1+a2)-a0-a3+16) >> 5);
00425 q[0] = b3;
00426 q[-s3] = q[-s3] + ((((b1+b2)<<3)+(b1+b2)-b0-b3+8) >> 4);
00427 q += s+s;
00428 }
00429 while (q < e)
00430 {
00431
00432 a0=a1;
00433 a1=a2;
00434 a2=a3;
00435 a3=0;
00436 b0=b1;
00437 b1=b2;
00438 b2=b3;
00439 b3 = q[0] - ((((a1+a2)<<3)+(a1+a2)-a0-a3+16) >> 5);
00440 q[0] = b3;
00441 q[-s3] = q[-s3] + ((((b1+b2)<<3)+(b1+b2)-b0-b3+8) >> 4);
00442 q += s+s;
00443 }
00444 while (q-s3 < e)
00445 {
00446
00447 b0=b1;
00448 b1=b2;
00449 b2=b3;
00450 if (q-s3 >= p)
00451 q[-s3] = q[-s3] + ((b1+b2+1)>>1);
00452 q += s+s;
00453 }
00454 y += scale;
00455 p += rowsize;
00456 }
00457 }
00458
00459
00461
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 static int zigzagloc[1024] = {
00478 0, 16, 512, 528, 8, 24, 520, 536, 256, 272, 768, 784, 264, 280, 776, 792,
00479 4, 20, 516, 532, 12, 28, 524, 540, 260, 276, 772, 788, 268, 284, 780, 796,
00480 128, 144, 640, 656, 136, 152, 648, 664, 384, 400, 896, 912, 392, 408, 904, 920,
00481 132, 148, 644, 660, 140, 156, 652, 668, 388, 404, 900, 916, 396, 412, 908, 924,
00482 2, 18, 514, 530, 10, 26, 522, 538, 258, 274, 770, 786, 266, 282, 778, 794,
00483 6, 22, 518, 534, 14, 30, 526, 542, 262, 278, 774, 790, 270, 286, 782, 798,
00484 130, 146, 642, 658, 138, 154, 650, 666, 386, 402, 898, 914, 394, 410, 906, 922,
00485 134, 150, 646, 662, 142, 158, 654, 670, 390, 406, 902, 918, 398, 414, 910, 926,
00486 64, 80, 576, 592, 72, 88, 584, 600, 320, 336, 832, 848, 328, 344, 840, 856,
00487 68, 84, 580, 596, 76, 92, 588, 604, 324, 340, 836, 852, 332, 348, 844, 860,
00488 192, 208, 704, 720, 200, 216, 712, 728, 448, 464, 960, 976, 456, 472, 968, 984,
00489 196, 212, 708, 724, 204, 220, 716, 732, 452, 468, 964, 980, 460, 476, 972, 988,
00490 66, 82, 578, 594, 74, 90, 586, 602, 322, 338, 834, 850, 330, 346, 842, 858,
00491 70, 86, 582, 598, 78, 94, 590, 606, 326, 342, 838, 854, 334, 350, 846, 862,
00492 194, 210, 706, 722, 202, 218, 714, 730, 450, 466, 962, 978, 458, 474, 970, 986,
00493 198, 214, 710, 726, 206, 222, 718, 734, 454, 470, 966, 982, 462, 478, 974, 990,
00494 1, 17, 513, 529, 9, 25, 521, 537, 257, 273, 769, 785, 265, 281, 777, 793,
00495 5, 21, 517, 533, 13, 29, 525, 541, 261, 277, 773, 789, 269, 285, 781, 797,
00496 129, 145, 641, 657, 137, 153, 649, 665, 385, 401, 897, 913, 393, 409, 905, 921,
00497 133, 149, 645, 661, 141, 157, 653, 669, 389, 405, 901, 917, 397, 413, 909, 925,
00498 3, 19, 515, 531, 11, 27, 523, 539, 259, 275, 771, 787, 267, 283, 779, 795,
00499 7, 23, 519, 535, 15, 31, 527, 543, 263, 279, 775, 791, 271, 287, 783, 799,
00500 131, 147, 643, 659, 139, 155, 651, 667, 387, 403, 899, 915, 395, 411, 907, 923,
00501 135, 151, 647, 663, 143, 159, 655, 671, 391, 407, 903, 919, 399, 415, 911, 927,
00502 65, 81, 577, 593, 73, 89, 585, 601, 321, 337, 833, 849, 329, 345, 841, 857,
00503 69, 85, 581, 597, 77, 93, 589, 605, 325, 341, 837, 853, 333, 349, 845, 861,
00504 193, 209, 705, 721, 201, 217, 713, 729, 449, 465, 961, 977, 457, 473, 969, 985,
00505 197, 213, 709, 725, 205, 221, 717, 733, 453, 469, 965, 981, 461, 477, 973, 989,
00506 67, 83, 579, 595, 75, 91, 587, 603, 323, 339, 835, 851, 331, 347, 843, 859,
00507 71, 87, 583, 599, 79, 95, 591, 607, 327, 343, 839, 855, 335, 351, 847, 863,
00508 195, 211, 707, 723, 203, 219, 715, 731, 451, 467, 963, 979, 459, 475, 971, 987,
00509 199, 215, 711, 727, 207, 223, 719, 735, 455, 471, 967, 983, 463, 479, 975, 991,
00510 32, 48, 544, 560, 40, 56, 552, 568, 288, 304, 800, 816, 296, 312, 808, 824,
00511 36, 52, 548, 564, 44, 60, 556, 572, 292, 308, 804, 820, 300, 316, 812, 828,
00512 160, 176, 672, 688, 168, 184, 680, 696, 416, 432, 928, 944, 424, 440, 936, 952,
00513 164, 180, 676, 692, 172, 188, 684, 700, 420, 436, 932, 948, 428, 444, 940, 956,
00514 34, 50, 546, 562, 42, 58, 554, 570, 290, 306, 802, 818, 298, 314, 810, 826,
00515 38, 54, 550, 566, 46, 62, 558, 574, 294, 310, 806, 822, 302, 318, 814, 830,
00516 162, 178, 674, 690, 170, 186, 682, 698, 418, 434, 930, 946, 426, 442, 938, 954,
00517 166, 182, 678, 694, 174, 190, 686, 702, 422, 438, 934, 950, 430, 446, 942, 958,
00518 96, 112, 608, 624, 104, 120, 616, 632, 352, 368, 864, 880, 360, 376, 872, 888,
00519 100, 116, 612, 628, 108, 124, 620, 636, 356, 372, 868, 884, 364, 380, 876, 892,
00520 224, 240, 736, 752, 232, 248, 744, 760, 480, 496, 992,1008, 488, 504,1000,1016,
00521 228, 244, 740, 756, 236, 252, 748, 764, 484, 500, 996,1012, 492, 508,1004,1020,
00522 98, 114, 610, 626, 106, 122, 618, 634, 354, 370, 866, 882, 362, 378, 874, 890,
00523 102, 118, 614, 630, 110, 126, 622, 638, 358, 374, 870, 886, 366, 382, 878, 894,
00524 226, 242, 738, 754, 234, 250, 746, 762, 482, 498, 994,1010, 490, 506,1002,1018,
00525 230, 246, 742, 758, 238, 254, 750, 766, 486, 502, 998,1014, 494, 510,1006,1022,
00526 33, 49, 545, 561, 41, 57, 553, 569, 289, 305, 801, 817, 297, 313, 809, 825,
00527 37, 53, 549, 565, 45, 61, 557, 573, 293, 309, 805, 821, 301, 317, 813, 829,
00528 161, 177, 673, 689, 169, 185, 681, 697, 417, 433, 929, 945, 425, 441, 937, 953,
00529 165, 181, 677, 693, 173, 189, 685, 701, 421, 437, 933, 949, 429, 445, 941, 957,
00530 35, 51, 547, 563, 43, 59, 555, 571, 291, 307, 803, 819, 299, 315, 811, 827,
00531 39, 55, 551, 567, 47, 63, 559, 575, 295, 311, 807, 823, 303, 319, 815, 831,
00532 163, 179, 675, 691, 171, 187, 683, 699, 419, 435, 931, 947, 427, 443, 939, 955,
00533 167, 183, 679, 695, 175, 191, 687, 703, 423, 439, 935, 951, 431, 447, 943, 959,
00534 97, 113, 609, 625, 105, 121, 617, 633, 353, 369, 865, 881, 361, 377, 873, 889,
00535 101, 117, 613, 629, 109, 125, 621, 637, 357, 373, 869, 885, 365, 381, 877, 893,
00536 225, 241, 737, 753, 233, 249, 745, 761, 481, 497, 993,1009, 489, 505,1001,1017,
00537 229, 245, 741, 757, 237, 253, 749, 765, 485, 501, 997,1013, 493, 509,1005,1021,
00538 99, 115, 611, 627, 107, 123, 619, 635, 355, 371, 867, 883, 363, 379, 875, 891,
00539 103, 119, 615, 631, 111, 127, 623, 639, 359, 375, 871, 887, 367, 383, 879, 895,
00540 227, 243, 739, 755, 235, 251, 747, 763, 483, 499, 995,1011, 491, 507,1003,1019,
00541 231, 247, 743, 759, 239, 255, 751, 767, 487, 503, 999,1015, 495, 511,1007,1023,
00542 };
00543
00544
00545
00546
00547 struct IW44Image::Alloc
00548 {
00549 Alloc *next;
00550 short data[IWALLOCSIZE];
00551 };
00552
00553
00554
00555
00556
00557 IW44Image::Block::Block(void)
00558 {
00559 pdata[0] = pdata[1] = pdata[2] = pdata[3] = 0;
00560 }
00561
00562 void
00563 IW44Image::Block::zero(int n)
00564 {
00565 if (pdata[n>>4])
00566 pdata[n>>4][n&15] = 0;
00567 }
00568
00569 void
00570 IW44Image::Block::read_liftblock(const short *coeff, IW44Image::Map *map)
00571 {
00572 int n=0;
00573 for (int n1=0; n1<64; n1++)
00574 {
00575 short *d = data(n1,map);
00576 for (int n2=0; n2<16; n2++,n++)
00577 d[n2] = coeff[zigzagloc[n]];
00578 }
00579 }
00580
00581 void
00582 IW44Image::Block::write_liftblock(short *coeff, int bmin, int bmax) const
00583 {
00584 int n = bmin<<4;
00585 memset(coeff, 0, 1024*sizeof(short));
00586 for (int n1=bmin; n1<bmax; n1++)
00587 {
00588 const short *d = data(n1);
00589 if (d == 0)
00590 n += 16;
00591 else
00592 for (int n2=0; n2<16; n2++,n++)
00593 coeff[zigzagloc[n]] = d[n2];
00594 }
00595 }
00596
00597
00598
00599
00600
00601 IW44Image::Map::Map(int w, int h)
00602 : blocks(0), iw(w), ih(h), chain(0)
00603 {
00604 bw = (w+0x20-1) & ~0x1f;
00605 bh = (h+0x20-1) & ~0x1f;
00606 nb = (bw * bh) / (32 * 32);
00607 blocks = new IW44Image::Block[nb];
00608 top = IWALLOCSIZE;
00609 }
00610
00611 IW44Image::Map::~Map()
00612 {
00613 while (chain)
00614 {
00615 IW44Image::Alloc *next = chain->next;
00616 delete chain;
00617 chain = next;
00618 }
00619 delete [] blocks;
00620 }
00621
00622 short *
00623 IW44Image::Map::alloc(int n)
00624 {
00625 if (top+n > IWALLOCSIZE)
00626 {
00627 IW44Image::Alloc *n = new IW44Image::Alloc;
00628 n->next = chain;
00629 chain = n;
00630 top = 0;
00631 }
00632 short *ans = chain->data + top;
00633 top += n;
00634 memset((void*)ans, 0, sizeof(short)*n);
00635 return ans;
00636 }
00637
00638 short **
00639 IW44Image::Map::allocp(int n)
00640 {
00641
00642 short *p = alloc( (n+1) * sizeof(short*) / sizeof(short) );
00643
00644 while ( ((long)p) & (sizeof(short*)-1) )
00645 p += 1;
00646
00647 return (short**)p;
00648 }
00649
00650 int
00651 IW44Image::Map::get_bucket_count(void) const
00652 {
00653 int buckets = 0;
00654 for (int blockno=0; blockno<nb; blockno++)
00655 for (int buckno=0; buckno<64; buckno++)
00656 if (blocks[blockno].data(buckno))
00657 buckets += 1;
00658 return buckets;
00659 }
00660
00661 unsigned int
00662 IW44Image::Map::get_memory_usage(void) const
00663 {
00664 unsigned int usage = sizeof(Map);
00665 usage += sizeof(IW44Image::Block) * nb;
00666 for (IW44Image::Alloc *n = chain; n; n=n->next)
00667 usage += sizeof(IW44Image::Alloc);
00668 return usage;
00669 }
00670
00671
00672
00673
00674 void
00675 IW44Image::Map::image(signed char *img8, int rowsize, int pixsep, int fast)
00676 {
00677
00678 short *data16;
00679 GPBuffer<short> gdata16(data16,bw*bh);
00680
00681 int i;
00682 short *p = data16;
00683 const IW44Image::Block *block = blocks;
00684 for (i=0; i<bh; i+=32)
00685 {
00686 for (int j=0; j<bw; j+=32)
00687 {
00688 short liftblock[1024];
00689
00690 block->write_liftblock(liftblock);
00691 block++;
00692
00693 short *pp = p + j;
00694 short *pl = liftblock;
00695 for (int ii=0; ii<32; ii++, pp+=bw,pl+=32)
00696 memcpy((void*)pp, (void*)pl, 32*sizeof(short));
00697 }
00698
00699 p += 32*bw;
00700 }
00701
00702 if (fast)
00703 {
00704 IW44Image::Transform::Decode::backward(data16, iw, ih, bw, 32, 2);
00705 p = data16;
00706 for (i=0; i<bh; i+=2,p+=bw)
00707 for (int jj=0; jj<bw; jj+=2,p+=2)
00708 p[bw] = p[bw+1] = p[1] = p[0];
00709 }
00710 else
00711 {
00712 IW44Image::Transform::Decode::backward(data16, iw, ih, bw, 32, 1);
00713 }
00714
00715 p = data16;
00716 signed char *row = img8;
00717 for (i=0; i<ih; i++)
00718 {
00719 signed char *pix = row;
00720 for (int j=0; j<iw; j+=1,pix+=pixsep)
00721 {
00722 int x = (p[j] + iw_round) >> iw_shift;
00723 if (x < -128)
00724 x = -128;
00725 else if (x > 127)
00726 x = 127;
00727 *pix = x;
00728 }
00729 row += rowsize;
00730 p += bw;
00731 }
00732 }
00733
00734 void
00735 IW44Image::Map::image(int subsample, const GRect &rect,
00736 signed char *img8, int rowsize, int pixsep, int fast)
00737 {
00738 int i;
00739
00740 int nlevel = 0;
00741 while (nlevel<5 && (32>>nlevel)>subsample)
00742 nlevel += 1;
00743 int boxsize = 1<<nlevel;
00744
00745 if (subsample!=(32>>nlevel))
00746 G_THROW( ERR_MSG("IW44Image.sample_factor") );
00747 if (rect.isempty())
00748 G_THROW( ERR_MSG("IW44Image.empty_rect") );
00749 GRect irect(0,0,(iw+subsample-1)/subsample,(ih+subsample-1)/subsample);
00750 if (rect.xmin<0 || rect.ymin<0 || rect.xmax>irect.xmax || rect.ymax>irect.ymax)
00751 G_THROW( ERR_MSG("IW44Image.bad_rect") );
00752
00753
00754
00755 GRect needed[8];
00756 GRect recomp[8];
00757 int r = 1;
00758 needed[nlevel] = rect;
00759 recomp[nlevel] = rect;
00760 for (i=nlevel-1; i>=0; i--)
00761 {
00762 needed[i] = recomp[i+1];
00763 needed[i].inflate(iw_border*r, iw_border*r);
00764 needed[i].intersect(needed[i], irect);
00765 r += r;
00766 recomp[i].xmin = (needed[i].xmin + r-1) & ~(r-1);
00767 recomp[i].xmax = (needed[i].xmax) & ~(r-1);
00768 recomp[i].ymin = (needed[i].ymin + r-1) & ~(r-1);
00769 recomp[i].ymax = (needed[i].ymax) & ~(r-1);
00770 }
00771
00772
00773 GRect work;
00774 work.xmin = (needed[0].xmin) & ~(boxsize-1);
00775 work.ymin = (needed[0].ymin) & ~(boxsize-1);
00776 work.xmax = ((needed[0].xmax-1) & ~(boxsize-1) ) + boxsize;
00777 work.ymax = ((needed[0].ymax-1) & ~(boxsize-1) ) + boxsize;
00778
00779 int dataw = work.xmax - work.xmin;
00780 int datah = work.ymax - work.ymin;
00781 short *data;
00782 GPBuffer<short> gdata(data,dataw*datah);
00783
00784
00785 short *ldata = data;
00786 int blkw = (bw>>5);
00787 const IW44Image::Block *lblock = blocks + (work.ymin>>nlevel)*blkw + (work.xmin>>nlevel);
00788 for (int by=work.ymin; by<work.ymax; by+=boxsize)
00789 {
00790
00791 const IW44Image::Block *block = lblock;
00792 short *rdata = ldata;
00793 for (int bx=work.xmin; bx<work.xmax; bx+=boxsize)
00794 {
00795
00796 int mlevel = nlevel;
00797 if (nlevel>2)
00798 if (bx+31<needed[2].xmin || bx>needed[2].xmax ||
00799 by+31<needed[2].ymin || by>needed[2].ymax )
00800 mlevel = 2;
00801 int bmax = ((1<<(mlevel+mlevel))+15)>>4;
00802 int ppinc = (1<<(nlevel-mlevel));
00803 int ppmod1 = (dataw<<(nlevel-mlevel));
00804 int ttmod0 = (32 >> mlevel);
00805 int ttmod1 = (ttmod0 << 5);
00806
00807 short liftblock[1024];
00808 block->write_liftblock(liftblock, 0, bmax );
00809
00810 short *tt = liftblock;
00811 short *pp = rdata;
00812 for (int ii=0; ii<boxsize; ii+=ppinc,pp+=ppmod1,tt+=ttmod1-32)
00813 for (int jj=0; jj<boxsize; jj+=ppinc,tt+=ttmod0)
00814 pp[jj] = *tt;
00815
00816 rdata += boxsize;
00817 block += 1;
00818 }
00819
00820 ldata += dataw << nlevel;
00821 lblock += blkw;
00822 }
00823
00824 r = boxsize;
00825 for (i=0; i<nlevel; i++)
00826 {
00827 GRect comp = needed[i];
00828 comp.xmin = comp.xmin & ~(r-1);
00829 comp.ymin = comp.ymin & ~(r-1);
00830 comp.translate(-work.xmin, -work.ymin);
00831
00832 if (fast && i>=4)
00833 {
00834 short *pp = data + comp.ymin*dataw;
00835 for (int ii=comp.ymin; ii<comp.ymax; ii+=2, pp+=dataw+dataw)
00836 for (int jj=comp.xmin; jj<comp.xmax; jj+=2)
00837 pp[jj+dataw] = pp[jj+dataw+1] = pp[jj+1] = pp[jj];
00838 break;
00839 }
00840 else
00841 {
00842 short *pp = data + comp.ymin*dataw + comp.xmin;
00843 IW44Image::Transform::Decode::backward(pp, comp.width(), comp.height(), dataw, r, r>>1);
00844 }
00845 r = r>>1;
00846 }
00847
00848 GRect nrect = rect;
00849 nrect.translate(-work.xmin, -work.ymin);
00850 short *p = data + nrect.ymin*dataw;
00851 signed char *row = img8;
00852 for (i=nrect.ymin; i<nrect.ymax; i++)
00853 {
00854 int j;
00855 signed char *pix = row;
00856 for (j=nrect.xmin; j<nrect.xmax; j+=1,pix+=pixsep)
00857 {
00858 int x = (p[j] + iw_round) >> iw_shift;
00859 if (x < -128)
00860 x = -128;
00861 else if (x > 127)
00862 x = 127;
00863 *pix = x;
00864 }
00865 row += rowsize;
00866 p += dataw;
00867 }
00868 }
00869
00870
00871
00872
00874
00875
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886 static const struct { int start; int size; }
00887 bandbuckets[] =
00888 {
00889
00890 { 0, 1 },
00891 { 1, 1 }, { 2, 1 }, { 3, 1 },
00892 { 4, 4 }, { 8, 4 }, { 12,4 },
00893 { 16,16 }, { 32,16 }, { 48,16 },
00894 };
00895
00896
00897
00898
00899 IW44Image::Codec::Codec(IW44Image::Map &xmap)
00900 : map(xmap),
00901 curband(0),
00902 curbit(1)
00903 {
00904
00905 int j;
00906 int i = 0;
00907 const int *q = iw_quant;
00908
00909 for (j=0; i<4; j++)
00910 quant_lo[i++] = *q++;
00911 for (j=0; j<4; j++)
00912 quant_lo[i++] = *q;
00913 q += 1;
00914 for (j=0; j<4; j++)
00915 quant_lo[i++] = *q;
00916 q += 1;
00917 for (j=0; j<4; j++)
00918 quant_lo[i++] = *q;
00919 q += 1;
00920
00921 quant_hi[0] = 0;
00922 for (j=1; j<10; j++)
00923 quant_hi[j] = *q++;
00924
00925 memset((void*)ctxStart, 0, sizeof(ctxStart));
00926 memset((void*)ctxBucket, 0, sizeof(ctxBucket));
00927 ctxMant = 0;
00928 ctxRoot = 0;
00929 }
00930
00931
00932
00933
00934 IW44Image::Codec::~Codec() {}
00935
00936
00937
00938
00939
00940 int
00941 IW44Image::Codec::is_null_slice(int bit, int band)
00942 {
00943 if (band == 0)
00944 {
00945 int is_null = 1;
00946 for (int i=0; i<16; i++)
00947 {
00948 int threshold = quant_lo[i];
00949 coeffstate[i] = ZERO;
00950 if (threshold>0 && threshold<0x8000)
00951 {
00952 coeffstate[i] = UNK;
00953 is_null = 0;
00954 }
00955 }
00956 return is_null;
00957 }
00958 else
00959 {
00960 int threshold = quant_hi[band];
00961 return (! (threshold>0 && threshold<0x8000));
00962 }
00963 }
00964
00965
00966
00967
00968
00969 int
00970 IW44Image::Codec::Decode::code_slice(ZPCodec &zp)
00971 {
00972
00973 if (curbit < 0)
00974 return 0;
00975
00976 if (! is_null_slice(curbit, curband))
00977 {
00978 for (int blockno=0; blockno<map.nb; blockno++)
00979 {
00980 int fbucket = bandbuckets[curband].start;
00981 int nbucket = bandbuckets[curband].size;
00982 decode_buckets(zp, curbit, curband,
00983 map.blocks[blockno],
00984 fbucket, nbucket);
00985 }
00986 }
00987 return finish_code_slice(zp);
00988 }
00989
00990
00991
00992
00993 int
00994 IW44Image::Codec::finish_code_slice(ZPCodec &zp)
00995 {
00996
00997 quant_hi[curband] = quant_hi[curband] >> 1;
00998 if (curband == 0)
00999 for (int i=0; i<16; i++)
01000 quant_lo[i] = quant_lo[i] >> 1;
01001
01002 if (++curband >= (int)(sizeof(bandbuckets)/sizeof(bandbuckets[0])))
01003 {
01004 curband = 0;
01005 curbit += 1;
01006 if (quant_hi[(sizeof(bandbuckets)/sizeof(bandbuckets[0]))-1] == 0)
01007 {
01008
01009 curbit = -1;
01010 return 0;
01011 }
01012 }
01013 return 1;
01014 }
01015
01016
01017
01018
01019 int
01020 IW44Image::Codec::decode_prepare(int fbucket, int nbucket, IW44Image::Block &blk)
01021 {
01022 int bbstate = 0;
01023 char *cstate = coeffstate;
01024 if (fbucket)
01025 {
01026
01027 for (int buckno=0; buckno<nbucket; buckno++, cstate+=16)
01028 {
01029 int bstatetmp = 0;
01030 const short *pcoeff = blk.data(fbucket+buckno);
01031 if (! pcoeff)
01032 {
01033
01034 bstatetmp = UNK;
01035 }
01036 else
01037 {
01038 for (int i=0; i<16; i++)
01039 {
01040 int cstatetmp = UNK;
01041 if (pcoeff[i])
01042 cstatetmp = ACTIVE;
01043 cstate[i] = cstatetmp;
01044 bstatetmp |= cstatetmp;
01045 }
01046 }
01047 bucketstate[buckno] = bstatetmp;
01048 bbstate |= bstatetmp;
01049 }
01050 }
01051 else
01052 {
01053
01054 const short *pcoeff = blk.data(0);
01055 if (! pcoeff)
01056 {
01057
01058 bbstate = UNK;
01059 }
01060 else
01061 {
01062 for (int i=0; i<16; i++)
01063 {
01064 int cstatetmp = cstate[i];
01065 if (cstatetmp != ZERO)
01066 {
01067 cstatetmp = UNK;
01068 if (pcoeff[i])
01069 cstatetmp = ACTIVE;
01070 }
01071 cstate[i] = cstatetmp;
01072 bbstate |= cstatetmp;
01073 }
01074 }
01075 bucketstate[0] = bbstate;
01076 }
01077 return bbstate;
01078 }
01079
01080
01081
01082
01083
01084 void
01085 IW44Image::Codec::decode_buckets(ZPCodec &zp, int bit, int band,
01086 IW44Image::Block &blk,
01087 int fbucket, int nbucket)
01088 {
01089
01090 int bbstate = decode_prepare(fbucket, nbucket, blk);
01091
01092 if ((nbucket<16) || (bbstate&ACTIVE))
01093 {
01094 bbstate |= NEW;
01095 }
01096 else if (bbstate & UNK)
01097 {
01098 if (zp.decoder(ctxRoot))
01099 bbstate |= NEW;
01100 #ifdef TRACE
01101 DjVuPrintMessage("bbstate[bit=%d,band=%d] = %d\n", bit, band, bbstate);
01102 #endif
01103 }
01104
01105
01106 if (bbstate & NEW)
01107 for (int buckno=0; buckno<nbucket; buckno++)
01108 {
01109
01110 if (bucketstate[buckno] & UNK)
01111 {
01112
01113 int ctx = 0;
01114 #ifndef NOCTX_BUCKET_UPPER
01115 if (band>0)
01116 {
01117 int k = (fbucket+buckno)<<2;
01118 const short *b = blk.data(k>>4);
01119 if (b)
01120 {
01121 k = k & 0xf;
01122 if (b[k])
01123 ctx += 1;
01124 if (b[k+1])
01125 ctx += 1;
01126 if (b[k+2])
01127 ctx += 1;
01128 if (ctx<3 && b[k+3])
01129 ctx += 1;
01130 }
01131 }
01132 #endif // NOCTX_BUCKET_UPPER
01133 #ifndef NOCTX_BUCKET_ACTIVE
01134 if (bbstate & ACTIVE)
01135 ctx |= 4;
01136 #endif
01137
01138 if (zp.decoder( ctxBucket[band][ctx] ))
01139 bucketstate[buckno] |= NEW;
01140 #ifdef TRACE
01141 DjVuPrintMessage(" bucketstate[bit=%d,band=%d,buck=%d] = %d\n",
01142 bit, band, buckno, bucketstate[buckno]);
01143 #endif
01144 }
01145 }
01146
01147
01148 if (bbstate & NEW)
01149 {
01150 int thres = quant_hi[band];
01151 char *cstate = coeffstate;
01152 for (int buckno=0; buckno<nbucket; buckno++, cstate+=16)
01153 if (bucketstate[buckno] & NEW)
01154 {
01155 int i;
01156 short *pcoeff = (short*)blk.data(fbucket+buckno);
01157 if (!pcoeff)
01158 {
01159 pcoeff = blk.data(fbucket+buckno, &map);
01160
01161 if (fbucket == 0)
01162 {
01163 for (i=0; i<16; i++)
01164 if (cstate[i] != ZERO)
01165 cstate[i] = UNK;
01166 }
01167 else
01168 {
01169 for (i=0; i<16; i++)
01170 cstate[i] = UNK;
01171 }
01172 }
01173 #ifndef NOCTX_EXPECT
01174 int gotcha = 0;
01175 const int maxgotcha = 7;
01176 for (i=0; i<16; i++)
01177 if (cstate[i] & UNK)
01178 gotcha += 1;
01179 #endif
01180 for (i=0; i<16; i++)
01181 {
01182 if (cstate[i] & UNK)
01183 {
01184
01185 if (band == 0)
01186 thres = quant_lo[i];
01187
01188 int ctx = 0;
01189 #ifndef NOCTX_EXPECT
01190 if (gotcha>=maxgotcha)
01191 ctx = maxgotcha;
01192 else
01193 ctx = gotcha;
01194 #endif
01195 #ifndef NOCTX_ACTIVE
01196 if (bucketstate[buckno] & ACTIVE)
01197 ctx |= 8;
01198 #endif
01199
01200 if (zp.decoder( ctxStart[ctx] ))
01201 {
01202 cstate[i] |= NEW;
01203 int halfthres = thres>>1;
01204 int coeff = thres+halfthres-(halfthres>>2);
01205 if (zp.IWdecoder())
01206 pcoeff[i] = -coeff;
01207 else
01208 pcoeff[i] = coeff;
01209 }
01210 #ifndef NOCTX_EXPECT
01211 if (cstate[i] & NEW)
01212 gotcha = 0;
01213 else if (gotcha > 0)
01214 gotcha -= 1;
01215 #endif
01216 #ifdef TRACE
01217 DjVuPrintMessage(" coeffstate[bit=%d,band=%d,buck=%d,c=%d] = %d\n",
01218 bit, band, buckno, i, cstate[i]);
01219 #endif
01220 }
01221 }
01222 }
01223 }
01224
01225
01226 if (bbstate & ACTIVE)
01227 {
01228 int thres = quant_hi[band];
01229 char *cstate = coeffstate;
01230 for (int buckno=0; buckno<nbucket; buckno++, cstate+=16)
01231 if (bucketstate[buckno] & ACTIVE)
01232 {
01233 short *pcoeff = (short*)blk.data(fbucket+buckno);
01234 for (int i=0; i<16; i++)
01235 if (cstate[i] & ACTIVE)
01236 {
01237 int coeff = pcoeff[i];
01238 if (coeff < 0)
01239 coeff = -coeff;
01240
01241 if (band == 0)
01242 thres = quant_lo[i];
01243
01244 if (coeff <= 3*thres)
01245 {
01246
01247 coeff = coeff + (thres>>2);
01248 if (zp.decoder(ctxMant))
01249 coeff = coeff + (thres>>1);
01250 else
01251 coeff = coeff - thres + (thres>>1);
01252 }
01253 else
01254 {
01255 if (zp.IWdecoder())
01256 coeff = coeff + (thres>>1);
01257 else
01258 coeff = coeff - thres + (thres>>1);
01259 }
01260
01261 if (pcoeff[i] > 0)
01262 pcoeff[i] = coeff;
01263 else
01264 pcoeff[i] = -coeff;
01265 }
01266 }
01267 }
01268 }
01269
01270
01272
01274
01275
01276 #ifdef min
01277 #undef min
01278 #endif
01279 static inline int
01280 min(const int x, const int y)
01281 {
01282 return (x <= y) ? x : y;
01283 }
01284
01285 #ifdef max
01286 #undef max
01287 #endif
01288 static inline int
01289 max(const int x, const int y)
01290 {
01291 return (y <= x) ? x : y;
01292 }
01293
01294
01295 void
01296 IW44Image::PrimaryHeader::decode(GP<ByteStream> gbs)
01297 {
01298 serial = gbs->read8();
01299 slices = gbs->read8();
01300 }
01301
01302 void
01303 IW44Image::SecondaryHeader::decode(GP<ByteStream> gbs)
01304 {
01305 major = gbs->read8();
01306 minor = gbs->read8();
01307 }
01308
01309 void
01310 IW44Image::TertiaryHeader::decode(GP<ByteStream> gbs, int major, int minor)
01311 {
01312 xhi = gbs->read8();
01313 xlo = gbs->read8();
01314 yhi = gbs->read8();
01315 ylo = gbs->read8();
01316 crcbdelay = 0;
01317 if (major== 1 && minor>=2)
01318 crcbdelay = gbs->read8();
01319 }
01320
01321
01322
01324
01326
01327 IW44Image::IW44Image(void)
01328 : db_frac(1.0),
01329 ymap(0), cbmap(0), crmap(0),
01330 cslice(0), cserial(0), cbytes(0)
01331 {}
01332
01333 IW44Image::~IW44Image()
01334 {
01335 delete ymap;
01336 delete cbmap;
01337 delete crmap;
01338 }
01339
01340 GP<IW44Image>
01341 IW44Image::create_decode(const ImageType itype)
01342 {
01343 switch(itype)
01344 {
01345 case COLOR:
01346 return new IWPixmap();
01347 case GRAY:
01348 return new IWBitmap();
01349 default:
01350 return 0;
01351 }
01352 }
01353
01354 int
01355 IW44Image::encode_chunk(GP<ByteStream>, const IWEncoderParms &)
01356 {
01357 G_THROW( ERR_MSG("IW44Image.codec_open2") );
01358 return 0;
01359 }
01360
01361 void
01362 IW44Image::encode_iff(IFFByteStream &, int nchunks, const IWEncoderParms *)
01363 {
01364 G_THROW( ERR_MSG("IW44Image.codec_open2") );
01365 }
01366
01367
01368 void
01369 IWBitmap::close_codec(void)
01370 {
01371 delete ycodec;
01372 ycodec = 0;
01373 cslice = cbytes = cserial = 0;
01374 }
01375
01376 void
01377 IWPixmap::close_codec(void)
01378 {
01379 delete ycodec;
01380 delete cbcodec;
01381 delete crcodec;
01382 ycodec = crcodec = cbcodec = 0;
01383 cslice = cbytes = cserial = 0;
01384 }
01385
01386 int
01387 IW44Image::get_width(void) const
01388 {
01389 return (ymap)?(ymap->iw):0;
01390 }
01391
01392 int
01393 IW44Image::get_height(void) const
01394 {
01395 return (ymap)?(ymap->ih):0;
01396 }
01397
01398
01400
01402
01403 IWBitmap::IWBitmap(void )
01404 : IW44Image(), ycodec(0)
01405 {}
01406
01407 IWBitmap::~IWBitmap()
01408 {
01409 close_codec();
01410 }
01411
01412 int
01413 IWBitmap::get_percent_memory(void) const
01414 {
01415 int buckets = 0;
01416 int maximum = 0;
01417 if (ymap)
01418 {
01419 buckets += ymap->get_bucket_count();
01420 maximum += 64 * ymap->nb;
01421 }
01422 return 100*buckets/ (maximum ? maximum : 1);
01423 }
01424
01425 unsigned int
01426 IWBitmap::get_memory_usage(void) const
01427 {
01428 unsigned int usage = sizeof(GBitmap);
01429 if (ymap)
01430 usage += ymap->get_memory_usage();
01431 return usage;
01432 }
01433
01434
01435 GP<GBitmap>
01436 IWBitmap::get_bitmap(void)
01437 {
01438
01439 if (ymap == 0)
01440 return 0;
01441
01442 int w = ymap->iw;
01443 int h = ymap->ih;
01444 GP<GBitmap> pbm = GBitmap::create(h, w);
01445 ymap->image((signed char*)(*pbm)[0],pbm->rowsize());
01446
01447 for (int i=0; i<h; i++)
01448 {
01449 unsigned char *urow = (*pbm)[i];
01450 signed char *srow = (signed char*)urow;
01451 for (int j=0; j<w; j++)
01452 urow[j] = (int)(srow[j]) + 128;
01453 }
01454 pbm->set_grays(256);
01455 return pbm;
01456 }
01457
01458
01459 GP<GBitmap>
01460 IWBitmap::get_bitmap(int subsample, const GRect &rect)
01461 {
01462 if (ymap == 0)
01463 return 0;
01464
01465 int w = rect.width();
01466 int h = rect.height();
01467 GP<GBitmap> pbm = GBitmap::create(h,w);
01468 ymap->image(subsample, rect, (signed char*)(*pbm)[0],pbm->rowsize());
01469
01470 for (int i=0; i<h; i++)
01471 {
01472 unsigned char *urow = (*pbm)[i];
01473 signed char *srow = (signed char*)urow;
01474 for (int j=0; j<w; j++)
01475 urow[j] = (int)(srow[j]) + 128;
01476 }
01477 pbm->set_grays(256);
01478 return pbm;
01479 }
01480
01481
01482 int
01483 IWBitmap::decode_chunk(GP<ByteStream> gbs)
01484 {
01485
01486 if (! ycodec)
01487 {
01488 cslice = cserial = 0;
01489 delete ymap;
01490 ymap = 0;
01491 }
01492
01493 struct IW44Image::PrimaryHeader primary;
01494 primary.decode(gbs);
01495 if (primary.serial != cserial)
01496 G_THROW( ERR_MSG("IW44Image.wrong_serial") );
01497 int nslices = cslice + primary.slices;
01498
01499 if (cserial == 0)
01500 {
01501 struct IW44Image::SecondaryHeader secondary;
01502 secondary.decode(gbs);
01503 if ((secondary.major & 0x7f) != IWCODEC_MAJOR)
01504 G_THROW( ERR_MSG("IW44Image.incompat_codec") );
01505 if (secondary.minor > IWCODEC_MINOR)
01506 G_THROW( ERR_MSG("IW44Image.recent_codec") );
01507
01508 struct IW44Image::TertiaryHeader tertiary;
01509 tertiary.decode(gbs, secondary.major & 0x7f, secondary.minor);
01510 if (! (secondary.major & 0x80))
01511 G_THROW( ERR_MSG("IW44Image.has_color") );
01512
01513 int w = (tertiary.xhi << 8) | tertiary.xlo;
01514 int h = (tertiary.yhi << 8) | tertiary.ylo;
01515 assert(! ymap);
01516 ymap = new Map(w, h);
01517 assert(! ycodec);
01518 ycodec = new Codec::Decode(*ymap);
01519 }
01520
01521 assert(ymap);
01522 assert(ycodec);
01523 GP<ZPCodec> gzp=ZPCodec::create(gbs, false, true);
01524 ZPCodec &zp=*gzp;
01525 int flag = 1;
01526 while (flag && cslice<nslices)
01527 {
01528 flag = ycodec->code_slice(zp);
01529 cslice++;
01530 }
01531
01532 cserial += 1;
01533 return nslices;
01534 }
01535
01536 void
01537 IWBitmap::parm_dbfrac(float frac)
01538 {
01539 if (frac>0 && frac<=1)
01540 db_frac = frac;
01541 else
01542 G_THROW( ERR_MSG("IW44Image.param_range") );
01543 }
01544
01545
01546 int
01547 IWBitmap::get_serial(void)
01548 {
01549 return cserial;
01550 }
01551
01552 void
01553 IWBitmap::decode_iff(IFFByteStream &iff, int maxchunks)
01554 {
01555 if (ycodec)
01556 G_THROW( ERR_MSG("IW44Image.left_open2") );
01557 GUTF8String chkid;
01558 iff.get_chunk(chkid);
01559 if (chkid != "FORM:BM44")
01560 G_THROW( ERR_MSG("IW44Image.corrupt_BM44") );
01561 while (--maxchunks>=0 && iff.get_chunk(chkid))
01562 {
01563 if (chkid == "BM44")
01564 decode_chunk(iff.get_bytestream());
01565 iff.close_chunk();
01566 }
01567 iff.close_chunk();
01568 close_codec();
01569 }
01570
01571
01572
01573
01575
01577
01578
01579 IWEncoderParms::IWEncoderParms(void)
01580 {
01581
01582 memset((void*)this, 0, sizeof(IWEncoderParms));
01583 }
01584
01585
01586
01587
01588
01590
01592
01593
01594 IWPixmap::IWPixmap(void)
01595 : IW44Image(), crcb_delay(10), crcb_half(0), ycodec(0), cbcodec(0), crcodec(0)
01596 {}
01597
01598 IWPixmap::~IWPixmap()
01599 {
01600 close_codec();
01601 }
01602
01603 int
01604 IWPixmap::get_percent_memory(void) const
01605 {
01606 int buckets = 0;
01607 int maximum = 0;
01608 if (ymap)
01609 {
01610 buckets += ymap->get_bucket_count();
01611 maximum += 64*ymap->nb;
01612 }
01613 if (cbmap)
01614 {
01615 buckets += cbmap->get_bucket_count();
01616 maximum += 64*cbmap->nb;
01617 }
01618 if (crmap)
01619 {
01620 buckets += crmap->get_bucket_count();
01621 maximum += 64*crmap->nb;
01622 }
01623 return 100*buckets/ (maximum ? maximum : 1);
01624 }
01625
01626 unsigned int
01627 IWPixmap::get_memory_usage(void) const
01628 {
01629 unsigned int usage = sizeof(GPixmap);
01630 if (ymap)
01631 usage += ymap->get_memory_usage();
01632 if (cbmap)
01633 usage += cbmap->get_memory_usage();
01634 if (crmap)
01635 usage += crmap->get_memory_usage();
01636 return usage;
01637 }
01638
01639
01640 GP<GPixmap>
01641 IWPixmap::get_pixmap(void)
01642 {
01643
01644 if (ymap == 0)
01645 return 0;
01646
01647 int w = ymap->iw;
01648 int h = ymap->ih;
01649 GP<GPixmap> ppm = GPixmap::create(h, w);
01650
01651 signed char *ptr = (signed char*) (*ppm)[0];
01652 int rowsep = ppm->rowsize() * sizeof(GPixel);
01653 int pixsep = sizeof(GPixel);
01654 ymap->image(ptr, rowsep, pixsep);
01655 if (crmap && cbmap && crcb_delay >= 0)
01656 {
01657 cbmap->image(ptr+1, rowsep, pixsep, crcb_half);
01658 crmap->image(ptr+2, rowsep, pixsep, crcb_half);
01659 }
01660
01661 if (crmap && cbmap && crcb_delay >= 0)
01662 {
01663 Transform::Decode::YCbCr_to_RGB((*ppm)[0], w, h, ppm->rowsize());
01664 }
01665 else
01666 {
01667 for (int i=0; i<h; i++)
01668 {
01669 GPixel *pixrow = (*ppm)[i];
01670 for (int j=0; j<w; j++, pixrow++)
01671 pixrow->b = pixrow->g = pixrow->r
01672 = 127 - (int)(((signed char*)pixrow)[0]);
01673 }
01674 }
01675
01676 return ppm;
01677 }
01678
01679
01680
01681 GP<GPixmap>
01682 IWPixmap::get_pixmap(int subsample, const GRect &rect)
01683 {
01684 if (ymap == 0)
01685 return 0;
01686
01687 int w = rect.width();
01688 int h = rect.height();
01689 GP<GPixmap> ppm = GPixmap::create(h,w);
01690
01691 signed char *ptr = (signed char*) (*ppm)[0];
01692 int rowsep = ppm->rowsize() * sizeof(GPixel);
01693 int pixsep = sizeof(GPixel);
01694 ymap->image(subsample, rect, ptr, rowsep, pixsep);
01695 if (crmap && cbmap && crcb_delay >= 0)
01696 {
01697 cbmap->image(subsample, rect, ptr+1, rowsep, pixsep, crcb_half);
01698 crmap->image(subsample, rect, ptr+2, rowsep, pixsep, crcb_half);
01699 }
01700
01701 if (crmap && cbmap && crcb_delay >= 0)
01702 {
01703 Transform::Decode::YCbCr_to_RGB((*ppm)[0], w, h, ppm->rowsize());
01704 }
01705 else
01706 {
01707 for (int i=0; i<h; i++)
01708 {
01709 GPixel *pixrow = (*ppm)[i];
01710 for (int j=0; j<w; j++, pixrow++)
01711 pixrow->b = pixrow->g = pixrow->r
01712 = 127 - (int)(((signed char*)pixrow)[0]);
01713 }
01714 }
01715
01716 return ppm;
01717 }
01718
01719
01720 int
01721 IWPixmap::decode_chunk(GP<ByteStream> gbs)
01722 {
01723
01724 if (! ycodec)
01725 {
01726 cslice = cserial = 0;
01727 delete ymap;
01728 ymap = 0;
01729 }
01730
01731
01732 struct IW44Image::PrimaryHeader primary;
01733 primary.decode(gbs);
01734 if (primary.serial != cserial)
01735 G_THROW( ERR_MSG("IW44Image.wrong_serial2") );
01736 int nslices = cslice + primary.slices;
01737
01738 if (cserial == 0)
01739 {
01740 struct IW44Image::SecondaryHeader secondary;
01741 secondary.decode(gbs);
01742 if ((secondary.major & 0x7f) != IWCODEC_MAJOR)
01743 G_THROW( ERR_MSG("IW44Image.incompat_codec2") );
01744 if (secondary.minor > IWCODEC_MINOR)
01745 G_THROW( ERR_MSG("IW44Image.recent_codec2") );
01746
01747 struct IW44Image::TertiaryHeader tertiary;
01748 tertiary.decode(gbs, secondary.major & 0x7f, secondary.minor);
01749
01750 int w = (tertiary.xhi << 8) | tertiary.xlo;
01751 int h = (tertiary.yhi << 8) | tertiary.ylo;
01752 crcb_delay = 0;
01753 crcb_half = 0;
01754 if (secondary.minor>=2)
01755 crcb_delay = tertiary.crcbdelay & 0x7f;
01756 if (secondary.minor>=2)
01757 crcb_half = (tertiary.crcbdelay & 0x80 ? 0 : 1);
01758 if (secondary.major & 0x80)
01759 crcb_delay = -1;
01760
01761 assert(! ymap);
01762 assert(! ycodec);
01763 ymap = new Map(w, h);
01764 ycodec = new Codec::Decode(*ymap);
01765 if (crcb_delay >= 0)
01766 {
01767 cbmap = new Map(w, h);
01768 crmap = new Map(w, h);
01769 cbcodec = new Codec::Decode(*cbmap);
01770 crcodec = new Codec::Decode(*crmap);
01771 }
01772 }
01773
01774 assert(ymap);
01775 assert(ycodec);
01776 GP<ZPCodec> gzp=ZPCodec::create(gbs, false, true);
01777 ZPCodec &zp=*gzp;
01778 int flag = 1;
01779 while (flag && cslice<nslices)
01780 {
01781 flag = ycodec->code_slice(zp);
01782 if (crcodec && cbcodec && crcb_delay<=cslice)
01783 {
01784 flag |= cbcodec->code_slice(zp);
01785 flag |= crcodec->code_slice(zp);
01786 }
01787 cslice++;
01788 }
01789
01790 cserial += 1;
01791 return nslices;
01792 }
01793
01794
01795 int
01796 IWPixmap::parm_crcbdelay(const int parm)
01797 {
01798 if (parm >= 0)
01799 crcb_delay = parm;
01800 return crcb_delay;
01801 }
01802
01803 void
01804 IWPixmap::parm_dbfrac(float frac)
01805 {
01806 if (frac>0 && frac<=1)
01807 db_frac = frac;
01808 else
01809 G_THROW( ERR_MSG("IW44Image.param_range2") );
01810 }
01811
01812 int
01813 IWPixmap::get_serial(void)
01814 {
01815 return cserial;
01816 }
01817
01818
01819 void
01820 IWPixmap::decode_iff(IFFByteStream &iff, int maxchunks)
01821 {
01822 if (ycodec)
01823 G_THROW( ERR_MSG("IW44Image.left_open4") );
01824 GUTF8String chkid;
01825 iff.get_chunk(chkid);
01826 if (chkid!="FORM:PM44" && chkid!="FORM:BM44")
01827 G_THROW( ERR_MSG("IW44Image.corrupt_BM44_2") );
01828 while (--maxchunks>=0 && iff.get_chunk(chkid))
01829 {
01830 if (chkid=="PM44" || chkid=="BM44")
01831 decode_chunk(iff.get_bytestream());
01832 iff.close_chunk();
01833 }
01834 iff.close_chunk();
01835 close_codec();
01836 }
01837
01839
01841
01842 void
01843 IW44Image::Transform::filter_begin(int w, int h)
01844 {
01845 if (MMXControl::mmxflag < 0)
01846 MMXControl::enable_mmx();
01847 }
01848
01849
01850 void
01851 IW44Image::Transform::filter_end(void)
01852 {
01853 #ifdef MMX
01854 if (MMXControl::mmxflag > 0)
01855 MMXemms;
01856 #endif
01857 }
01858
01859
01861
01863
01864
01865
01866
01867
01868
01869 void
01870 IW44Image::Transform::Decode::backward(short *p, int w, int h, int rowsize, int begin, int end)
01871 {
01872
01873 filter_begin(w,h);
01874
01875 for (int scale=begin>>1; scale>=end; scale>>=1)
01876 {
01877 #ifdef IWTRANSFORM_TIMER
01878 int tv,th;
01879 th = tv = GOS::ticks();
01880 #endif
01881 filter_bv(p, w, h, rowsize, scale);
01882 #ifdef IWTRANSFORM_TIMER
01883 th = GOS::ticks();
01884 tv = th - tv;
01885 #endif
01886 filter_bh(p, w, h, rowsize, scale);
01887 #ifdef IWTRANSFORM_TIMER
01888 th = GOS::ticks()-th;
01889 DjVuPrintErrorUTF8("back%d\tv=%dms h=%dms\n", scale,tv,th);
01890 #endif
01891 }
01892
01893 filter_end();
01894 }
01895
01896
01897
01898
01900
01902
01903
01904 void
01905 IW44Image::Transform::Decode::YCbCr_to_RGB(GPixel *p, int w, int h, int rowsize)
01906 {
01907 for (int i=0; i<h; i++,p+=rowsize)
01908 {
01909 GPixel *q = p;
01910 for (int j=0; j<w; j++,q++)
01911 {
01912 signed char y = ((signed char*)q)[0];
01913 signed char b = ((signed char*)q)[1];
01914 signed char r = ((signed char*)q)[2];
01915
01916 int t1 = b >> 2 ;
01917 int t2 = r + (r >> 1);
01918 int t3 = y + 128 - t1;
01919 int tr = y + 128 + t2;
01920 int tg = t3 - (t2 >> 1);
01921 int tb = t3 + (b << 1);
01922 q->r = max(0,min(255,tr));
01923 q->g = max(0,min(255,tg));
01924 q->b = max(0,min(255,tb));
01925 }
01926 }
01927 }
01928
01929
01930 #ifdef HAVE_NAMESPACES
01931 }
01932 # ifndef NOT_USING_DJVU_NAMESPACE
01933 using namespace DJVU;
01934 # endif
01935 #endif