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 #include "JB2Image.h"
00069 #include "GThreads.h"
00070 #include "GRect.h"
00071 #include "GBitmap.h"
00072 #include <string.h>
00073
00074
00075 #ifdef HAVE_NAMESPACES
00076 namespace DJVU {
00077 # ifdef NOT_DEFINED // Just to fool emacs c++ mode
00078 }
00079 #endif
00080 #endif
00081
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 class JB2Dict::JB2Codec::Decode : public JB2Dict::JB2Codec
00095 {
00096 public:
00097 Decode(void);
00098 void init(const GP<ByteStream> &gbs);
00099
00100 void code(const GP<JB2Image> &jim);
00101 void code(JB2Image *jim) {const GP<JB2Image> gjim(jim);code(gjim);}
00102 void code(const GP<JB2Dict> &jim);
00103 void code(JB2Dict *jim) {const GP<JB2Dict> gjim(jim);code(gjim);}
00104 void set_dict_callback(JB2DecoderCallback *cb, void *arg);
00105 protected:
00106 int CodeNum(const int lo, const int hi, NumContext &ctx);
00107
00108
00109 bool CodeBit(const bool bit, BitContext &ctx);
00110 void code_comment(GUTF8String &comment);
00111 void code_record_type(int &rectype);
00112 int code_match_index(int &index, JB2Dict &jim);
00113 void code_inherited_shape_count(JB2Dict &jim);
00114 void code_image_size(JB2Dict &jim);
00115 void code_image_size(JB2Image &jim);
00116 void code_absolute_location(JB2Blit *jblt, int rows, int columns);
00117 void code_absolute_mark_size(GBitmap &bm, int border=0);
00118 void code_relative_mark_size(GBitmap &bm, int cw, int ch, int border=0);
00119 void code_bitmap_directly(GBitmap &bm,const int dw, int dy,
00120 unsigned char *up2, unsigned char *up1, unsigned char *up0 );
00121 void code_bitmap_by_cross_coding (GBitmap &bm, GBitmap &cbm,
00122 const int xd2c, const int dw, int dy, int cy,
00123 unsigned char *up1, unsigned char *up0, unsigned char *xup1,
00124 unsigned char *xup0, unsigned char *xdn1 );
00125 int get_diff(const int x_diff,NumContext &rel_loc);
00126
00127 private:
00128 GP<ZPCodec> gzp;
00129 JB2DecoderCallback *cbfunc;
00130 void *cbarg;
00131 };
00132
00136
00137
00138 JB2Dict::JB2Dict()
00139 : inherited_shapes(0)
00140 {
00141 }
00142
00143 void
00144 JB2Dict::init()
00145 {
00146 inherited_shapes = 0;
00147 inherited_dict = 0;
00148 shapes.empty();
00149 }
00150
00151 JB2Shape &
00152 JB2Dict::get_shape(const int shapeno)
00153 {
00154 JB2Shape *retval;
00155 if(shapeno >= inherited_shapes)
00156 {
00157 retval=&shapes[shapeno - inherited_shapes];
00158 }else if(inherited_dict)
00159 {
00160 retval=&(inherited_dict->get_shape(shapeno));
00161 }else
00162 {
00163 G_THROW( ERR_MSG("JB2Image.bad_number") );
00164 }
00165 return *retval;
00166 }
00167
00168 const JB2Shape &
00169 JB2Dict::get_shape(const int shapeno) const
00170 {
00171 const JB2Shape *retval;
00172 if(shapeno >= inherited_shapes)
00173 {
00174 retval=&shapes[shapeno - inherited_shapes];
00175 }else if(inherited_dict)
00176 {
00177 retval=&(inherited_dict->get_shape(shapeno));
00178 }else
00179 {
00180 G_THROW( ERR_MSG("JB2Image.bad_number") );
00181 }
00182 return *retval;
00183 }
00184
00185 void
00186 JB2Dict::set_inherited_dict(const GP<JB2Dict> &dict)
00187 {
00188 if (shapes.size() > 0)
00189 G_THROW( ERR_MSG("JB2Image.cant_set") );
00190 if (inherited_dict)
00191 G_THROW( ERR_MSG("JB2Image.cant_change") );
00192 inherited_dict = dict;
00193 inherited_shapes = dict->get_shape_count();
00194
00195 for (int i=0; i<inherited_shapes; i++)
00196 {
00197 JB2Shape &jshp = dict->get_shape(i);
00198 if (jshp.bits) jshp.bits->share();
00199 }
00200 }
00201
00202 void
00203 JB2Dict::compress()
00204 {
00205 for (int i=shapes.lbound(); i<=shapes.hbound(); i++)
00206 shapes[i].bits->compress();
00207 }
00208
00209 unsigned int
00210 JB2Dict::get_memory_usage() const
00211 {
00212 unsigned int usage = sizeof(JB2Dict);
00213 usage += sizeof(JB2Shape) * shapes.size();
00214 for (int i=shapes.lbound(); i<=shapes.hbound(); i++)
00215 if (shapes[i].bits)
00216 usage += shapes[i].bits->get_memory_usage();
00217 return usage;
00218 }
00219
00220 int
00221 JB2Dict::add_shape(const JB2Shape &shape)
00222 {
00223 if (shape.parent >= get_shape_count())
00224 G_THROW( ERR_MSG("JB2Image.bad_parent_shape") );
00225 int index = shapes.size();
00226 shapes.touch(index);
00227 shapes[index] = shape;
00228 return index + inherited_shapes;
00229 }
00230
00231 void
00232 JB2Dict::decode(const GP<ByteStream> &gbs, JB2DecoderCallback *cb, void *arg)
00233 {
00234 init();
00235 JB2Codec::Decode codec;
00236 codec.init(gbs);
00237 codec.set_dict_callback(cb,arg);
00238 codec.code(this);
00239 }
00240
00241
00242
00246
00247
00248 JB2Image::JB2Image(void)
00249 : width(0), height(0), reproduce_old_bug(false)
00250 {
00251 }
00252
00253 void
00254 JB2Image::init(void)
00255 {
00256 width = height = 0;
00257 blits.empty();
00258 JB2Dict::init();
00259 }
00260
00261 unsigned int
00262 JB2Image::get_memory_usage() const
00263 {
00264 unsigned int usage = JB2Dict::get_memory_usage();
00265 usage += sizeof(JB2Image) - sizeof(JB2Dict);
00266 usage += sizeof(JB2Blit) * blits.size();
00267 return usage;
00268 }
00269
00270 void
00271 JB2Image::set_dimension(int awidth, int aheight)
00272 {
00273 width = awidth;
00274 height = aheight;
00275 }
00276
00277 int
00278 JB2Image::add_blit(const JB2Blit &blit)
00279 {
00280 if (blit.shapeno >= (unsigned int)get_shape_count())
00281 G_THROW( ERR_MSG("JB2Image.bad_shape") );
00282 int index = blits.size();
00283 blits.touch(index);
00284 blits[index] = blit;
00285 return index;
00286 }
00287
00288 GP<GBitmap>
00289 JB2Image::get_bitmap(int subsample, int align) const
00290 {
00291 if (width==0 || height==0)
00292 G_THROW( ERR_MSG("JB2Image.cant_create") );
00293 int swidth = (width + subsample - 1) / subsample;
00294 int sheight = (height + subsample - 1) / subsample;
00295 int border = ((swidth + align - 1) & ~(align - 1)) - swidth;
00296 GP<GBitmap> bm = GBitmap::create(sheight, swidth, border);
00297 bm->set_grays(1+subsample*subsample);
00298 for (int blitno = 0; blitno < get_blit_count(); blitno++)
00299 {
00300 const JB2Blit *pblit = get_blit(blitno);
00301 const JB2Shape &pshape = get_shape(pblit->shapeno);
00302 if (pshape.bits)
00303 bm->blit(pshape.bits, pblit->left, pblit->bottom, subsample);
00304 }
00305 return bm;
00306 }
00307
00308 GP<GBitmap>
00309 JB2Image::get_bitmap(const GRect &rect, int subsample, int align, int dispy) const
00310 {
00311 if (width==0 || height==0)
00312 G_THROW( ERR_MSG("JB2Image.cant_create") );
00313 int rxmin = rect.xmin * subsample;
00314 int rymin = rect.ymin * subsample;
00315 int swidth = rect.width();
00316 int sheight = rect.height();
00317 int border = ((swidth + align - 1) & ~(align - 1)) - swidth;
00318 GP<GBitmap> bm = GBitmap::create(sheight, swidth, border);
00319 bm->set_grays(1+subsample*subsample);
00320 for (int blitno = 0; blitno < get_blit_count(); blitno++)
00321 {
00322 const JB2Blit *pblit = get_blit(blitno);
00323 const JB2Shape &pshape = get_shape(pblit->shapeno);
00324 if (pshape.bits)
00325 bm->blit(pshape.bits, pblit->left-rxmin, pblit->bottom-rymin+dispy, subsample);
00326 }
00327 return bm;
00328 }
00329
00330 void
00331 JB2Image::decode(const GP<ByteStream> &gbs, JB2DecoderCallback *cb, void *arg)
00332 {
00333 init();
00334 JB2Codec::Decode codec;
00335 codec.init(gbs);
00336 codec.set_dict_callback(cb,arg);
00337 codec.code(this);
00338 }
00339
00340
00341
00345
00346
00347
00348 #define START_OF_DATA (0)
00349 #define NEW_MARK (1)
00350 #define NEW_MARK_LIBRARY_ONLY (2)
00351 #define NEW_MARK_IMAGE_ONLY (3)
00352 #define MATCHED_REFINE (4)
00353 #define MATCHED_REFINE_LIBRARY_ONLY (5)
00354 #define MATCHED_REFINE_IMAGE_ONLY (6)
00355 #define MATCHED_COPY (7)
00356 #define NON_MARK_DATA (8)
00357 #define REQUIRED_DICT_OR_RESET (9)
00358 #define PRESERVED_COMMENT (10)
00359 #define END_OF_DATA (11)
00360
00361
00362
00363
00364
00365 static const int BIGPOSITIVE = 262142;
00366 static const int BIGNEGATIVE = -262143;
00367 static const int CELLCHUNK = 20000;
00368 static const int CELLEXTRA = 500;
00369
00370
00371
00372
00373 JB2Dict::JB2Codec::Decode::Decode(void)
00374 : JB2Dict::JB2Codec(0), cbfunc(0), cbarg(0) {}
00375
00376 void
00377 JB2Dict::JB2Codec::Decode::init(const GP<ByteStream> &gbs)
00378 {
00379 gzp=ZPCodec::create(gbs,false,true);
00380 }
00381
00382 JB2Dict::JB2Codec::JB2Codec(const bool xencoding)
00383 : encoding(xencoding),
00384 cur_ncell(0),
00385 gbitcells(bitcells,CELLCHUNK+CELLEXTRA),
00386 gleftcell(leftcell,CELLCHUNK+CELLEXTRA),
00387 grightcell(rightcell,CELLCHUNK+CELLEXTRA),
00388 refinementp(false),
00389 gotstartrecordp(0),
00390 dist_comment_byte(0),
00391 dist_comment_length(0),
00392 dist_record_type(0),
00393 dist_match_index(0),
00394 dist_refinement_flag(0),
00395 abs_loc_x(0),
00396 abs_loc_y(0),
00397 abs_size_x(0),
00398 abs_size_y(0),
00399 image_size_dist(0),
00400 inherited_shape_count_dist(0),
00401 offset_type_dist(0),
00402 rel_loc_x_current(0),
00403 rel_loc_x_last(0),
00404 rel_loc_y_current(0),
00405 rel_loc_y_last(0),
00406 rel_size_x(0),
00407 rel_size_y(0)
00408 {
00409 memset(bitdist, 0, sizeof(bitdist));
00410 memset(cbitdist, 0, sizeof(cbitdist));
00411
00412 bitcells[0] = 0;
00413 leftcell[0] = rightcell[0] = 0;
00414 cur_ncell = 1;
00415 }
00416
00417 JB2Dict::JB2Codec::~JB2Codec() {}
00418
00419 void
00420 JB2Dict::JB2Codec::reset_numcoder()
00421 {
00422 dist_comment_byte = 0;
00423 dist_comment_length = 0;
00424 dist_record_type = 0;
00425 dist_match_index = 0;
00426 abs_loc_x = 0;
00427 abs_loc_y = 0;
00428 abs_size_x = 0;
00429 abs_size_y = 0;
00430 image_size_dist = 0;
00431 inherited_shape_count_dist = 0;
00432 rel_loc_x_current = 0;
00433 rel_loc_x_last = 0;
00434 rel_loc_y_current = 0;
00435 rel_loc_y_last = 0;
00436 rel_size_x = 0;
00437 rel_size_y = 0;
00438 gbitcells.clear();
00439 gleftcell.clear();
00440 grightcell.clear();
00441 cur_ncell = 1;
00442 }
00443
00444
00445 void
00446 JB2Dict::JB2Codec::Decode::set_dict_callback(JB2DecoderCallback *cb, void *arg)
00447 {
00448 cbfunc = cb;
00449 cbarg = arg;
00450 }
00451
00452
00453
00454
00455 inline bool
00456 JB2Dict::JB2Codec::Decode::CodeBit(const bool, BitContext &ctx)
00457 {
00458 return gzp->decoder(ctx)?true:false;
00459 }
00460
00461 int
00462 JB2Dict::JB2Codec::Decode::CodeNum(int low, int high, NumContext &ctx)
00463 {
00464 return JB2Codec::CodeNum(low,high,&ctx,0);
00465 }
00466
00467 int
00468 JB2Dict::JB2Codec::CodeNum(int low, int high, NumContext *pctx, int v)
00469 {
00470 bool negative=false;
00471 int cutoff;
00472
00473 if (!pctx || ((int)*pctx >= cur_ncell))
00474 G_THROW( ERR_MSG("JB2Image.bad_numcontext") );
00475
00476 cutoff = 0;
00477 for(int phase=1,range=0xffffffff;range != 1;)
00478 {
00479 if (! *pctx)
00480 {
00481 const int max_ncell=gbitcells;
00482 if (cur_ncell >= max_ncell)
00483 {
00484 const int nmax_ncell = max_ncell+CELLCHUNK;
00485 gbitcells.resize(nmax_ncell);
00486 gleftcell.resize(nmax_ncell);
00487 grightcell.resize(nmax_ncell);
00488 }
00489 *pctx = cur_ncell ++;
00490 bitcells[*pctx] = 0;
00491 leftcell[*pctx] = rightcell[*pctx] = 0;
00492 }
00493
00494 const bool decision = encoding
00495 ? ((low < cutoff && high >= cutoff)
00496 ? CodeBit((v>=cutoff),bitcells[*pctx])
00497 : (v >= cutoff))
00498 : ((low>=cutoff)||((high>=cutoff)&&CodeBit(false,bitcells[*pctx])));
00499
00500 pctx = decision?(&rightcell[*pctx]):(&leftcell[*pctx]);
00501
00502 switch (phase)
00503 {
00504 case 1:
00505 negative = !decision;
00506 if (negative)
00507 {
00508 if (encoding)
00509 v = - v - 1;
00510 const int temp = - low - 1;
00511 low = - high - 1;
00512 high = temp;
00513 }
00514 phase = 2; cutoff = 1;
00515 break;
00516
00517 case 2:
00518 if (!decision)
00519 {
00520 phase = 3;
00521 range = (cutoff + 1) / 2;
00522 if (range == 1)
00523 cutoff = 0;
00524 else
00525 cutoff -= range / 2;
00526 }
00527 else
00528 {
00529 cutoff += cutoff + 1;
00530 }
00531 break;
00532
00533 case 3:
00534 range /= 2;
00535 if (range != 1)
00536 {
00537 if (!decision)
00538 cutoff -= range / 2;
00539 else
00540 cutoff += range / 2;
00541 }
00542 else if (!decision)
00543 {
00544 cutoff --;
00545 }
00546 break;
00547 }
00548 }
00549 return (negative)?(- cutoff - 1):cutoff;
00550 }
00551
00552
00553
00554
00555
00556 void
00557 JB2Dict::JB2Codec::Decode::code_comment(GUTF8String &comment)
00558 {
00559 int size=CodeNum(0, BIGPOSITIVE, dist_comment_length);
00560 comment.empty();
00561 char *combuf = comment.getbuf(size);
00562 for (int i=0; i<size; i++)
00563 {
00564 combuf[i]=CodeNum(0, 255, dist_comment_byte);
00565 }
00566 comment.getbuf();
00567 }
00568
00569
00570
00571
00572
00573 void
00574 JB2Dict::JB2Codec::init_library(JB2Dict &jim)
00575 {
00576 int nshape = jim.get_inherited_shape_count();
00577 shape2lib.resize(0,nshape-1);
00578 lib2shape.resize(0,nshape-1);
00579 libinfo.resize(0,nshape-1);
00580 for (int i=0; i<nshape; i++)
00581 {
00582 shape2lib[i] = i;
00583 lib2shape[i] = i;
00584 JB2Shape &jshp = jim.get_shape(i);
00585 libinfo[i].compute_bounding_box(*(jshp.bits));
00586 }
00587 }
00588
00589 int
00590 JB2Dict::JB2Codec::add_library(const int shapeno, JB2Shape &jshp)
00591 {
00592 const int libno = lib2shape.hbound() + 1;
00593 lib2shape.touch(libno);
00594 lib2shape[libno] = shapeno;
00595 shape2lib.touch(shapeno);
00596 shape2lib[shapeno] = libno;
00597 libinfo.touch(libno);
00598 libinfo[libno].compute_bounding_box(*(jshp.bits));
00599 return libno;
00600 }
00601
00602
00603
00604
00605 inline void
00606 JB2Dict::JB2Codec::Decode::code_record_type(int &rectype)
00607 {
00608 rectype=CodeNum( START_OF_DATA, END_OF_DATA, dist_record_type);
00609 }
00610
00611 int
00612 JB2Dict::JB2Codec::Decode::code_match_index(int &index, JB2Dict &)
00613 {
00614 int match=CodeNum(0, lib2shape.hbound(), dist_match_index);
00615 index = lib2shape[match];
00616 return match;
00617 }
00618
00619
00620
00621
00622 int
00623 JB2Dict::JB2Codec::update_short_list(const int v)
00624 {
00625 if (++ short_list_pos == 3)
00626 short_list_pos = 0;
00627 int * const s = short_list;
00628 s[short_list_pos] = v;
00629
00630 return (s[0] >= s[1])
00631 ?((s[0] > s[2])?((s[1] >= s[2])?s[1]:s[2]):s[0])
00632 :((s[0] < s[2])?((s[1] >= s[2])?s[2]:s[1]):s[0]);
00633 }
00634
00635
00636
00637
00638
00639
00640 void
00641 JB2Dict::JB2Codec::Decode::code_inherited_shape_count(JB2Dict &jim)
00642 {
00643 int size=CodeNum(0, BIGPOSITIVE, inherited_shape_count_dist);
00644 {
00645 GP<JB2Dict> dict = jim.get_inherited_dict();
00646 if (!dict && size>0)
00647 {
00648
00649 if (cbfunc)
00650 dict = (*cbfunc)(cbarg);
00651 if (dict)
00652 jim.set_inherited_dict(dict);
00653 }
00654 if (!dict && size>0)
00655 G_THROW( ERR_MSG("JB2Image.need_dict") );
00656 if (dict && size!=dict->get_shape_count())
00657 G_THROW( ERR_MSG("JB2Image.bad_dict") );
00658 }
00659 }
00660
00661 void
00662 JB2Dict::JB2Codec::Decode::code_image_size(JB2Dict &jim)
00663 {
00664 int w=CodeNum(0, BIGPOSITIVE, image_size_dist);
00665 int h=CodeNum(0, BIGPOSITIVE, image_size_dist);
00666 if (w || h)
00667 G_THROW( ERR_MSG("JB2Image.bad_dict2") );
00668 JB2Codec::code_image_size(jim);
00669 }
00670
00671 void
00672 JB2Dict::JB2Codec::code_image_size(JB2Dict &)
00673 {
00674 last_left = 1;
00675 last_row_left = 0;
00676 last_row_bottom = 0;
00677 last_right = 0;
00678 fill_short_list(last_row_bottom);
00679 gotstartrecordp = 1;
00680 }
00681
00682 void
00683 JB2Dict::JB2Codec::Decode::code_image_size(JB2Image &jim)
00684 {
00685 image_columns=CodeNum(0, BIGPOSITIVE, image_size_dist);
00686 image_rows=CodeNum(0, BIGPOSITIVE, image_size_dist);
00687 if (!image_columns || !image_rows)
00688 G_THROW( ERR_MSG("JB2Image.zero_dim") );
00689 jim.set_dimension(image_columns, image_rows);
00690 JB2Codec::code_image_size(jim);
00691 }
00692
00693 void
00694 JB2Dict::JB2Codec::code_image_size(JB2Image &)
00695 {
00696 last_left = 1 + image_columns;
00697 last_row_left = 0;
00698 last_row_bottom = image_rows;
00699 last_right = 0;
00700 fill_short_list(last_row_bottom);
00701 gotstartrecordp = 1;
00702 }
00703
00704 inline int
00705 JB2Dict::JB2Codec::Decode::get_diff(int,NumContext &rel_loc)
00706 {
00707 return CodeNum(BIGNEGATIVE, BIGPOSITIVE, rel_loc);
00708 }
00709
00710 void
00711 JB2Dict::JB2Codec::code_relative_location(JB2Blit *jblt, int rows, int columns)
00712 {
00713
00714 if (!gotstartrecordp)
00715 G_THROW( ERR_MSG("JB2Image.no_start") );
00716
00717 int bottom=0, left=0, top=0, right=0;
00718 int x_diff, y_diff;
00719 if (encoding)
00720 {
00721 left = jblt->left + 1;
00722 bottom = jblt->bottom + 1;
00723 right = left + columns - 1;
00724 top = bottom + rows - 1;
00725 }
00726
00727 int new_row=CodeBit((left<last_left), offset_type_dist);
00728 if (new_row)
00729 {
00730
00731 x_diff=get_diff(left-last_row_left,rel_loc_x_last);
00732 y_diff=get_diff(top-last_row_bottom,rel_loc_y_last);
00733 if (!encoding)
00734 {
00735 left = last_row_left + x_diff;
00736 top = last_row_bottom + y_diff;
00737 right = left + columns - 1;
00738 bottom = top - rows + 1;
00739 }
00740 last_left = last_row_left = left;
00741 last_right = right;
00742 last_bottom = last_row_bottom = bottom;
00743 fill_short_list(bottom);
00744 }
00745 else
00746 {
00747
00748 x_diff=get_diff(left-last_right,rel_loc_x_current);
00749 y_diff=get_diff(bottom-last_bottom,rel_loc_y_current);
00750 if (!encoding)
00751 {
00752 left = last_right + x_diff;
00753 bottom = last_bottom + y_diff;
00754 right = left + columns - 1;
00755 top = bottom + rows - 1;
00756 }
00757 last_left = left;
00758 last_right = right;
00759 last_bottom = update_short_list(bottom);
00760 }
00761
00762 if (!encoding)
00763 {
00764 jblt->bottom = bottom - 1;
00765 jblt->left = left - 1;
00766 }
00767 }
00768
00769 void
00770 JB2Dict::JB2Codec::Decode::code_absolute_location(JB2Blit *jblt, int rows, int columns)
00771 {
00772
00773 if (!gotstartrecordp)
00774 G_THROW( ERR_MSG("JB2Image.no_start") );
00775 int left=CodeNum(1, image_columns, abs_loc_x);
00776 int top=CodeNum(1, image_rows, abs_loc_y);
00777 jblt->bottom = top - rows + 1 - 1;
00778 jblt->left = left - 1;
00779 }
00780
00781 void
00782 JB2Dict::JB2Codec::Decode::code_absolute_mark_size(GBitmap &bm, int border)
00783 {
00784 int xsize=CodeNum(0, BIGPOSITIVE, abs_size_x);
00785 int ysize=CodeNum(0, BIGPOSITIVE, abs_size_y);
00786 if ((xsize!=(unsigned short)xsize) || (ysize!=(unsigned short)ysize))
00787 G_THROW( ERR_MSG("JB2Image.bad_number") );
00788 bm.init(ysize, xsize, border);
00789 }
00790
00791 void
00792 JB2Dict::JB2Codec::Decode::code_relative_mark_size(GBitmap &bm, int cw, int ch, int border)
00793 {
00794 int xdiff=CodeNum(BIGNEGATIVE, BIGPOSITIVE, rel_size_x);
00795 int ydiff=CodeNum(BIGNEGATIVE, BIGPOSITIVE, rel_size_y);
00796 int xsize = cw + xdiff;
00797 int ysize = ch + ydiff;
00798 if ((xsize!=(unsigned short)xsize) || (ysize!=(unsigned short)ysize))
00799 G_THROW( ERR_MSG("JB2Image.bad_number") );
00800 bm.init(ysize, xsize, border);
00801 }
00802
00803
00804
00805
00806
00807
00808 void
00809 JB2Dict::JB2Codec::code_bitmap_directly (GBitmap &bm)
00810 {
00811
00812 GMonitorLock lock(bm.monitor());
00813
00814 bm.minborder(3);
00815
00816 int dy = bm.rows() - 1;
00817 code_bitmap_directly(bm,bm.columns(),dy,bm[dy+2],bm[dy+1],bm[dy]);
00818 }
00819
00820 void
00821 JB2Dict::JB2Codec::Decode::code_bitmap_directly(
00822 GBitmap &bm,const int dw, int dy,
00823 unsigned char *up2, unsigned char *up1, unsigned char *up0 )
00824 {
00825 ZPCodec &zp=*gzp;
00826
00827 while (dy >= 0)
00828 {
00829 int context=get_direct_context(up2, up1, up0, 0);
00830 for(int dx=0;dx < dw;)
00831 {
00832 int n = zp.decoder(bitdist[context]);
00833 up0[dx++] = n;
00834 context=shift_direct_context(context, n, up2, up1, up0, dx);
00835 }
00836
00837 dy -= 1;
00838 up2 = up1;
00839 up1 = up0;
00840 up0 = bm[dy];
00841 }
00842 #ifndef NDEBUG
00843 bm.check_border();
00844 #endif
00845 }
00846
00847
00848
00849
00850
00851
00852
00853 void
00854 JB2Dict::JB2Codec::code_bitmap_by_cross_coding (GBitmap &bm, GP<GBitmap> &cbm, const int libno)
00855 {
00856
00857 GP<GBitmap> copycbm=GBitmap::create();
00858 if (cbm->monitor())
00859 {
00860
00861 GMonitorLock lock2(cbm->monitor());
00862 copycbm->init(*cbm);
00863 cbm = copycbm;
00864 }
00865 GMonitorLock lock1(bm.monitor());
00866
00867 const int cw = cbm->columns();
00868 const int dw = bm.columns();
00869 const int dh = bm.rows();
00870 const LibRect &l = libinfo[libno];
00871 const int xd2c = (dw/2 - dw + 1) - ((l.right - l.left + 1)/2 - l.right);
00872 const int yd2c = (dh/2 - dh + 1) - ((l.top - l.bottom + 1)/2 - l.top);
00873
00874 bm.minborder(2);
00875 cbm->minborder(2-xd2c);
00876 cbm->minborder(2+dw+xd2c-cw);
00877
00878 const int dy = dh - 1;
00879 const int cy = dy + yd2c;
00880 #ifndef NDEBUG
00881 bm.check_border();
00882 cbm->check_border();
00883 #endif
00884 code_bitmap_by_cross_coding (bm,*cbm, xd2c, dw, dy, cy, bm[dy+1], bm[dy],
00885 (*cbm)[cy+1] + xd2c, (*cbm)[cy ] + xd2c, (*cbm)[cy-1] + xd2c);
00886 }
00887
00888 void
00889 JB2Dict::JB2Codec::Decode::code_bitmap_by_cross_coding (GBitmap &bm, GBitmap &cbm,
00890 const int xd2c, const int dw, int dy, int cy,
00891 unsigned char *up1, unsigned char *up0, unsigned char *xup1,
00892 unsigned char *xup0, unsigned char *xdn1 )
00893 {
00894 ZPCodec &zp=*gzp;
00895
00896 while (dy >= 0)
00897 {
00898 int context=get_cross_context(
00899 up1, up0, xup1, xup0, xdn1, 0);
00900 for(int dx=0;dx < dw;)
00901 {
00902 const int n = zp.decoder(cbitdist[context]);
00903 up0[dx++] = n;
00904 context=shift_cross_context(context, n,
00905 up1, up0, xup1, xup0, xdn1, dx);
00906 }
00907
00908 up1 = up0;
00909 up0 = bm[--dy];
00910 xup1 = xup0;
00911 xup0 = xdn1;
00912 xdn1 = cbm[(--cy)-1] + xd2c;
00913 #ifndef NDEBUG
00914 bm.check_border();
00915 #endif
00916 }
00917 }
00918
00919
00920
00921
00922
00923
00924 void
00925 JB2Dict::JB2Codec::code_record(
00926 int &rectype, const GP<JB2Dict> &gjim, JB2Shape *xjshp)
00927 {
00928 GP<GBitmap> cbm;
00929 GP<GBitmap> bm;
00930 int shapeno = -1;
00931
00932
00933 code_record_type(rectype);
00934
00935
00936 switch(rectype)
00937 {
00938 case NEW_MARK_LIBRARY_ONLY:
00939 case MATCHED_REFINE_LIBRARY_ONLY:
00940 {
00941 if(!xjshp)
00942 {
00943 G_THROW( ERR_MSG("JB2Image.bad_number") );
00944 }
00945 JB2Shape &jshp=*xjshp;
00946 if (!encoding)
00947 {
00948 jshp.bits = GBitmap::create();
00949 jshp.parent = -1;
00950 }
00951 bm = jshp.bits;
00952 break;
00953 }
00954 }
00955
00956 switch (rectype)
00957 {
00958 case START_OF_DATA:
00959 {
00960 if(!gjim)
00961 {
00962 G_THROW( ERR_MSG("JB2Image.bad_number") );
00963 }
00964 JB2Dict &jim=*gjim;
00965 code_image_size (jim);
00966 code_eventual_lossless_refinement ();
00967 if (! encoding)
00968 init_library(jim);
00969 break;
00970 }
00971 case NEW_MARK_LIBRARY_ONLY:
00972 {
00973 code_absolute_mark_size (*bm, 4);
00974 code_bitmap_directly (*bm);
00975 break;
00976 }
00977 case MATCHED_REFINE_LIBRARY_ONLY:
00978 {
00979 if(!xjshp||!gjim)
00980 {
00981 G_THROW( ERR_MSG("JB2Image.bad_number") );
00982 }
00983 JB2Dict &jim=*gjim;
00984 JB2Shape &jshp=*xjshp;
00985 int match = code_match_index (jshp.parent, jim);
00986 cbm = jim.get_shape(jshp.parent).bits;
00987 LibRect &l = libinfo[match];
00988 code_relative_mark_size (*bm, l.right-l.left+1, l.top-l.bottom+1, 4);
00989 code_bitmap_by_cross_coding (*bm, cbm, jshp.parent);
00990 break;
00991 }
00992 case PRESERVED_COMMENT:
00993 {
00994 if(!gjim)
00995 {
00996 G_THROW( ERR_MSG("JB2Image.bad_number") );
00997 }
00998 JB2Dict &jim=*gjim;
00999 code_comment(jim.comment);
01000 break;
01001 }
01002 case REQUIRED_DICT_OR_RESET:
01003 {
01004 if (! gotstartrecordp)
01005 {
01006
01007 if(!gjim)
01008 {
01009 G_THROW( ERR_MSG("JB2Image.bad_number") );
01010 }
01011 code_inherited_shape_count(*gjim);
01012 }else
01013
01014 reset_numcoder();
01015 break;
01016 }
01017 case END_OF_DATA:
01018 {
01019 break;
01020 }
01021 default:
01022 {
01023 G_THROW( ERR_MSG("JB2Image.bad_type") );
01024 }
01025 }
01026
01027 if (!encoding)
01028 {
01029
01030 switch(rectype)
01031 {
01032 case NEW_MARK_LIBRARY_ONLY:
01033 case MATCHED_REFINE_LIBRARY_ONLY:
01034 {
01035 if(!xjshp||!gjim)
01036 {
01037 G_THROW( ERR_MSG("JB2Image.bad_number") );
01038 }
01039 JB2Shape &jshp=*xjshp;
01040 shapeno = gjim->add_shape(jshp);
01041 add_library(shapeno, jshp);
01042 break;
01043 }
01044 }
01045
01046
01047 if (bm)
01048 bm->compress();
01049 }
01050 }
01051
01052
01053
01054
01055 void
01056 JB2Dict::JB2Codec::Decode::code(const GP<JB2Dict> &gjim)
01057 {
01058 if(!gjim)
01059 {
01060 G_THROW( ERR_MSG("JB2Image.bad_number") );
01061 }
01062 JB2Dict &jim=*gjim;
01063
01064
01065
01066 int rectype;
01067 JB2Shape tmpshape;
01068 do
01069 {
01070 code_record(rectype, gjim, &tmpshape);
01071 }
01072 while(rectype != END_OF_DATA);
01073 if (!gotstartrecordp)
01074 G_THROW( ERR_MSG("JB2Image.no_start") );
01075 jim.compress();
01076 }
01077
01078
01079
01080
01081
01082 void
01083 JB2Dict::JB2Codec::code_record(
01084 int &rectype, const GP<JB2Image> &gjim, JB2Shape *xjshp, JB2Blit *jblt)
01085 {
01086 GP<GBitmap> bm;
01087 GP<GBitmap> cbm;
01088 int shapeno = -1;
01089 int match;
01090
01091
01092 code_record_type(rectype);
01093
01094
01095 switch(rectype)
01096 {
01097 case NEW_MARK:
01098 case NEW_MARK_LIBRARY_ONLY:
01099 case NEW_MARK_IMAGE_ONLY:
01100 case MATCHED_REFINE:
01101 case MATCHED_REFINE_LIBRARY_ONLY:
01102 case MATCHED_REFINE_IMAGE_ONLY:
01103 case NON_MARK_DATA:
01104 {
01105 if(!xjshp)
01106 {
01107 G_THROW( ERR_MSG("JB2Image.bad_number") );
01108 }
01109 JB2Shape &jshp=*xjshp;
01110 if (!encoding)
01111 {
01112 jshp.bits = GBitmap::create();
01113 jshp.parent = -1;
01114 if (rectype == NON_MARK_DATA)
01115 jshp.parent = -2;
01116 }
01117 bm = jshp.bits;
01118 break;
01119 }
01120 }
01121
01122 switch (rectype)
01123 {
01124 case START_OF_DATA:
01125 {
01126 if(!gjim)
01127 {
01128 G_THROW( ERR_MSG("JB2Image.bad_number") );
01129 }
01130 JB2Image &jim=*gjim;
01131 code_image_size (jim);
01132 code_eventual_lossless_refinement ();
01133 if (! encoding)
01134 init_library(jim);
01135 break;
01136 }
01137 case NEW_MARK:
01138 {
01139 code_absolute_mark_size (*bm, 4);
01140 code_bitmap_directly (*bm);
01141 code_relative_location (jblt, bm->rows(), bm->columns() );
01142 break;
01143 }
01144 case NEW_MARK_LIBRARY_ONLY:
01145 {
01146 code_absolute_mark_size (*bm, 4);
01147 code_bitmap_directly (*bm);
01148 break;
01149 }
01150 case NEW_MARK_IMAGE_ONLY:
01151 {
01152 code_absolute_mark_size (*bm, 3);
01153 code_bitmap_directly (*bm);
01154 code_relative_location (jblt, bm->rows(), bm->columns() );
01155 break;
01156 }
01157 case MATCHED_REFINE:
01158 {
01159 if(!xjshp || !gjim)
01160 {
01161 G_THROW( ERR_MSG("JB2Image.bad_number") );
01162 }
01163 JB2Shape &jshp=*xjshp;
01164 JB2Image &jim=*gjim;
01165 match = code_match_index (jshp.parent, jim);
01166 cbm = jim.get_shape(jshp.parent).bits;
01167 LibRect &l = libinfo[match];
01168 code_relative_mark_size (*bm, l.right-l.left+1, l.top-l.bottom+1, 4);
01169 code_bitmap_by_cross_coding (*bm, cbm, match);
01170 code_relative_location (jblt, bm->rows(), bm->columns() );
01171 break;
01172 }
01173 case MATCHED_REFINE_LIBRARY_ONLY:
01174 {
01175 if(!xjshp||!gjim)
01176 {
01177 G_THROW( ERR_MSG("JB2Image.bad_number") );
01178 }
01179 JB2Image &jim=*gjim;
01180 JB2Shape &jshp=*xjshp;
01181 match = code_match_index (jshp.parent, jim);
01182 cbm = jim.get_shape(jshp.parent).bits;
01183 LibRect &l = libinfo[match];
01184 code_relative_mark_size (*bm, l.right-l.left+1, l.top-l.bottom+1, 4);
01185 break;
01186 }
01187 case MATCHED_REFINE_IMAGE_ONLY:
01188 {
01189 if(!xjshp||!gjim)
01190 {
01191 G_THROW( ERR_MSG("JB2Image.bad_number") );
01192 }
01193 JB2Image &jim=*gjim;
01194 JB2Shape &jshp=*xjshp;
01195 match = code_match_index (jshp.parent, jim);
01196 cbm = jim.get_shape(jshp.parent).bits;
01197 LibRect &l = libinfo[match];
01198 code_relative_mark_size (*bm, l.right-l.left+1, l.top-l.bottom+1, 4);
01199 code_bitmap_by_cross_coding (*bm, cbm, match);
01200 code_relative_location (jblt, bm->rows(), bm->columns() );
01201 break;
01202 }
01203 case MATCHED_COPY:
01204 {
01205 int temp;
01206 if (encoding) temp = jblt->shapeno;
01207 if(!gjim)
01208 {
01209 G_THROW( ERR_MSG("JB2Image.bad_number") );
01210 }
01211 JB2Image &jim=*gjim;
01212 match = code_match_index (temp, jim);
01213 if (!encoding) jblt->shapeno = temp;
01214 bm = jim.get_shape(jblt->shapeno).bits;
01215 LibRect &l = libinfo[match];
01216 jblt->left += l.left;
01217 jblt->bottom += l.bottom;
01218 if (jim.reproduce_old_bug)
01219 code_relative_location (jblt, bm->rows(), bm->columns() );
01220 else
01221 code_relative_location (jblt, l.top-l.bottom+1, l.right-l.left+1 );
01222 jblt->left -= l.left;
01223 jblt->bottom -= l.bottom;
01224 break;
01225 }
01226 case NON_MARK_DATA:
01227 {
01228 code_absolute_mark_size (*bm, 3);
01229 code_bitmap_directly (*bm);
01230 code_absolute_location (jblt, bm->rows(), bm->columns() );
01231 break;
01232 }
01233 case PRESERVED_COMMENT:
01234 {
01235 if(!gjim)
01236 {
01237 G_THROW( ERR_MSG("JB2Image.bad_number") );
01238 }
01239 JB2Image &jim=*gjim;
01240 code_comment(jim.comment);
01241 break;
01242 }
01243 case REQUIRED_DICT_OR_RESET:
01244 {
01245 if(!gjim)
01246 {
01247 G_THROW( ERR_MSG("JB2Image.bad_number") );
01248 }
01249 JB2Image &jim=*gjim;
01250 if (! gotstartrecordp)
01251
01252 code_inherited_shape_count(jim);
01253 else
01254
01255 reset_numcoder();
01256 break;
01257 }
01258 case END_OF_DATA:
01259 {
01260 break;
01261 }
01262 default:
01263 {
01264 G_THROW( ERR_MSG("JB2Image.unknown_type") );
01265 }
01266 }
01267
01268
01269 if (!encoding)
01270 {
01271
01272 switch(rectype)
01273 {
01274 case NEW_MARK:
01275 case NEW_MARK_LIBRARY_ONLY:
01276 case NEW_MARK_IMAGE_ONLY:
01277 case MATCHED_REFINE:
01278 case MATCHED_REFINE_LIBRARY_ONLY:
01279 case MATCHED_REFINE_IMAGE_ONLY:
01280 case NON_MARK_DATA:
01281 {
01282 if(!xjshp||!gjim)
01283 {
01284 G_THROW( ERR_MSG("JB2Image.bad_number") );
01285 }
01286 JB2Shape &jshp=*xjshp;
01287 shapeno = gjim->add_shape(jshp);
01288 shape2lib.touch(shapeno);
01289 shape2lib[shapeno] = -1;
01290 break;
01291 }
01292 }
01293
01294 switch(rectype)
01295 {
01296 case NEW_MARK:
01297 case NEW_MARK_LIBRARY_ONLY:
01298 case MATCHED_REFINE:
01299 case MATCHED_REFINE_LIBRARY_ONLY:
01300 if(!xjshp)
01301 {
01302 G_THROW( ERR_MSG("JB2Image.bad_number") );
01303 }
01304 add_library(shapeno, *xjshp);
01305 break;
01306 }
01307
01308
01309 if (bm)
01310 bm->compress();
01311
01312 switch (rectype)
01313 {
01314 case NEW_MARK:
01315 case NEW_MARK_IMAGE_ONLY:
01316 case MATCHED_REFINE:
01317 case MATCHED_REFINE_IMAGE_ONLY:
01318 case NON_MARK_DATA:
01319 jblt->shapeno = shapeno;
01320 case MATCHED_COPY:
01321 if(!gjim)
01322 {
01323 G_THROW( ERR_MSG("JB2Image.bad_number") );
01324 }
01325 gjim->add_blit(* jblt);
01326 break;
01327 }
01328 }
01329 }
01330
01331
01332
01333
01334 void
01335 JB2Dict::JB2Codec::Decode::code(const GP<JB2Image> &gjim)
01336 {
01337 if(!gjim)
01338 {
01339 G_THROW( ERR_MSG("JB2Image.bad_number") );
01340 }
01341 JB2Image &jim=*gjim;
01342
01343
01344
01345 int rectype;
01346 JB2Blit tmpblit;
01347 JB2Shape tmpshape;
01348 do
01349 {
01350 code_record(rectype, gjim, &tmpshape, &tmpblit);
01351 }
01352 while(rectype!=END_OF_DATA);
01353 if (!gotstartrecordp)
01354 G_THROW( ERR_MSG("JB2Image.no_start") );
01355 jim.compress();
01356 }
01357
01358
01359
01363
01364 void
01365 JB2Dict::JB2Codec::LibRect::compute_bounding_box(const GBitmap &bm)
01366 {
01367
01368 GMonitorLock lock(bm.monitor());
01369
01370 const int w = bm.columns();
01371 const int h = bm.rows();
01372 const int s = bm.rowsize();
01373
01374 for(right=w-1;right >= 0;--right)
01375 {
01376 unsigned char const *p = bm[0] + right;
01377 unsigned char const * const pe = p+(s*h);
01378 for (;(p<pe)&&(!*p);p+=s)
01379 continue;
01380 if (p<pe)
01381 break;
01382 }
01383
01384 for(top=h-1;top >= 0;--top)
01385 {
01386 unsigned char const *p = bm[top];
01387 unsigned char const * const pe = p+w;
01388 for (;(p<pe)&&(!*p); ++p)
01389 continue;
01390 if (p<pe)
01391 break;
01392 }
01393
01394 for (left=0;left <= right;++left)
01395 {
01396 unsigned char const *p = bm[0] + left;
01397 unsigned char const * const pe=p+(s*h);
01398 for (;(p<pe)&&(!*p);p+=s)
01399 continue;
01400 if (p<pe)
01401 break;
01402 }
01403
01404 for(bottom=0;bottom <= top;++bottom)
01405 {
01406 unsigned char const *p = bm[bottom];
01407 unsigned char const * const pe = p+w;
01408 for (;(p<pe)&&(!*p); ++p)
01409 continue;
01410 if (p<pe)
01411 break;
01412 }
01413 }
01414
01415 GP<JB2Dict>
01416 JB2Dict::create(void)
01417 {
01418 return new JB2Dict();
01419 }
01420
01421
01422 #ifdef HAVE_NAMESPACES
01423 }
01424 # ifndef NOT_USING_DJVU_NAMESPACE
01425 using namespace DJVU;
01426 # endif
01427 #endif