• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kviewshell

JB2Image.cpp

Go to the documentation of this file.
00001 //C-  -*- C++ -*-
00002 //C- -------------------------------------------------------------------
00003 //C- DjVuLibre-3.5
00004 //C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
00005 //C- Copyright (c) 2001  AT&T
00006 //C-
00007 //C- This software is subject to, and may be distributed under, the
00008 //C- GNU General Public License, Version 2. The license should have
00009 //C- accompanied the software or you may obtain a copy of the license
00010 //C- from the Free Software Foundation at http://www.fsf.org .
00011 //C-
00012 //C- This program is distributed in the hope that it will be useful,
00013 //C- but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 //C- GNU General Public License for more details.
00016 //C- 
00017 //C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library
00018 //C- distributed by Lizardtech Software.  On July 19th 2002, Lizardtech 
00019 //C- Software authorized us to replace the original DjVu(r) Reference 
00020 //C- Library notice by the following text (see doc/lizard2002.djvu):
00021 //C-
00022 //C-  ------------------------------------------------------------------
00023 //C- | DjVu (r) Reference Library (v. 3.5)
00024 //C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
00025 //C- | The DjVu Reference Library is protected by U.S. Pat. No.
00026 //C- | 6,058,214 and patents pending.
00027 //C- |
00028 //C- | This software is subject to, and may be distributed under, the
00029 //C- | GNU General Public License, Version 2. The license should have
00030 //C- | accompanied the software or you may obtain a copy of the license
00031 //C- | from the Free Software Foundation at http://www.fsf.org .
00032 //C- |
00033 //C- | The computer code originally released by LizardTech under this
00034 //C- | license and unmodified by other parties is deemed "the LIZARDTECH
00035 //C- | ORIGINAL CODE."  Subject to any third party intellectual property
00036 //C- | claims, LizardTech grants recipient a worldwide, royalty-free, 
00037 //C- | non-exclusive license to make, use, sell, or otherwise dispose of 
00038 //C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the 
00039 //C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU 
00040 //C- | General Public License.   This grant only confers the right to 
00041 //C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to 
00042 //C- | the extent such infringement is reasonably necessary to enable 
00043 //C- | recipient to make, have made, practice, sell, or otherwise dispose 
00044 //C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to 
00045 //C- | any greater extent that may be necessary to utilize further 
00046 //C- | modifications or combinations.
00047 //C- |
00048 //C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
00049 //C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
00050 //C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
00051 //C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
00052 //C- +------------------------------------------------------------------
00053 // 
00054 // $Id: JB2Image.cpp,v 1.10 2004/04/17 23:56:11 leonb Exp $
00055 // $Name: release_3_5_15 $
00056 
00057 #ifdef HAVE_CONFIG_H
00058 # include "config.h"
00059 #endif
00060 #if NEED_GNUG_PRAGMAS
00061 # pragma implementation
00062 #endif
00063 
00064 // From: Leon Bottou, 1/31/2002
00065 // Lizardtech has split the corresponding cpp file into a decoder and an encoder.
00066 // Only superficial changes.  The meat is mine.
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 // This class is accessed via the decode
00087 // functions of class JB2Image
00088 
00089 
00090 //**** Class JB2Codec
00091 // This class implements the JB2 decoder.
00092 // Contains all contextual information for decoding a JB2Image.
00093 
00094 class JB2Dict::JB2Codec::Decode : public JB2Dict::JB2Codec
00095 {
00096 public:
00097   Decode(void);
00098   void init(const GP<ByteStream> &gbs);
00099 // virtual
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 // virtual
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   // Make sure that inherited bitmaps are marked as shared
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 // STATIC DATA MEMBERS
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 // CONSTRUCTOR
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   // Initialize numcoder
00412   bitcells[0] = 0; // dummy cell
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 // CODE NUMBERS
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   // Check
00473   if (!pctx || ((int)*pctx >= cur_ncell))
00474     G_THROW( ERR_MSG("JB2Image.bad_numcontext") );
00475   // Start all phases
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       // encode
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       // context for new bit
00500       pctx = decision?(&rightcell[*pctx]):(&leftcell[*pctx]);
00501       // phase dependent part
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 // CODE COMMENTS
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 // LIBRARY
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 // CODE SIMPLE VALUES
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 // HANDLE SHORT LIST
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 // CODE PAIRS
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           // Call callback function to obtain dictionary
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   // Check start record
00714   if (!gotstartrecordp)
00715     G_THROW( ERR_MSG("JB2Image.no_start") );
00716   // Find location
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   // Code offset type
00727   int new_row=CodeBit((left<last_left), offset_type_dist);
00728   if (new_row)
00729     {
00730       // Begin a new row
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       // Same row
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   // Store in blit record
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   // Check start record
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 // CODE BITMAP DIRECTLY
00807 
00808 void 
00809 JB2Dict::JB2Codec::code_bitmap_directly (GBitmap &bm)
00810 {
00811   // Make sure bitmap will not be disturbed
00812   GMonitorLock lock(bm.monitor());
00813   // ensure borders are adequate
00814   bm.minborder(3);
00815   // initialize row pointers
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       // iterate on rows (decoding)      
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           // next row
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 // CODE BITMAP BY CROSS CODING
00852 
00853 void 
00854 JB2Dict::JB2Codec::code_bitmap_by_cross_coding (GBitmap &bm, GP<GBitmap> &cbm, const int libno)
00855 {
00856   // Make sure bitmaps will not be disturbed
00857   GP<GBitmap> copycbm=GBitmap::create();
00858   if (cbm->monitor())
00859     {
00860       // Perform a copy when the bitmap is explicitely shared
00861       GMonitorLock lock2(cbm->monitor());
00862       copycbm->init(*cbm);
00863       cbm = copycbm;
00864     }
00865   GMonitorLock lock1(bm.monitor());
00866   // Center bitmaps
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   // Ensure borders are adequate
00874   bm.minborder(2);
00875   cbm->minborder(2-xd2c);
00876   cbm->minborder(2+dw+xd2c-cw);
00877   // Initialize row pointers
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       // iterate on rows (decoding)      
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           // next row
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 // CODE JB2DICT RECORD
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   // Code record type
00933   code_record_type(rectype);
00934   
00935   // Pre-coding actions
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   // Coding actions
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       // Indicates need for a shape dictionary
01007           if(!gjim)
01008           {
01009              G_THROW( ERR_MSG("JB2Image.bad_number") );
01010           }
01011       code_inherited_shape_count(*gjim);
01012         }else
01013       // Reset all numerical contexts to zero
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   // Post-coding action
01027   if (!encoding)
01028     {
01029       // add shape to dictionary
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       // make sure everything is compacted
01046       // decompaction will occur automatically when needed
01047       if (bm)
01048         bm->compress();
01049     }
01050 }
01051 
01052 
01053 // CODE JB2DICT
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       // THIS IS THE DECODING PART
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 // CODE JB2IMAGE RECORD
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   // Code record type
01092   code_record_type(rectype);
01093   
01094   // Pre-coding actions
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   // Coding actions
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       // Indicates need for a shape dictionary
01252       code_inherited_shape_count(jim);
01253     else
01254       // Reset all numerical contexts to zero
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   // Post-coding action
01269   if (!encoding)
01270     {
01271       // add shape to image
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       // add shape to library
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       // make sure everything is compacted
01308       // decompaction will occur automatically on cross-coding bitmaps
01309       if (bm)
01310         bm->compress();
01311       // add blit to image
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 // CODE JB2IMAGE
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       // THIS IS THE DECODING PART
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   // First lock the stuff.
01368   GMonitorLock lock(bm.monitor());
01369   // Get size
01370   const int w = bm.columns();
01371   const int h = bm.rows();
01372   const int s = bm.rowsize();
01373   // Right border
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   // Top border
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   // Left border
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   // Bottom border
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

kviewshell

Skip menu "kviewshell"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • kviewshell
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal