source: trunk/libdjvu/JB2Image.cpp @ 136

Last change on this file since 136 was 17, checked in by Eugene Romanenko, 16 years ago

update makefiles, remove absolute paths, update djvulibre to version 3.5.17

File size: 37.2 KB
Line 
1//C-  -*- C++ -*-
2//C- -------------------------------------------------------------------
3//C- DjVuLibre-3.5
4//C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
5//C- Copyright (c) 2001  AT&T
6//C-
7//C- This software is subject to, and may be distributed under, the
8//C- GNU General Public License, Version 2. The license should have
9//C- accompanied the software or you may obtain a copy of the license
10//C- from the Free Software Foundation at http://www.fsf.org .
11//C-
12//C- This program is distributed in the hope that it will be useful,
13//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
14//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15//C- GNU General Public License for more details.
16//C-
17//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library
18//C- distributed by Lizardtech Software.  On July 19th 2002, Lizardtech
19//C- Software authorized us to replace the original DjVu(r) Reference
20//C- Library notice by the following text (see doc/lizard2002.djvu):
21//C-
22//C-  ------------------------------------------------------------------
23//C- | DjVu (r) Reference Library (v. 3.5)
24//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
25//C- | The DjVu Reference Library is protected by U.S. Pat. No.
26//C- | 6,058,214 and patents pending.
27//C- |
28//C- | This software is subject to, and may be distributed under, the
29//C- | GNU General Public License, Version 2. The license should have
30//C- | accompanied the software or you may obtain a copy of the license
31//C- | from the Free Software Foundation at http://www.fsf.org .
32//C- |
33//C- | The computer code originally released by LizardTech under this
34//C- | license and unmodified by other parties is deemed "the LIZARDTECH
35//C- | ORIGINAL CODE."  Subject to any third party intellectual property
36//C- | claims, LizardTech grants recipient a worldwide, royalty-free,
37//C- | non-exclusive license to make, use, sell, or otherwise dispose of
38//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the
39//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU
40//C- | General Public License.   This grant only confers the right to
41//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to
42//C- | the extent such infringement is reasonably necessary to enable
43//C- | recipient to make, have made, practice, sell, or otherwise dispose
44//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to
45//C- | any greater extent that may be necessary to utilize further
46//C- | modifications or combinations.
47//C- |
48//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
49//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
50//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
51//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
52//C- +------------------------------------------------------------------
53//
54// $Id: JB2Image.cpp,v 1.10 2004/04/17 23:56:11 leonb Exp $
55// $Name:  $
56
57#ifdef HAVE_CONFIG_H
58# include "config.h"
59#endif
60#if NEED_GNUG_PRAGMAS
61# pragma implementation
62#endif
63
64// From: Leon Bottou, 1/31/2002
65// Lizardtech has split the corresponding cpp file into a decoder and an encoder.
66// Only superficial changes.  The meat is mine.
67
68#include "JB2Image.h"
69#include "GThreads.h"
70#include "GRect.h"
71#include "GBitmap.h"
72#include <string.h>
73
74
75#ifdef HAVE_NAMESPACES
76namespace DJVU {
77# ifdef NOT_DEFINED // Just to fool emacs c++ mode
78}
79#endif
80#endif
81
82////////////////////////////////////////
83//// CLASS JB2Codec::Decode:  DECLARATION
84////////////////////////////////////////
85
86// This class is accessed via the decode
87// functions of class JB2Image
88
89
90//**** Class JB2Codec
91// This class implements the JB2 decoder.
92// Contains all contextual information for decoding a JB2Image.
93
94class JB2Dict::JB2Codec::Decode : public JB2Dict::JB2Codec
95{
96public:
97  Decode(void);
98  void init(const GP<ByteStream> &gbs);
99// virtual
100  void code(const GP<JB2Image> &jim);
101  void code(JB2Image *jim) {const GP<JB2Image> gjim(jim);code(gjim);}
102  void code(const GP<JB2Dict> &jim);
103  void code(JB2Dict *jim) {const GP<JB2Dict> gjim(jim);code(gjim);}
104  void set_dict_callback(JB2DecoderCallback *cb, void *arg);
105protected:
106  int CodeNum(const int lo, const int hi, NumContext &ctx);
107
108// virtual
109  bool CodeBit(const bool bit, BitContext &ctx);
110  void code_comment(GUTF8String &comment);
111  void code_record_type(int &rectype);
112  int code_match_index(int &index, JB2Dict &jim);
113  void code_inherited_shape_count(JB2Dict &jim);
114  void code_image_size(JB2Dict &jim);
115  void code_image_size(JB2Image &jim);
116  void code_absolute_location(JB2Blit *jblt,  int rows, int columns);
117  void code_absolute_mark_size(GBitmap &bm, int border=0);
118  void code_relative_mark_size(GBitmap &bm, int cw, int ch, int border=0);
119  void code_bitmap_directly(GBitmap &bm,const int dw, int dy,
120    unsigned char *up2, unsigned char *up1, unsigned char *up0 );
121  void code_bitmap_by_cross_coding (GBitmap &bm, GBitmap &cbm,
122    const int xd2c, const int dw, int dy, int cy,
123    unsigned char *up1, unsigned char *up0, unsigned char *xup1, 
124    unsigned char *xup0, unsigned char *xdn1 );
125  int get_diff(const int x_diff,NumContext &rel_loc);
126
127private:
128  GP<ZPCodec> gzp;
129  JB2DecoderCallback *cbfunc;
130  void *cbarg;
131};
132
133////////////////////////////////////////
134//// CLASS JB2DICT: IMPLEMENTATION
135////////////////////////////////////////
136
137
138JB2Dict::JB2Dict()
139  : inherited_shapes(0)
140{
141}
142
143void
144JB2Dict::init()
145{
146  inherited_shapes = 0;
147  inherited_dict = 0;
148  shapes.empty();
149}
150
151JB2Shape &
152JB2Dict::get_shape(const int shapeno)
153{
154  JB2Shape *retval;
155  if(shapeno >= inherited_shapes)
156  {
157    retval=&shapes[shapeno - inherited_shapes];
158  }else if(inherited_dict)
159  {
160    retval=&(inherited_dict->get_shape(shapeno));
161  }else
162  {
163    G_THROW( ERR_MSG("JB2Image.bad_number") );
164  }
165  return *retval;
166}
167
168const JB2Shape &
169JB2Dict::get_shape(const int shapeno) const
170{
171  const JB2Shape *retval;
172  if(shapeno >= inherited_shapes)
173  {
174    retval=&shapes[shapeno - inherited_shapes];
175  }else if(inherited_dict)
176  {
177    retval=&(inherited_dict->get_shape(shapeno));
178  }else
179  {
180    G_THROW( ERR_MSG("JB2Image.bad_number") );
181  }
182  return *retval;
183}
184
185void 
186JB2Dict::set_inherited_dict(const GP<JB2Dict> &dict)
187{
188  if (shapes.size() > 0)
189    G_THROW( ERR_MSG("JB2Image.cant_set") );
190  if (inherited_dict)
191    G_THROW( ERR_MSG("JB2Image.cant_change") );
192  inherited_dict = dict; 
193  inherited_shapes = dict->get_shape_count();
194  // Make sure that inherited bitmaps are marked as shared
195  for (int i=0; i<inherited_shapes; i++)
196    {
197      JB2Shape &jshp = dict->get_shape(i);
198      if (jshp.bits) jshp.bits->share();
199    }
200}
201
202void
203JB2Dict::compress()
204{
205  for (int i=shapes.lbound(); i<=shapes.hbound(); i++)
206    shapes[i].bits->compress();
207}
208
209unsigned int
210JB2Dict::get_memory_usage() const
211{
212  unsigned int usage = sizeof(JB2Dict);
213  usage += sizeof(JB2Shape) * shapes.size();
214  for (int i=shapes.lbound(); i<=shapes.hbound(); i++)
215    if (shapes[i].bits)
216      usage += shapes[i].bits->get_memory_usage();
217  return usage;
218}
219
220int 
221JB2Dict::add_shape(const JB2Shape &shape)
222{
223  if (shape.parent >= get_shape_count())
224    G_THROW( ERR_MSG("JB2Image.bad_parent_shape") );
225  int index = shapes.size();
226  shapes.touch(index);
227  shapes[index] = shape;
228  return index + inherited_shapes;
229}
230
231void 
232JB2Dict::decode(const GP<ByteStream> &gbs, JB2DecoderCallback *cb, void *arg)
233{
234  init();
235  JB2Codec::Decode codec;
236  codec.init(gbs);
237  codec.set_dict_callback(cb,arg);
238  codec.code(this);
239}
240
241
242
243////////////////////////////////////////
244//// CLASS JB2IMAGE: IMPLEMENTATION
245////////////////////////////////////////
246
247
248JB2Image::JB2Image(void)
249  : width(0), height(0), reproduce_old_bug(false)
250{
251}
252
253void
254JB2Image::init(void)
255{
256  width = height = 0;
257  blits.empty();
258  JB2Dict::init();
259}
260
261unsigned int
262JB2Image::get_memory_usage() const
263{
264  unsigned int usage = JB2Dict::get_memory_usage();
265  usage += sizeof(JB2Image) - sizeof(JB2Dict);
266  usage += sizeof(JB2Blit) * blits.size();
267  return usage;
268}
269
270void 
271JB2Image::set_dimension(int awidth, int aheight)
272{
273  width = awidth;
274  height = aheight;
275}
276
277int 
278JB2Image::add_blit(const JB2Blit &blit)
279{
280  if (blit.shapeno >= (unsigned int)get_shape_count())
281    G_THROW( ERR_MSG("JB2Image.bad_shape") );
282  int index = blits.size();
283  blits.touch(index);
284  blits[index] = blit;
285  return index;
286}
287
288GP<GBitmap>
289JB2Image::get_bitmap(int subsample, int align) const
290{
291  if (width==0 || height==0)
292    G_THROW( ERR_MSG("JB2Image.cant_create") );
293  int swidth = (width + subsample - 1) / subsample;
294  int sheight = (height + subsample - 1) / subsample;
295  int border = ((swidth + align - 1) & ~(align - 1)) - swidth;
296  GP<GBitmap> bm = GBitmap::create(sheight, swidth, border);
297  bm->set_grays(1+subsample*subsample);
298  for (int blitno = 0; blitno < get_blit_count(); blitno++)
299    {
300      const JB2Blit *pblit = get_blit(blitno);
301      const JB2Shape  &pshape = get_shape(pblit->shapeno);
302      if (pshape.bits)
303        bm->blit(pshape.bits, pblit->left, pblit->bottom, subsample);
304    }
305  return bm;
306}
307
308GP<GBitmap>
309JB2Image::get_bitmap(const GRect &rect, int subsample, int align, int dispy) const
310{
311  if (width==0 || height==0)
312    G_THROW( ERR_MSG("JB2Image.cant_create") );
313  int rxmin = rect.xmin * subsample;
314  int rymin = rect.ymin * subsample;
315  int swidth = rect.width();
316  int sheight = rect.height();
317  int border = ((swidth + align - 1) & ~(align - 1)) - swidth;
318  GP<GBitmap> bm = GBitmap::create(sheight, swidth, border);
319  bm->set_grays(1+subsample*subsample);
320  for (int blitno = 0; blitno < get_blit_count(); blitno++)
321    {
322      const JB2Blit *pblit = get_blit(blitno);
323      const JB2Shape  &pshape = get_shape(pblit->shapeno);
324      if (pshape.bits)
325        bm->blit(pshape.bits, pblit->left-rxmin, pblit->bottom-rymin+dispy, subsample);
326    }
327  return bm;
328}
329
330void 
331JB2Image::decode(const GP<ByteStream> &gbs, JB2DecoderCallback *cb, void *arg)
332{
333  init();
334  JB2Codec::Decode codec;
335  codec.init(gbs);
336  codec.set_dict_callback(cb,arg);
337  codec.code(this);
338}
339
340
341
342////////////////////////////////////////
343//// CLASS JB2CODEC : IMPLEMENTATION
344////////////////////////////////////////
345
346
347
348#define START_OF_DATA                   (0)
349#define NEW_MARK                        (1)
350#define NEW_MARK_LIBRARY_ONLY           (2)
351#define NEW_MARK_IMAGE_ONLY             (3)
352#define MATCHED_REFINE                  (4)
353#define MATCHED_REFINE_LIBRARY_ONLY     (5)
354#define MATCHED_REFINE_IMAGE_ONLY       (6)
355#define MATCHED_COPY                    (7)
356#define NON_MARK_DATA                   (8)
357#define REQUIRED_DICT_OR_RESET          (9)
358#define PRESERVED_COMMENT               (10)
359#define END_OF_DATA                     (11)
360
361
362
363// STATIC DATA MEMBERS
364
365static const int BIGPOSITIVE = 262142;
366static const int BIGNEGATIVE = -262143;
367static const int CELLCHUNK = 20000;
368static const int CELLEXTRA =   500;
369
370
371// CONSTRUCTOR
372
373JB2Dict::JB2Codec::Decode::Decode(void)
374: JB2Dict::JB2Codec(0), cbfunc(0), cbarg(0) {}
375
376void
377JB2Dict::JB2Codec::Decode::init(const GP<ByteStream> &gbs)
378{
379  gzp=ZPCodec::create(gbs,false,true);
380}
381
382JB2Dict::JB2Codec::JB2Codec(const bool xencoding)
383  : encoding(xencoding),
384    cur_ncell(0),
385    gbitcells(bitcells,CELLCHUNK+CELLEXTRA),
386    gleftcell(leftcell,CELLCHUNK+CELLEXTRA),
387    grightcell(rightcell,CELLCHUNK+CELLEXTRA),
388    refinementp(false),
389    gotstartrecordp(0),
390    dist_comment_byte(0),
391    dist_comment_length(0),
392    dist_record_type(0),
393    dist_match_index(0),
394    dist_refinement_flag(0),
395    abs_loc_x(0),
396    abs_loc_y(0),
397    abs_size_x(0),
398    abs_size_y(0),
399    image_size_dist(0),
400    inherited_shape_count_dist(0),
401    offset_type_dist(0),
402    rel_loc_x_current(0),
403    rel_loc_x_last(0),
404    rel_loc_y_current(0),
405    rel_loc_y_last(0),
406    rel_size_x(0),
407    rel_size_y(0)
408{
409  memset(bitdist, 0, sizeof(bitdist));
410  memset(cbitdist, 0, sizeof(cbitdist));
411  // Initialize numcoder
412  bitcells[0] = 0; // dummy cell
413  leftcell[0] = rightcell[0] = 0;
414  cur_ncell = 1;
415}
416
417JB2Dict::JB2Codec::~JB2Codec() {}
418
419void 
420JB2Dict::JB2Codec::reset_numcoder()
421{
422  dist_comment_byte = 0;
423  dist_comment_length = 0;
424  dist_record_type = 0;
425  dist_match_index = 0;
426  abs_loc_x = 0;
427  abs_loc_y = 0;
428  abs_size_x = 0;
429  abs_size_y = 0;
430  image_size_dist = 0;
431  inherited_shape_count_dist = 0;
432  rel_loc_x_current = 0;
433  rel_loc_x_last = 0;
434  rel_loc_y_current = 0;
435  rel_loc_y_last = 0;
436  rel_size_x = 0;
437  rel_size_y = 0;
438  gbitcells.clear();
439  gleftcell.clear();
440  grightcell.clear();
441  cur_ncell = 1;
442}
443
444
445void 
446JB2Dict::JB2Codec::Decode::set_dict_callback(JB2DecoderCallback *cb, void *arg)
447{
448  cbfunc = cb;
449  cbarg = arg;
450}
451
452
453// CODE NUMBERS
454
455inline bool
456JB2Dict::JB2Codec::Decode::CodeBit(const bool, BitContext &ctx)
457{
458  return gzp->decoder(ctx)?true:false;
459}
460
461int
462JB2Dict::JB2Codec::Decode::CodeNum(int low, int high, NumContext &ctx)
463{
464  return JB2Codec::CodeNum(low,high,&ctx,0);
465}
466
467int
468JB2Dict::JB2Codec::CodeNum(int low, int high, NumContext *pctx, int v)
469{
470  bool negative=false;
471  int cutoff;
472  // Check
473  if (pctx && ((int)*pctx >= cur_ncell))
474    G_THROW( ERR_MSG("JB2Image.bad_numcontext") );
475  // Start all phases
476  cutoff = 0;
477  for(int phase=1,range=0xffffffff;range != 1;)
478    {
479      if (! *pctx)
480        {
481          const int max_ncell=gbitcells;
482          if (cur_ncell >= max_ncell)
483            {
484              const int nmax_ncell = max_ncell+CELLCHUNK;
485              gbitcells.resize(nmax_ncell);
486              gleftcell.resize(nmax_ncell);
487              grightcell.resize(nmax_ncell);
488            }
489          *pctx = cur_ncell ++;
490          bitcells[*pctx] = 0;
491          leftcell[*pctx] = rightcell[*pctx] = 0;
492        }
493      // encode
494      const bool decision = encoding
495        ? ((low < cutoff && high >= cutoff)
496          ? CodeBit((v>=cutoff),bitcells[*pctx])
497          : (v >= cutoff))
498        : ((low>=cutoff)||((high>=cutoff)&&CodeBit(false,bitcells[*pctx])));
499      // context for new bit
500      pctx = decision?(&rightcell[*pctx]):(&leftcell[*pctx]);
501      // phase dependent part
502      switch (phase) 
503        {
504        case 1:
505          negative = !decision;
506          if (negative) 
507            {
508              if (encoding)
509                v = - v - 1;
510              const int temp = - low - 1; 
511              low = - high - 1; 
512              high = temp;
513            }
514          phase = 2; cutoff =  1;
515          break;
516         
517        case 2:
518          if (!decision) 
519            {
520              phase = 3;
521              range = (cutoff + 1) / 2;
522              if (range == 1)
523                cutoff = 0;
524              else
525                cutoff -= range / 2;
526            }
527          else 
528            { 
529              cutoff += cutoff + 1; 
530            }
531          break;
532
533        case 3:
534          range /= 2;
535          if (range != 1) 
536            {
537              if (!decision)
538                cutoff -= range / 2;
539              else               
540                cutoff += range / 2;
541            }
542          else if (!decision) 
543            {
544                cutoff --;
545            }
546          break;
547        }
548    }
549    return (negative)?(- cutoff - 1):cutoff;
550}
551
552
553
554// CODE COMMENTS
555
556void 
557JB2Dict::JB2Codec::Decode::code_comment(GUTF8String &comment)
558{
559      int size=CodeNum(0, BIGPOSITIVE, dist_comment_length);
560      comment.empty();
561      char *combuf = comment.getbuf(size);
562      for (int i=0; i<size; i++) 
563        {
564          combuf[i]=CodeNum(0, 255, dist_comment_byte);
565        }
566      comment.getbuf();
567}
568
569
570// LIBRARY
571
572
573void
574JB2Dict::JB2Codec::init_library(JB2Dict &jim)
575{
576  int nshape = jim.get_inherited_shape_count();
577  shape2lib.resize(0,nshape-1);
578  lib2shape.resize(0,nshape-1);
579  libinfo.resize(0,nshape-1);
580  for (int i=0; i<nshape; i++)
581    {
582      shape2lib[i] = i;
583      lib2shape[i] = i;
584      JB2Shape &jshp = jim.get_shape(i);
585      libinfo[i].compute_bounding_box(*(jshp.bits));
586    }
587}
588
589int 
590JB2Dict::JB2Codec::add_library(const int shapeno, JB2Shape &jshp)
591{
592  const int libno = lib2shape.hbound() + 1;
593  lib2shape.touch(libno);
594  lib2shape[libno] = shapeno;
595  shape2lib.touch(shapeno);
596  shape2lib[shapeno] = libno;
597  libinfo.touch(libno);
598  libinfo[libno].compute_bounding_box(*(jshp.bits));
599  return libno;
600}
601
602
603// CODE SIMPLE VALUES
604
605inline void 
606JB2Dict::JB2Codec::Decode::code_record_type(int &rectype)
607{
608  rectype=CodeNum( START_OF_DATA, END_OF_DATA, dist_record_type);
609}
610
611int 
612JB2Dict::JB2Codec::Decode::code_match_index(int &index, JB2Dict &)
613{
614    int match=CodeNum(0, lib2shape.hbound(), dist_match_index);
615    index = lib2shape[match];
616    return match;
617}
618
619
620// HANDLE SHORT LIST
621
622int 
623JB2Dict::JB2Codec::update_short_list(const int v)
624{
625  if (++ short_list_pos == 3)
626    short_list_pos = 0;
627  int * const s = short_list;
628  s[short_list_pos] = v;
629
630  return (s[0] >= s[1])
631    ?((s[0] > s[2])?((s[1] >= s[2])?s[1]:s[2]):s[0])
632    :((s[0] < s[2])?((s[1] >= s[2])?s[2]:s[1]):s[0]);
633}
634
635
636
637// CODE PAIRS
638
639
640void
641JB2Dict::JB2Codec::Decode::code_inherited_shape_count(JB2Dict &jim)
642{
643  int size=CodeNum(0, BIGPOSITIVE, inherited_shape_count_dist);
644    {
645      GP<JB2Dict> dict = jim.get_inherited_dict();
646      if (!dict && size>0)
647        {
648          // Call callback function to obtain dictionary
649          if (cbfunc)
650            dict = (*cbfunc)(cbarg);
651          if (dict)
652            jim.set_inherited_dict(dict);
653        }
654      if (!dict && size>0)
655        G_THROW( ERR_MSG("JB2Image.need_dict") );
656      if (dict && size!=dict->get_shape_count())
657        G_THROW( ERR_MSG("JB2Image.bad_dict") );
658    }
659}
660
661void 
662JB2Dict::JB2Codec::Decode::code_image_size(JB2Dict &jim)
663{
664  int w=CodeNum(0, BIGPOSITIVE, image_size_dist);
665  int h=CodeNum(0, BIGPOSITIVE, image_size_dist);
666  if (w || h)
667    G_THROW( ERR_MSG("JB2Image.bad_dict2") );
668  JB2Codec::code_image_size(jim);
669}
670
671void 
672JB2Dict::JB2Codec::code_image_size(JB2Dict &)
673{
674  last_left = 1;
675  last_row_left = 0;
676  last_row_bottom = 0;
677  last_right = 0;
678  fill_short_list(last_row_bottom);
679  gotstartrecordp = 1;
680}
681
682void 
683JB2Dict::JB2Codec::Decode::code_image_size(JB2Image &jim)
684{
685  image_columns=CodeNum(0, BIGPOSITIVE, image_size_dist);
686  image_rows=CodeNum(0, BIGPOSITIVE, image_size_dist);
687  if (!image_columns || !image_rows)
688    G_THROW( ERR_MSG("JB2Image.zero_dim") );
689  jim.set_dimension(image_columns, image_rows);
690  JB2Codec::code_image_size(jim);
691}
692
693void 
694JB2Dict::JB2Codec::code_image_size(JB2Image &)
695{
696  last_left = 1 + image_columns;
697  last_row_left = 0;
698  last_row_bottom = image_rows;
699  last_right = 0;
700  fill_short_list(last_row_bottom);
701  gotstartrecordp = 1;
702}
703
704inline int
705JB2Dict::JB2Codec::Decode::get_diff(int,NumContext &rel_loc)
706{
707   return CodeNum(BIGNEGATIVE, BIGPOSITIVE, rel_loc);
708}
709
710void 
711JB2Dict::JB2Codec::code_relative_location(JB2Blit *jblt, int rows, int columns)
712{
713  // Check start record
714  if (!gotstartrecordp)
715    G_THROW( ERR_MSG("JB2Image.no_start") );
716  // Find location
717  int bottom=0, left=0, top=0, right=0;
718  int x_diff, y_diff;
719  if (encoding)
720    {
721      left = jblt->left + 1;
722      bottom = jblt->bottom + 1;
723      right = left + columns - 1;
724      top = bottom + rows - 1;
725    }
726  // Code offset type
727  int new_row=CodeBit((left<last_left), offset_type_dist);
728  if (new_row)
729    {
730      // Begin a new row
731      x_diff=get_diff(left-last_row_left,rel_loc_x_last);
732      y_diff=get_diff(top-last_row_bottom,rel_loc_y_last);
733      if (!encoding)
734        {
735          left = last_row_left + x_diff;
736          top = last_row_bottom + y_diff;
737          right = left + columns - 1;
738          bottom = top - rows + 1;
739        }
740      last_left = last_row_left = left;
741      last_right = right;
742      last_bottom = last_row_bottom = bottom;
743      fill_short_list(bottom);
744    }
745  else
746    {
747      // Same row
748      x_diff=get_diff(left-last_right,rel_loc_x_current);
749      y_diff=get_diff(bottom-last_bottom,rel_loc_y_current);
750      if (!encoding)
751        {
752          left = last_right + x_diff;
753          bottom = last_bottom + y_diff;
754          right = left + columns - 1;
755          top = bottom + rows - 1;
756        }
757      last_left = left;
758      last_right = right;
759      last_bottom = update_short_list(bottom);
760    }
761  // Store in blit record
762  if (!encoding)
763    {
764      jblt->bottom = bottom - 1;
765      jblt->left = left - 1;
766    }
767}
768
769void 
770JB2Dict::JB2Codec::Decode::code_absolute_location(JB2Blit *jblt, int rows, int columns)
771{
772  // Check start record
773  if (!gotstartrecordp)
774    G_THROW( ERR_MSG("JB2Image.no_start") );
775  int left=CodeNum(1, image_columns, abs_loc_x);
776  int top=CodeNum(1, image_rows, abs_loc_y);
777  jblt->bottom = top - rows + 1 - 1;
778  jblt->left = left - 1;
779}
780
781void 
782JB2Dict::JB2Codec::Decode::code_absolute_mark_size(GBitmap &bm, int border)
783{
784  int xsize=CodeNum(0, BIGPOSITIVE, abs_size_x);
785  int ysize=CodeNum(0, BIGPOSITIVE, abs_size_y);
786  if ((xsize!=(unsigned short)xsize) || (ysize!=(unsigned short)ysize))
787    G_THROW( ERR_MSG("JB2Image.bad_number") );
788  bm.init(ysize, xsize, border);
789}
790
791void 
792JB2Dict::JB2Codec::Decode::code_relative_mark_size(GBitmap &bm, int cw, int ch, int border)
793{
794  int xdiff=CodeNum(BIGNEGATIVE, BIGPOSITIVE, rel_size_x);
795  int ydiff=CodeNum(BIGNEGATIVE, BIGPOSITIVE, rel_size_y);
796  int xsize = cw + xdiff;
797  int ysize = ch + ydiff;
798  if ((xsize!=(unsigned short)xsize) || (ysize!=(unsigned short)ysize))
799    G_THROW( ERR_MSG("JB2Image.bad_number") );
800  bm.init(ysize, xsize, border);
801}
802
803
804
805
806// CODE BITMAP DIRECTLY
807
808void 
809JB2Dict::JB2Codec::code_bitmap_directly (GBitmap &bm)
810{
811  // Make sure bitmap will not be disturbed
812  GMonitorLock lock(bm.monitor());
813  // ensure borders are adequate
814  bm.minborder(3);
815  // initialize row pointers
816  int dy = bm.rows() - 1;
817  code_bitmap_directly(bm,bm.columns(),dy,bm[dy+2],bm[dy+1],bm[dy]);
818}
819
820void 
821JB2Dict::JB2Codec::Decode::code_bitmap_directly(
822  GBitmap &bm,const int dw, int dy,
823  unsigned char *up2, unsigned char *up1, unsigned char *up0 )
824{
825      ZPCodec &zp=*gzp;
826      // iterate on rows (decoding)     
827      while (dy >= 0)
828        {
829          int context=get_direct_context(up2, up1, up0, 0);
830          for(int dx=0;dx < dw;)
831            {
832              int n = zp.decoder(bitdist[context]);
833              up0[dx++] = n;
834              context=shift_direct_context(context, n, up2, up1, up0, dx);
835            }
836          // next row
837          dy -= 1;
838          up2 = up1;
839          up1 = up0;
840          up0 = bm[dy];
841        }
842#ifndef NDEBUG
843      bm.check_border();
844#endif
845}
846
847
848
849
850
851// CODE BITMAP BY CROSS CODING
852
853void 
854JB2Dict::JB2Codec::code_bitmap_by_cross_coding (GBitmap &bm, GP<GBitmap> &cbm, const int libno)
855{
856  // Make sure bitmaps will not be disturbed
857  GP<GBitmap> copycbm=GBitmap::create();
858  if (cbm->monitor())
859    {
860      // Perform a copy when the bitmap is explicitely shared
861      GMonitorLock lock2(cbm->monitor());
862      copycbm->init(*cbm);
863      cbm = copycbm;
864    }
865  GMonitorLock lock1(bm.monitor());
866  // Center bitmaps
867  const int cw = cbm->columns();
868  const int dw = bm.columns();
869  const int dh = bm.rows();
870  const LibRect &l = libinfo[libno];
871  const int xd2c = (dw/2 - dw + 1) - ((l.right - l.left + 1)/2 - l.right);
872  const int yd2c = (dh/2 - dh + 1) - ((l.top - l.bottom + 1)/2 - l.top);
873  // Ensure borders are adequate
874  bm.minborder(2);
875  cbm->minborder(2-xd2c);
876  cbm->minborder(2+dw+xd2c-cw);
877  // Initialize row pointers
878  const int dy = dh - 1;
879  const int cy = dy + yd2c;
880#ifndef NDEBUG
881  bm.check_border();
882  cbm->check_border();
883#endif
884  code_bitmap_by_cross_coding (bm,*cbm, xd2c, dw, dy, cy, bm[dy+1], bm[dy],
885    (*cbm)[cy+1] + xd2c, (*cbm)[cy  ] + xd2c, (*cbm)[cy-1] + xd2c);
886}
887
888void 
889JB2Dict::JB2Codec::Decode::code_bitmap_by_cross_coding (GBitmap &bm, GBitmap &cbm,
890  const int xd2c, const int dw, int dy, int cy,
891  unsigned char *up1, unsigned char *up0, unsigned char *xup1, 
892  unsigned char *xup0, unsigned char *xdn1 )
893{
894      ZPCodec &zp=*gzp;
895      // iterate on rows (decoding)     
896      while (dy >= 0)
897        {
898          int context=get_cross_context(
899                            up1, up0, xup1, xup0, xdn1, 0);
900          for(int dx=0;dx < dw;)
901            {
902              const int n = zp.decoder(cbitdist[context]);
903              up0[dx++] = n;
904              context=shift_cross_context(context, n, 
905                                  up1, up0, xup1, xup0, xdn1, dx);
906            }
907          // next row
908          up1 = up0;
909          up0 = bm[--dy];
910          xup1 = xup0;
911          xup0 = xdn1;
912          xdn1 = cbm[(--cy)-1] + xd2c;
913#ifndef NDEBUG
914          bm.check_border();
915#endif
916        }
917}
918
919
920
921
922// CODE JB2DICT RECORD
923
924void
925JB2Dict::JB2Codec::code_record(
926  int &rectype, const GP<JB2Dict> &gjim, JB2Shape *xjshp)
927{
928  GP<GBitmap> cbm;
929  GP<GBitmap> bm;
930  int shapeno = -1;
931
932  // Code record type
933  code_record_type(rectype);
934 
935  // Pre-coding actions
936  switch(rectype)
937    {
938    case NEW_MARK_LIBRARY_ONLY:
939    case MATCHED_REFINE_LIBRARY_ONLY:
940      {
941        if(!xjshp)
942        {
943          G_THROW( ERR_MSG("JB2Image.bad_number") );
944        }
945        JB2Shape &jshp=*xjshp;
946        if (!encoding) 
947        {
948          jshp.bits = GBitmap::create();
949          jshp.parent = -1;
950        }
951        bm = jshp.bits;
952        break;
953      }
954    }
955  // Coding actions
956  switch (rectype)
957    {
958    case START_OF_DATA:
959      {
960        if(!gjim)
961        {
962           G_THROW( ERR_MSG("JB2Image.bad_number") );
963        }
964        JB2Dict &jim=*gjim;
965        code_image_size (jim);
966        code_eventual_lossless_refinement ();
967        if (! encoding)
968          init_library(jim);
969        break;
970      }
971    case NEW_MARK_LIBRARY_ONLY:
972      {
973        code_absolute_mark_size (*bm, 4);
974        code_bitmap_directly (*bm);
975        break;
976      }
977    case MATCHED_REFINE_LIBRARY_ONLY:
978      {
979        if(!xjshp||!gjim)
980        {
981           G_THROW( ERR_MSG("JB2Image.bad_number") );
982        }
983        JB2Dict &jim=*gjim;
984        JB2Shape &jshp=*xjshp;
985        int match = code_match_index (jshp.parent, jim);
986        cbm = jim.get_shape(jshp.parent).bits;
987        LibRect &l = libinfo[match];
988        code_relative_mark_size (*bm, l.right-l.left+1, l.top-l.bottom+1, 4);
989        code_bitmap_by_cross_coding (*bm, cbm, jshp.parent);
990        break;
991      }
992    case PRESERVED_COMMENT:
993      {
994        if(!gjim)
995        {
996           G_THROW( ERR_MSG("JB2Image.bad_number") );
997        }
998        JB2Dict &jim=*gjim;
999        code_comment(jim.comment);
1000        break;
1001      }
1002    case REQUIRED_DICT_OR_RESET:
1003      {
1004        if (! gotstartrecordp)
1005        {
1006          // Indicates need for a shape dictionary
1007          if(!gjim)
1008          {
1009             G_THROW( ERR_MSG("JB2Image.bad_number") );
1010          }
1011          code_inherited_shape_count(*gjim);
1012        }else
1013          // Reset all numerical contexts to zero
1014          reset_numcoder();
1015        break;
1016      }
1017    case END_OF_DATA:
1018      {
1019        break;
1020      }
1021    default:
1022      {
1023        G_THROW( ERR_MSG("JB2Image.bad_type") );
1024      }
1025    }
1026  // Post-coding action
1027  if (!encoding)
1028    {
1029      // add shape to dictionary
1030      switch(rectype)
1031        {
1032        case NEW_MARK_LIBRARY_ONLY:
1033        case MATCHED_REFINE_LIBRARY_ONLY:
1034          {
1035            if(!xjshp||!gjim)
1036            {
1037               G_THROW( ERR_MSG("JB2Image.bad_number") );
1038            }
1039            JB2Shape &jshp=*xjshp;
1040            shapeno = gjim->add_shape(jshp);
1041            add_library(shapeno, jshp);
1042            break;
1043          }
1044        }
1045      // make sure everything is compacted
1046      // decompaction will occur automatically when needed
1047      if (bm)
1048        bm->compress();
1049    }
1050}
1051
1052
1053// CODE JB2DICT
1054
1055void 
1056JB2Dict::JB2Codec::Decode::code(const GP<JB2Dict> &gjim)
1057{
1058  if(!gjim)
1059  {
1060    G_THROW( ERR_MSG("JB2Image.bad_number") );
1061  }
1062  JB2Dict &jim=*gjim;
1063      // -------------------------
1064      // THIS IS THE DECODING PART
1065      // -------------------------
1066      int rectype;
1067      JB2Shape tmpshape;
1068      do
1069        {
1070          code_record(rectype, gjim, &tmpshape);       
1071        } 
1072      while(rectype != END_OF_DATA);
1073      if (!gotstartrecordp)
1074        G_THROW( ERR_MSG("JB2Image.no_start") );
1075      jim.compress();
1076}
1077
1078
1079
1080// CODE JB2IMAGE RECORD
1081
1082void
1083JB2Dict::JB2Codec::code_record(
1084  int &rectype, const GP<JB2Image> &gjim, JB2Shape *xjshp, JB2Blit *jblt)
1085{
1086  GP<GBitmap> bm;
1087  GP<GBitmap> cbm;
1088  int shapeno = -1;
1089  int match;
1090
1091  // Code record type
1092  code_record_type(rectype);
1093 
1094  // Pre-coding actions
1095  switch(rectype)
1096    {
1097    case NEW_MARK:
1098    case NEW_MARK_LIBRARY_ONLY:
1099    case NEW_MARK_IMAGE_ONLY:
1100    case MATCHED_REFINE:
1101    case MATCHED_REFINE_LIBRARY_ONLY:
1102    case MATCHED_REFINE_IMAGE_ONLY:
1103    case NON_MARK_DATA:
1104      {
1105        if(!xjshp)
1106        {
1107           G_THROW( ERR_MSG("JB2Image.bad_number") );
1108        }
1109        JB2Shape &jshp=*xjshp;
1110        if (!encoding) 
1111        {
1112          jshp.bits = GBitmap::create();
1113          jshp.parent = -1;
1114          if (rectype == NON_MARK_DATA)
1115            jshp.parent = -2;
1116        }
1117        bm = jshp.bits;
1118        break;
1119      }
1120    }
1121  // Coding actions
1122  switch (rectype)
1123    {
1124    case START_OF_DATA:
1125      {
1126        if(!gjim)
1127        {
1128           G_THROW( ERR_MSG("JB2Image.bad_number") );
1129        }
1130        JB2Image &jim=*gjim;
1131        code_image_size (jim);
1132        code_eventual_lossless_refinement ();
1133        if (! encoding)
1134          init_library(jim);
1135        break;
1136      }
1137    case NEW_MARK:
1138      {
1139        code_absolute_mark_size (*bm, 4);
1140        code_bitmap_directly (*bm);
1141        code_relative_location (jblt, bm->rows(), bm->columns() );
1142        break;
1143      }
1144    case NEW_MARK_LIBRARY_ONLY:
1145      {
1146        code_absolute_mark_size (*bm, 4);
1147        code_bitmap_directly (*bm);
1148        break;
1149      }
1150    case NEW_MARK_IMAGE_ONLY:
1151      {
1152        code_absolute_mark_size (*bm, 3);
1153        code_bitmap_directly (*bm);
1154        code_relative_location (jblt, bm->rows(), bm->columns() );
1155        break;
1156      }
1157    case MATCHED_REFINE:
1158      {
1159        if(!xjshp || !gjim)
1160        {
1161           G_THROW( ERR_MSG("JB2Image.bad_number") );
1162        }
1163        JB2Shape &jshp=*xjshp;
1164        JB2Image &jim=*gjim;
1165        match = code_match_index (jshp.parent, jim);
1166        cbm = jim.get_shape(jshp.parent).bits;
1167        LibRect &l = libinfo[match];
1168        code_relative_mark_size (*bm, l.right-l.left+1, l.top-l.bottom+1, 4); 
1169        code_bitmap_by_cross_coding (*bm, cbm, match);
1170        code_relative_location (jblt, bm->rows(), bm->columns() );
1171        break;
1172      }
1173    case MATCHED_REFINE_LIBRARY_ONLY:
1174      {
1175        if(!xjshp||!gjim)
1176        {
1177           G_THROW( ERR_MSG("JB2Image.bad_number") );
1178        }
1179        JB2Image &jim=*gjim;
1180        JB2Shape &jshp=*xjshp;
1181        match = code_match_index (jshp.parent, jim);
1182        cbm = jim.get_shape(jshp.parent).bits;
1183        LibRect &l = libinfo[match];
1184        code_relative_mark_size (*bm, l.right-l.left+1, l.top-l.bottom+1, 4);
1185        break;
1186      }
1187    case MATCHED_REFINE_IMAGE_ONLY:
1188      {
1189        if(!xjshp||!gjim)
1190        {
1191           G_THROW( ERR_MSG("JB2Image.bad_number") );
1192        }
1193        JB2Image &jim=*gjim;
1194        JB2Shape &jshp=*xjshp;
1195        match = code_match_index (jshp.parent, jim);
1196        cbm = jim.get_shape(jshp.parent).bits;
1197        LibRect &l = libinfo[match];
1198        code_relative_mark_size (*bm, l.right-l.left+1, l.top-l.bottom+1, 4);
1199        code_bitmap_by_cross_coding (*bm, cbm, match);
1200        code_relative_location (jblt, bm->rows(), bm->columns() );
1201        break;
1202      }
1203    case MATCHED_COPY:
1204      {
1205        int temp;
1206        if (encoding) temp = jblt->shapeno;
1207        if(!gjim)
1208        {
1209           G_THROW( ERR_MSG("JB2Image.bad_number") );
1210        }
1211        JB2Image &jim=*gjim;
1212        match = code_match_index (temp, jim);
1213        if (!encoding) jblt->shapeno = temp;
1214        bm = jim.get_shape(jblt->shapeno).bits;
1215        LibRect &l = libinfo[match];
1216        jblt->left += l.left;
1217        jblt->bottom += l.bottom;
1218        if (jim.reproduce_old_bug)
1219          code_relative_location (jblt, bm->rows(), bm->columns() );
1220        else
1221          code_relative_location (jblt, l.top-l.bottom+1, l.right-l.left+1 );
1222        jblt->left -= l.left;
1223        jblt->bottom -= l.bottom; 
1224        break;
1225      }
1226    case NON_MARK_DATA:
1227      {
1228        code_absolute_mark_size (*bm, 3);
1229        code_bitmap_directly (*bm);
1230        code_absolute_location (jblt, bm->rows(), bm->columns() );
1231        break;
1232      }
1233    case PRESERVED_COMMENT:
1234      {
1235        if(!gjim)
1236        {
1237           G_THROW( ERR_MSG("JB2Image.bad_number") );
1238        }
1239        JB2Image &jim=*gjim;
1240        code_comment(jim.comment);
1241        break;
1242      }
1243    case REQUIRED_DICT_OR_RESET:
1244      {
1245        if(!gjim)
1246        {
1247           G_THROW( ERR_MSG("JB2Image.bad_number") );
1248        }
1249        JB2Image &jim=*gjim;
1250        if (! gotstartrecordp)
1251          // Indicates need for a shape dictionary
1252          code_inherited_shape_count(jim);
1253        else
1254          // Reset all numerical contexts to zero
1255          reset_numcoder();
1256        break;
1257      }
1258    case END_OF_DATA:
1259      {
1260        break;
1261      }
1262    default:
1263      {
1264        G_THROW( ERR_MSG("JB2Image.unknown_type") );
1265      }
1266    }
1267 
1268  // Post-coding action
1269  if (!encoding)
1270    {
1271      // add shape to image
1272      switch(rectype)
1273        {
1274        case NEW_MARK:
1275        case NEW_MARK_LIBRARY_ONLY:
1276        case NEW_MARK_IMAGE_ONLY:
1277        case MATCHED_REFINE:
1278        case MATCHED_REFINE_LIBRARY_ONLY:
1279        case MATCHED_REFINE_IMAGE_ONLY:
1280        case NON_MARK_DATA:
1281          {
1282            if(!xjshp||!gjim)
1283            {
1284              G_THROW( ERR_MSG("JB2Image.bad_number") );
1285            }
1286            JB2Shape &jshp=*xjshp;
1287            shapeno = gjim->add_shape(jshp);
1288            shape2lib.touch(shapeno);
1289            shape2lib[shapeno] = -1;
1290            break;
1291          }
1292        }
1293      // add shape to library
1294      switch(rectype)
1295        {
1296        case NEW_MARK:
1297        case NEW_MARK_LIBRARY_ONLY:
1298        case MATCHED_REFINE:
1299        case MATCHED_REFINE_LIBRARY_ONLY:
1300          if(!xjshp)
1301          {
1302            G_THROW( ERR_MSG("JB2Image.bad_number") );
1303          }
1304          add_library(shapeno, *xjshp);
1305          break;
1306        }
1307      // make sure everything is compacted
1308      // decompaction will occur automatically on cross-coding bitmaps
1309      if (bm)
1310        bm->compress();
1311      // add blit to image
1312      switch (rectype)
1313        {
1314        case NEW_MARK:
1315        case NEW_MARK_IMAGE_ONLY:
1316        case MATCHED_REFINE:
1317        case MATCHED_REFINE_IMAGE_ONLY:
1318        case NON_MARK_DATA:
1319          jblt->shapeno = shapeno;
1320        case MATCHED_COPY:
1321          if(!gjim)
1322          {
1323            G_THROW( ERR_MSG("JB2Image.bad_number") );
1324          }
1325          gjim->add_blit(* jblt);
1326          break;
1327        }
1328    }
1329}
1330
1331
1332// CODE JB2IMAGE
1333
1334void 
1335JB2Dict::JB2Codec::Decode::code(const GP<JB2Image> &gjim)
1336{
1337  if(!gjim)
1338  {
1339    G_THROW( ERR_MSG("JB2Image.bad_number") );
1340  }
1341  JB2Image &jim=*gjim;
1342      // -------------------------
1343      // THIS IS THE DECODING PART
1344      // -------------------------
1345      int rectype;
1346      JB2Blit tmpblit;
1347      JB2Shape tmpshape;
1348      do
1349        {
1350          code_record(rectype, gjim, &tmpshape, &tmpblit);       
1351        } 
1352      while(rectype!=END_OF_DATA);
1353      if (!gotstartrecordp)
1354        G_THROW( ERR_MSG("JB2Image.no_start") );
1355      jim.compress();
1356}
1357
1358
1359
1360////////////////////////////////////////
1361//// HELPERS
1362////////////////////////////////////////
1363
1364void 
1365JB2Dict::JB2Codec::LibRect::compute_bounding_box(const GBitmap &bm)
1366{
1367  // First lock the stuff.
1368  GMonitorLock lock(bm.monitor());
1369  // Get size
1370  const int w = bm.columns();
1371  const int h = bm.rows();
1372  const int s = bm.rowsize();
1373  // Right border
1374  for(right=w-1;right >= 0;--right)
1375    {
1376      unsigned char const *p = bm[0] + right;
1377      unsigned char const * const pe = p+(s*h);
1378      for (;(p<pe)&&(!*p);p+=s)
1379        continue;
1380      if (p<pe)
1381        break;
1382    }
1383  // Top border
1384  for(top=h-1;top >= 0;--top)
1385    {
1386      unsigned char const *p = bm[top];
1387      unsigned char const * const pe = p+w;
1388      for (;(p<pe)&&(!*p); ++p)
1389        continue;
1390      if (p<pe)
1391        break;
1392    }
1393  // Left border
1394  for (left=0;left <= right;++left)
1395    {
1396      unsigned char const *p = bm[0] + left;
1397      unsigned char const * const pe=p+(s*h);
1398      for (;(p<pe)&&(!*p);p+=s)
1399        continue;
1400      if (p<pe)
1401        break;
1402    }
1403  // Bottom border
1404  for(bottom=0;bottom <= top;++bottom)
1405    {
1406      unsigned char const *p = bm[bottom];
1407      unsigned char const * const pe = p+w;
1408      for (;(p<pe)&&(!*p); ++p)
1409        continue;
1410      if (p<pe)
1411        break;
1412    }
1413}
1414
1415GP<JB2Dict>
1416JB2Dict::create(void)
1417{
1418  return new JB2Dict();
1419}
1420
1421
1422#ifdef HAVE_NAMESPACES
1423}
1424# ifndef NOT_USING_DJVU_NAMESPACE
1425using namespace DJVU;
1426# endif
1427#endif
Note: See TracBrowser for help on using the repository browser.