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 #ifndef _JB2IMAGE_H
00058 #define _JB2IMAGE_H
00059 #ifdef HAVE_CONFIG_H
00060 #include "config.h"
00061 #endif
00062 #if NEED_GNUG_PRAGMAS
00063 # pragma interface
00064 #endif
00065
00172
00173
00174 #include "GString.h"
00175 #include "ZPCodec.h"
00176
00177
00178 #ifdef HAVE_NAMESPACES
00179 namespace DJVU {
00180 # ifdef NOT_DEFINED // Just to fool emacs c++ mode
00181 }
00182 #endif
00183 #endif
00184
00185 class JB2Dict;
00186 class JB2Image;
00187 class GRect;
00188 class GBitmap;
00189 class ByteStream;
00190
00198 class JB2Blit {
00199 public:
00201 unsigned short left;
00203 unsigned short bottom;
00205 unsigned int shapeno;
00206 };
00207
00208
00215 class JB2Shape
00216 {
00217 public:
00225 int parent;
00230 GP<GBitmap> bits;
00234 long userdata;
00235 };
00236
00237
00238
00245 typedef GP<JB2Dict> JB2DecoderCallback ( void* );
00246
00247
00250 class JB2Dict : public GPEnabled
00251 {
00252 protected:
00253 JB2Dict(void);
00254 public:
00255 class JB2Codec;
00256
00257
00261 static GP<JB2Dict> create(void);
00262
00263
00266 void init(void);
00267
00268
00270 GP<JB2Dict> get_inherited_dict(void) const;
00272 int get_inherited_shape_count(void) const;
00274 void set_inherited_dict(const GP<JB2Dict> &dict);
00275
00276
00279 int get_shape_count(void) const;
00283 JB2Shape &get_shape(const int shapeno);
00287 const JB2Shape &get_shape(const int shapeno) const;
00292 int add_shape(const JB2Shape &shape);
00293
00294
00300 void compress(void);
00303 unsigned int get_memory_usage(void) const;
00304
00305
00308 void encode(const GP<ByteStream> &gbs) const;
00317 void decode(const GP<ByteStream> &gbs, JB2DecoderCallback *cb=0, void *arg=0);
00318
00319
00320 public:
00322 GUTF8String comment;
00323
00324 private:
00325 int inherited_shapes;
00326 GP<JB2Dict> inherited_dict;
00327 GArray<JB2Shape> shapes;
00328
00329 };
00330
00338 class JB2Image : public JB2Dict
00339 {
00340 protected:
00341 JB2Image(void);
00342 public:
00343
00348 static GP<JB2Image> create(void) { return new JB2Image(); }
00349
00350
00353 void init(void);
00354
00355
00358 int get_width(void) const;
00361 int get_height(void) const;
00366 void set_dimension(int width, int height);
00367
00368
00377 GP<GBitmap> get_bitmap(int subsample = 1, int align = 1) const;
00385 GP<GBitmap> get_bitmap(const GRect &rect, int subsample=1, int align=1, int dispy=0) const;
00386
00387
00390 int get_blit_count(void) const;
00394 JB2Blit *get_blit(int blitno);
00398 const JB2Blit *get_blit(int blitno) const;
00403 int add_blit(const JB2Blit &blit);
00404
00405
00408 unsigned int get_memory_usage(void) const;
00409
00410
00413 void encode(const GP<ByteStream> &gbs) const;
00422 void decode(const GP<ByteStream> &gbs, JB2DecoderCallback *cb=0, void *arg=0);
00423
00424 private:
00425
00426 int width;
00427 int height;
00428 GTArray<JB2Blit> blits;
00429 public:
00433 bool reproduce_old_bug;
00434 };
00435
00436
00437
00438
00439
00440 inline int
00441 JB2Dict::get_shape_count(void) const
00442 {
00443 return inherited_shapes + shapes.size();
00444 }
00445
00446 inline int
00447 JB2Dict::get_inherited_shape_count(void) const
00448 {
00449 return inherited_shapes;
00450 }
00451
00452 inline GP<JB2Dict>
00453 JB2Dict::get_inherited_dict(void) const
00454 {
00455 return inherited_dict;
00456 }
00457
00458
00459
00460 inline int
00461 JB2Image::get_width(void) const
00462 {
00463 return width;
00464 }
00465
00466 inline int
00467 JB2Image::get_height(void) const
00468 {
00469 return height;
00470 }
00471
00472
00473 inline int
00474 JB2Image::get_blit_count(void) const
00475 {
00476 return blits.size();
00477 }
00478
00479
00480 inline JB2Blit *
00481 JB2Image::get_blit(int blitno)
00482 {
00483 return & blits[blitno];
00484 }
00485
00486 inline const JB2Blit *
00487 JB2Image::get_blit(int blitno) const
00488 {
00489 return & blits[blitno];
00490 }
00491
00492
00493
00494
00495
00578
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592 class JB2Dict::JB2Codec
00593 {
00594 public:
00595 class Decode;
00596 class Encode;
00597 typedef unsigned int NumContext;
00598 struct LibRect
00599 {
00600 int top,left,right,bottom;
00601 void compute_bounding_box(const GBitmap &cbm);
00602 };
00603 virtual ~JB2Codec();
00604 protected:
00605
00606 JB2Codec(const bool xencoding=false);
00607
00608 JB2Codec(const JB2Codec &ref);
00609 JB2Codec& operator=(const JB2Codec &ref);
00610
00611 int CodeNum(int lo, int hi, NumContext *pctx,int v);
00612 void reset_numcoder(void);
00613 inline void code_eventual_lossless_refinement(void);
00614 void init_library(JB2Dict &jim);
00615 int add_library(const int shapeno, JB2Shape &jshp);
00616 void code_relative_location(JB2Blit *jblt, int rows, int columns);
00617 void code_bitmap_directly (GBitmap &bm);
00618 void code_bitmap_by_cross_coding (GBitmap &bm, GP<GBitmap> &cbm, const int libno);
00619 void code_record(int &rectype, const GP<JB2Dict> &jim, JB2Shape *jshp);
00620 void code_record(int &rectype, const GP<JB2Image> &jim, JB2Shape *jshp, JB2Blit *jblt);
00621 static void compute_bounding_box(GBitmap &cbm, LibRect &lrect);
00622 static int get_direct_context( unsigned char const * const up2,
00623 unsigned char const * const up1, unsigned char const * const up0,
00624 const int column);
00625 static int shift_direct_context ( const int context,
00626 const int next, unsigned char const * const up2,
00627 unsigned char const * const up1, unsigned char const * const up0,
00628 const int column);
00629 static int get_cross_context( unsigned char const * const up1,
00630 unsigned char const * const up0, unsigned char const * const xup1,
00631 unsigned char const * const xup0, unsigned char const * const xdn1,
00632 const int column );
00633 static int shift_cross_context( const int context,
00634 const int n, unsigned char const * const up1,
00635 unsigned char const * const up0, unsigned char const * const xup1,
00636 unsigned char const * const xup0, unsigned char const * const xdn1,
00637 const int column );
00638
00639 virtual bool CodeBit(const bool bit, BitContext &ctx) = 0;
00640 virtual void code_comment(GUTF8String &comment) = 0;
00641 virtual void code_record_type(int &rectype) = 0;
00642 virtual int code_match_index(int &index, JB2Dict &jim)=0;
00643 virtual void code_inherited_shape_count(JB2Dict &jim)=0;
00644 virtual void code_image_size(JB2Dict &jim);
00645 virtual void code_image_size(JB2Image &jim);
00646 virtual void code_absolute_location(JB2Blit *jblt, int rows, int columns)=0;
00647 virtual void code_absolute_mark_size(GBitmap &bm, int border=0) = 0;
00648 virtual void code_relative_mark_size(GBitmap &bm, int cw, int ch, int border=0) = 0;
00649 virtual void code_bitmap_directly(GBitmap &bm,const int dw, int dy,
00650 unsigned char *up2, unsigned char *up1, unsigned char *up0 )=0;
00651 virtual void code_bitmap_by_cross_coding (GBitmap &bm, GBitmap &cbm,
00652 const int xd2c, const int dw, int dy, int cy,
00653 unsigned char *up1, unsigned char *up0, unsigned char *xup1,
00654 unsigned char *xup0, unsigned char *xdn1 )=0;
00655
00656 virtual int get_diff(const int x_diff,NumContext &rel_loc) = 0;
00657
00658 private:
00659 bool encoding;
00660
00661 protected:
00662
00663 int cur_ncell;
00664 BitContext *bitcells;
00665 GPBuffer<BitContext> gbitcells;
00666 NumContext *leftcell;
00667 GPBuffer<NumContext> gleftcell;
00668 NumContext *rightcell;
00669 GPBuffer<NumContext> grightcell;
00670
00671 bool refinementp;
00672 char gotstartrecordp;
00673
00674 NumContext dist_comment_byte;
00675 NumContext dist_comment_length;
00676
00677 NumContext dist_record_type;
00678 NumContext dist_match_index;
00679 BitContext dist_refinement_flag;
00680
00681 GTArray<int> shape2lib;
00682 GTArray<int> lib2shape;
00683 GTArray<LibRect> libinfo;
00684
00685 NumContext abs_loc_x;
00686 NumContext abs_loc_y;
00687 NumContext abs_size_x;
00688 NumContext abs_size_y;
00689 NumContext image_size_dist;
00690 NumContext inherited_shape_count_dist;
00691 BitContext offset_type_dist;
00692 NumContext rel_loc_x_current;
00693 NumContext rel_loc_x_last;
00694 NumContext rel_loc_y_current;
00695 NumContext rel_loc_y_last;
00696 NumContext rel_size_x;
00697 NumContext rel_size_y;
00698 int last_bottom;
00699 int last_left;
00700 int last_right;
00701 int last_row_bottom;
00702 int last_row_left;
00703 int image_columns;
00704 int image_rows;
00705 int short_list[3];
00706 int short_list_pos;
00707 inline void fill_short_list(const int v);
00708 int update_short_list(const int v);
00709
00710 BitContext bitdist[1024];
00711 BitContext cbitdist[2048];
00712 };
00713
00714 inline void
00715 JB2Dict::JB2Codec::code_eventual_lossless_refinement(void)
00716 {
00717 refinementp=CodeBit(refinementp, dist_refinement_flag);
00718 }
00719
00720 inline void
00721 JB2Dict::JB2Codec::fill_short_list(const int v)
00722 {
00723 short_list[0] = short_list[1] = short_list[2] = v;
00724 short_list_pos = 0;
00725 }
00726
00727 inline int
00728 JB2Dict::JB2Codec::get_direct_context( unsigned char const * const up2,
00729 unsigned char const * const up1,
00730 unsigned char const * const up0,
00731 const int column)
00732 {
00733 return ( (up2[column - 1] << 9) |
00734 (up2[column ] << 8) |
00735 (up2[column + 1] << 7) |
00736 (up1[column - 2] << 6) |
00737 (up1[column - 1] << 5) |
00738 (up1[column ] << 4) |
00739 (up1[column + 1] << 3) |
00740 (up1[column + 2] << 2) |
00741 (up0[column - 2] << 1) |
00742 (up0[column - 1] << 0) );
00743 }
00744
00745 inline int
00746 JB2Dict::JB2Codec::shift_direct_context(const int context, const int next,
00747 unsigned char const * const up2,
00748 unsigned char const * const up1,
00749 unsigned char const * const up0,
00750 const int column)
00751 {
00752 return ( ((context << 1) & 0x37a) |
00753 (up1[column + 2] << 2) |
00754 (up2[column + 1] << 7) |
00755 (next << 0) );
00756 }
00757
00758 inline int
00759 JB2Dict::JB2Codec::get_cross_context( unsigned char const * const up1,
00760 unsigned char const * const up0,
00761 unsigned char const * const xup1,
00762 unsigned char const * const xup0,
00763 unsigned char const * const xdn1,
00764 const int column )
00765 {
00766 return ( ( up1[column - 1] << 10) |
00767 ( up1[column ] << 9) |
00768 ( up1[column + 1] << 8) |
00769 ( up0[column - 1] << 7) |
00770 (xup1[column ] << 6) |
00771 (xup0[column - 1] << 5) |
00772 (xup0[column ] << 4) |
00773 (xup0[column + 1] << 3) |
00774 (xdn1[column - 1] << 2) |
00775 (xdn1[column ] << 1) |
00776 (xdn1[column + 1] << 0) );
00777 }
00778
00779 inline int
00780 JB2Dict::JB2Codec::shift_cross_context( const int context, const int n,
00781 unsigned char const * const up1,
00782 unsigned char const * const up0,
00783 unsigned char const * const xup1,
00784 unsigned char const * const xup0,
00785 unsigned char const * const xdn1,
00786 const int column )
00787 {
00788 return ( ((context<<1) & 0x636) |
00789 ( up1[column + 1] << 8) |
00790 (xup1[column ] << 6) |
00791 (xup0[column + 1] << 3) |
00792 (xdn1[column + 1] << 0) |
00793 (n << 7) );
00794 }
00795
00796
00797
00798 #ifdef HAVE_NAMESPACES
00799 }
00800 # ifndef NOT_USING_DJVU_NAMESPACE
00801 using namespace DJVU;
00802 # endif
00803 #endif
00804 #endif
00805