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

kviewshell

JB2EncodeCodec.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: JB2EncodeCodec.cpp,v 1.9 2003/11/07 22:08:22 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 #ifndef NEED_DECODER_ONLY
00069 
00070 #include "JB2Image.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 encode
00087 // functions of class JB2Image
00088 
00089 
00090 //**** Class JB2Codec
00091 // This class implements the JB2 coder.
00092 // Contains all contextual information for encoding a JB2Image.
00093 
00094 class JB2Dict::JB2Codec::Encode : public JB2Dict::JB2Codec
00095 {
00096 public:
00097   Encode(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 
00105 protected:
00106   void CodeNum(const int num, const int lo, const int hi, NumContext &ctx);
00107   void encode_libonly_shape(const GP<JB2Image> &jim, int shapeno);
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   int get_diff(const int x_diff,NumContext &rel_loc);
00122   void code_bitmap_by_cross_coding (GBitmap &bm, GBitmap &cbm,
00123     const int xd2c, const int dw, int dy, int cy,
00124     unsigned char *up1, unsigned char *up0, unsigned char *xup1, 
00125     unsigned char *xup0, unsigned char *xdn1 );
00126 
00127 private:
00128   GP<ZPCodec> gzp;
00129 };
00130 
00131 
00135 
00136 void 
00137 JB2Dict::encode(const GP<ByteStream> &gbs) const
00138 {
00139   JB2Codec::Encode codec;
00140   codec.init(gbs);
00141   codec.code(const_cast<JB2Dict *>(this));
00142 }
00143 
00147 
00148 void 
00149 JB2Image::encode(const GP<ByteStream> &gbs) const
00150 {
00151   JB2Codec::Encode codec;
00152   codec.init(gbs);
00153   codec.code(const_cast<JB2Image *>(this));
00154 }
00155 
00159 
00160 #define START_OF_DATA                   (0)
00161 #define NEW_MARK                        (1)
00162 #define NEW_MARK_LIBRARY_ONLY           (2)
00163 #define NEW_MARK_IMAGE_ONLY             (3)
00164 #define MATCHED_REFINE                  (4)
00165 #define MATCHED_REFINE_LIBRARY_ONLY     (5)
00166 #define MATCHED_REFINE_IMAGE_ONLY       (6)
00167 #define MATCHED_COPY                    (7)
00168 #define NON_MARK_DATA                   (8)
00169 #define REQUIRED_DICT_OR_RESET          (9)
00170 #define PRESERVED_COMMENT               (10)
00171 #define END_OF_DATA                     (11)
00172 
00173 // STATIC DATA MEMBERS
00174 
00175 static const int BIGPOSITIVE = 262142;
00176 static const int BIGNEGATIVE = -262143;
00177 static const int CELLCHUNK = 20000;
00178 static const int CELLEXTRA =   500;
00179 
00180 // CONSTRUCTOR
00181 
00182 JB2Dict::JB2Codec::Encode::Encode(void)
00183 : JB2Dict::JB2Codec(1) {}
00184 
00185 void
00186 JB2Dict::JB2Codec::Encode::init(const GP<ByteStream> &gbs)
00187 {
00188   gzp=ZPCodec::create(gbs,true,true);
00189 }
00190 
00191 inline bool
00192 JB2Dict::JB2Codec::Encode::CodeBit(const bool bit, BitContext &ctx)
00193 {
00194     gzp->encoder(bit?1:0, ctx);
00195     return bit;
00196 }
00197 
00198 void
00199 JB2Dict::JB2Codec::Encode::CodeNum(int num, int low, int high, NumContext &ctx)
00200 {
00201   if (num < low || num > high)
00202     G_THROW( ERR_MSG("JB2Image.bad_number") );
00203   JB2Codec::CodeNum(low,high,&ctx,num);
00204 }
00205 
00206 // CODE COMMENTS
00207 
00208 void 
00209 JB2Dict::JB2Codec::Encode::code_comment(GUTF8String &comment)
00210 {
00211   // Encode size
00212       int size=comment.length();
00213       CodeNum(size, 0, BIGPOSITIVE, dist_comment_length);
00214       for (int i=0; i<size; i++) 
00215         {
00216           CodeNum(comment[i], 0, 255, dist_comment_byte);
00217         }
00218 }
00219 
00220 // CODE SIMPLE VALUES
00221 
00222 inline void 
00223 JB2Dict::JB2Codec::Encode::code_record_type(int &rectype)
00224 {
00225   CodeNum(rectype, START_OF_DATA, END_OF_DATA, dist_record_type);
00226 }
00227 
00228 int 
00229 JB2Dict::JB2Codec::Encode::code_match_index(int &index, JB2Dict &jim)
00230 {
00231     int match=shape2lib[index];
00232     CodeNum(match, 0, lib2shape.hbound(), dist_match_index);
00233     return match;
00234 }
00235 
00236 // CODE PAIRS
00237 
00238 void
00239 JB2Dict::JB2Codec::Encode::code_inherited_shape_count(JB2Dict &jim)
00240 {
00241   CodeNum(jim.get_inherited_shape_count(),
00242     0, BIGPOSITIVE, inherited_shape_count_dist);
00243 }
00244 
00245 void 
00246 JB2Dict::JB2Codec::Encode::code_image_size(JB2Dict &jim)
00247 {
00248   CodeNum(0, 0, BIGPOSITIVE, image_size_dist);
00249   CodeNum(0, 0, BIGPOSITIVE, image_size_dist);
00250   JB2Codec::code_image_size(jim);
00251 }
00252 
00253 void 
00254 JB2Dict::JB2Codec::Encode::code_image_size(JB2Image &jim)
00255 {
00256   image_columns = jim.get_width();
00257   CodeNum(image_columns, 0, BIGPOSITIVE, image_size_dist);
00258   image_rows = jim.get_height();
00259   CodeNum(image_rows, 0, BIGPOSITIVE, image_size_dist);
00260   JB2Codec::code_image_size(jim);
00261 }
00262 
00263 inline int
00264 JB2Dict::JB2Codec::Encode::get_diff(int x_diff,NumContext &rel_loc)
00265 {
00266    CodeNum(x_diff, BIGNEGATIVE, BIGPOSITIVE, rel_loc);
00267    return x_diff;
00268 }
00269 
00270 void 
00271 JB2Dict::JB2Codec::Encode::code_absolute_location(JB2Blit *jblt, int rows, int columns)
00272 {
00273   // Check start record
00274   if (!gotstartrecordp)
00275     G_THROW( ERR_MSG("JB2Image.no_start") );
00276   // Code TOP and LEFT
00277   CodeNum(jblt->left+1, 1, image_columns, abs_loc_x);
00278   CodeNum(jblt->bottom+rows-1+1, 1, image_rows, abs_loc_y);
00279 }
00280 
00281 void 
00282 JB2Dict::JB2Codec::Encode::code_absolute_mark_size(GBitmap &bm, int border)
00283 {
00284   CodeNum(bm.columns(), 0, BIGPOSITIVE, abs_size_x);
00285   CodeNum(bm.rows(), 0, BIGPOSITIVE, abs_size_y);
00286 }
00287 
00288 void 
00289 JB2Dict::JB2Codec::Encode::code_relative_mark_size(GBitmap &bm, int cw, int ch, int border)
00290 {
00291   CodeNum(bm.columns()-cw, BIGNEGATIVE, BIGPOSITIVE, rel_size_x);
00292   CodeNum(bm.rows()-ch, BIGNEGATIVE, BIGPOSITIVE, rel_size_y);
00293 }
00294 
00295 // CODE BITMAP DIRECTLY
00296 
00297 void 
00298 JB2Dict::JB2Codec::Encode::code_bitmap_directly(
00299   GBitmap &bm,const int dw, int dy,
00300   unsigned char *up2, unsigned char *up1, unsigned char *up0 )
00301 {
00302       ZPCodec &zp=*gzp;
00303       // iterate on rows (encoding)
00304       while (dy >= 0)
00305         {
00306           int context=get_direct_context(up2, up1, up0, 0);
00307           for (int dx=0;dx < dw;)
00308             {
00309               int n = up0[dx++];
00310               zp.encoder(n, bitdist[context]);
00311               context=shift_direct_context(context, n, up2, up1, up0, dx);
00312             }
00313           // next row
00314           dy -= 1;
00315           up2 = up1;
00316           up1 = up0;
00317           up0 = bm[dy];
00318         }
00319 }
00320 
00321 // CODE BITMAP BY CROSS CODING
00322 
00323 void 
00324 JB2Dict::JB2Codec::Encode::code_bitmap_by_cross_coding (GBitmap &bm, GBitmap &cbm,
00325   const int xd2c, const int dw, int dy, int cy,
00326   unsigned char *up1, unsigned char *up0, unsigned char *xup1, 
00327   unsigned char *xup0, unsigned char *xdn1 )
00328 {
00329       ZPCodec &zp=*gzp;
00330       // iterate on rows (encoding)
00331       while (dy >= 0)
00332         {
00333           int context=get_cross_context(up1, up0, xup1, xup0, xdn1, 0);
00334           for(int dx=0;dx < dw;)
00335             {
00336               const int n = up0[dx++];
00337               zp.encoder(n, cbitdist[context]);
00338               context=shift_cross_context(context, n,  
00339                                   up1, up0, xup1, xup0, xdn1, dx);
00340             }
00341           // next row
00342           up1 = up0;
00343           up0 = bm[--dy];
00344           xup1 = xup0;
00345           xup0 = xdn1;
00346           xdn1 = cbm[(--cy)-1] + xd2c;
00347         }
00348 }
00349 
00350 // CODE JB2DICT
00351 
00352 void 
00353 JB2Dict::JB2Codec::Encode::code(const GP<JB2Dict> &gjim)
00354 {
00355   if(!gjim)
00356   {
00357     G_THROW( ERR_MSG("JB2Image.bad_number") );
00358   }
00359   JB2Dict &jim=*gjim;
00360       // -------------------------
00361       // THIS IS THE ENCODING PART
00362       // -------------------------
00363       int firstshape = jim.get_inherited_shape_count();
00364       int nshape = jim.get_shape_count();
00365       init_library(jim);
00366       // Code headers.
00367       int rectype = REQUIRED_DICT_OR_RESET;
00368       if (jim.get_inherited_shape_count() > 0)
00369         code_record(rectype, gjim, 0);
00370       rectype = START_OF_DATA;
00371       code_record(rectype, gjim, 0);
00372       // Code Comment.
00373       rectype = PRESERVED_COMMENT;
00374       if (!! jim.comment)
00375         code_record(rectype, gjim, 0);
00376       // Encode every shape
00377       int shapeno;
00378       DJVU_PROGRESS_TASK(jb2code,"jb2 encode", nshape-firstshape);
00379       for (shapeno=firstshape; shapeno<nshape; shapeno++)
00380         {
00381           DJVU_PROGRESS_RUN(jb2code, (shapeno-firstshape)|0xff);
00382           // Code shape
00383           JB2Shape &jshp = jim.get_shape(shapeno);
00384           rectype=(jshp.parent >= 0)
00385             ?MATCHED_REFINE_LIBRARY_ONLY:NEW_MARK_LIBRARY_ONLY;
00386           code_record(rectype, gjim, &jshp);
00387           add_library(shapeno, jshp);
00388       // Check numcoder status
00389       if (cur_ncell > CELLCHUNK) 
00390         {
00391           rectype = REQUIRED_DICT_OR_RESET;
00392           code_record(rectype, 0, 0);         
00393         }
00394         }
00395       // Code end of data record
00396       rectype = END_OF_DATA;
00397       code_record(rectype, gjim, 0); 
00398       gzp=0;
00399 }
00400 
00401 // CODE JB2IMAGE
00402 
00403 void 
00404 JB2Dict::JB2Codec::Encode::code(const GP<JB2Image> &gjim)
00405 {
00406   if(!gjim)
00407   {
00408     G_THROW( ERR_MSG("JB2Image.bad_number") );
00409   }
00410   JB2Image &jim=*gjim;
00411       // -------------------------
00412       // THIS IS THE ENCODING PART
00413       // -------------------------
00414       int i;
00415       init_library(jim);
00416       int firstshape = jim.get_inherited_shape_count();
00417       int nshape = jim.get_shape_count();
00418       int nblit = jim.get_blit_count();
00419       // Initialize shape2lib 
00420       shape2lib.resize(0,nshape-1);
00421       for (i=firstshape; i<nshape; i++)
00422         shape2lib[i] = -1;
00423       // Determine shapes that go into library (shapeno>=firstshape)
00424       //  shape2lib is -2 if used by one blit
00425       //  shape2lib is -3 if used by more than one blit
00426       //  shape2lib is -4 if used as a parent
00427       for (i=0; i<nblit; i++)
00428         {
00429           JB2Blit *jblt = jim.get_blit(i);
00430           int shapeno = jblt->shapeno;
00431           if (shapeno < firstshape)
00432             continue;
00433           if (shape2lib[shapeno] >= -2) 
00434             shape2lib[shapeno] -= 1;
00435           shapeno = jim.get_shape(shapeno).parent;
00436           while (shapeno>=firstshape && shape2lib[shapeno]>=-3)
00437             {
00438               shape2lib[shapeno] = -4;
00439               shapeno = jim.get_shape(shapeno).parent;
00440             }
00441         }
00442       // Code headers.
00443       int rectype = REQUIRED_DICT_OR_RESET;
00444       if (jim.get_inherited_shape_count() > 0)
00445         code_record(rectype, gjim, 0, 0);
00446       rectype = START_OF_DATA;
00447       code_record(rectype, gjim, 0, 0);
00448       // Code Comment.
00449       rectype = PRESERVED_COMMENT;
00450       if (!! jim.comment)
00451         code_record(rectype, gjim, 0, 0);
00452       // Encode every blit
00453       int blitno;
00454       DJVU_PROGRESS_TASK(jb2code,"jb2 encode", nblit);
00455       for (blitno=0; blitno<nblit; blitno++)
00456         {
00457           DJVU_PROGRESS_RUN(jb2code, blitno|0xff);
00458           JB2Blit *jblt = jim.get_blit(blitno);
00459           int shapeno = jblt->shapeno;
00460           JB2Shape &jshp = jim.get_shape(shapeno);
00461           // Tests if shape exists in library
00462           if (shape2lib[shapeno] >= 0)
00463             {
00464               int rectype = MATCHED_COPY;
00465               code_record(rectype, gjim, 0, jblt);
00466             }
00467           // Avoid coding null shapes/blits
00468           else if (jshp.bits) 
00469             {
00470               // Make sure all parents have been coded
00471               if (jshp.parent>=0 && shape2lib[jshp.parent]<0)
00472                 encode_libonly_shape(gjim, jshp.parent);
00473               // Allocate library entry when needed
00474 #define LIBRARY_CONTAINS_ALL
00475               int libraryp = 0;
00476 #ifdef LIBRARY_CONTAINS_MARKS // baseline
00477               if (jshp.parent >= -1)
00478                 libraryp = 1;
00479 #endif
00480 #ifdef LIBRARY_CONTAINS_SHARED // worse             
00481               if (shape2lib[shapeno] <= -3)
00482                 libraryp = 1;
00483 #endif
00484 #ifdef LIBRARY_CONTAINS_ALL // better
00485               libraryp = 1;
00486 #endif
00487               // Test all blit cases
00488               if (jshp.parent<-1 && !libraryp)
00489                 {
00490                   int rectype = NON_MARK_DATA;
00491                   code_record(rectype, gjim, &jshp, jblt);
00492                 }
00493               else if (jshp.parent < 0)
00494                 {
00495                   int rectype = (libraryp ? NEW_MARK : NEW_MARK_IMAGE_ONLY);
00496                   code_record(rectype, gjim, &jshp, jblt);
00497                 }
00498               else 
00499                 {
00500                   int rectype = (libraryp ? MATCHED_REFINE : MATCHED_REFINE_IMAGE_ONLY);
00501                   code_record(rectype, gjim, &jshp, jblt);
00502                 }
00503               // Add shape to library
00504               if (libraryp) 
00505                 add_library(shapeno, jshp);
00506             }
00507       // Check numcoder status
00508       if (cur_ncell > CELLCHUNK) 
00509         {
00510           rectype = REQUIRED_DICT_OR_RESET;
00511           code_record(rectype, 0, 0);
00512         }
00513         }
00514       // Code end of data record
00515       rectype = END_OF_DATA;
00516       code_record(rectype, gjim, 0, 0); 
00517       gzp=0;
00518 }
00519 
00523 
00524 void 
00525 JB2Dict::JB2Codec::Encode::encode_libonly_shape(
00526   const GP<JB2Image> &gjim, int shapeno )
00527 {
00528   if(!gjim)
00529   {
00530     G_THROW( ERR_MSG("JB2Image.bad_number") );
00531   }
00532   JB2Image &jim=*gjim;
00533   // Recursively encode parent shape
00534   JB2Shape &jshp = jim.get_shape(shapeno);
00535   if (jshp.parent>=0 && shape2lib[jshp.parent]<0)
00536     encode_libonly_shape(gjim, jshp.parent);
00537   // Test that library shape must be encoded
00538   if (shape2lib[shapeno] < 0)
00539     {
00540       // Code library entry
00541       int rectype=(jshp.parent >= 0)
00542             ?NEW_MARK_LIBRARY_ONLY:MATCHED_REFINE_LIBRARY_ONLY;
00543       code_record(rectype, gjim, &jshp, 0);      
00544       // Add shape to library
00545       add_library(shapeno, jshp);
00546       // Check numcoder status
00547       if (cur_ncell > CELLCHUNK) 
00548     {
00549       rectype = REQUIRED_DICT_OR_RESET;
00550       code_record(rectype, 0, 0);
00551     }
00552     }
00553 }
00554 
00555 
00556 #ifdef HAVE_NAMESPACES
00557 }
00558 # ifndef NOT_USING_DJVU_NAMESPACE
00559 using namespace DJVU;
00560 # endif
00561 #endif
00562 
00563 #endif /* NEED_DECODER_ONLY */
00564 

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