source: trunk/libdjvu/JB2Image.cpp @ 269

Last change on this file since 269 was 206, checked in by Eugene Romanenko, 14 years ago

DJVU plugin: djvulibre updated to version 3.5.19

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