void 
JB2Dict::JB2Codec::Encode::code_bitmap_by_cross_coding (GBitmap &bm, GBitmap &cbm,
  const int xd2c, const int dw, int dy, int cy,
  unsigned char *up1, unsigned char *up0, unsigned char *xup1, 
  unsigned char *xup0, unsigned char *xdn1 )
{
      ZPCodec &zp=*gzp;
      // iterate on rows (encoding)
      while (dy >= 0)
        {
          int context=get_cross_context(up1, up0, xup1, xup0, xdn1, 0);
          for(int dx=0;dx < dw;)
            {
              const int n = up0[dx++];
              zp.encoder(n, cbitdist[context]);
              context=shift_cross_context(context, n,  
                                  up1, up0, xup1, xup0, xdn1, dx);
            }
          // next row
          up1 = up0;
          up0 = bm[--dy];
          xup1 = xup0;
          xup0 = xdn1;
          xdn1 = cbm[(--cy)-1] + xd2c;
        }
}
void 
JB2Dict::JB2Codec::Decode::code_bitmap_by_cross_coding (GBitmap &bm, GBitmap &cbm,
  const int xd2c, const int dw, int dy, int cy,
  unsigned char *up1, unsigned char *up0, unsigned char *xup1, 
  unsigned char *xup0, unsigned char *xdn1 )
{
      ZPCodec &zp=*gzp;
      // iterate on rows (decoding)      
      while (dy >= 0)
        {
          int context=get_cross_context(
                            up1, up0, xup1, xup0, xdn1, 0);
          for(int dx=0;dx < dw;)
            {
              const int n = zp.decoder(cbitdist[context]);
              up0[dx++] = n;
              context=shift_cross_context(context, n,  
                                  up1, up0, xup1, xup0, xdn1, dx);
            }
          // next row
          up1 = up0;
          up0 = bm[--dy];
          xup1 = xup0;
          xup0 = xdn1;
          xdn1 = cbm[(--cy)-1] + xd2c;
#ifndef NDEBUG
          bm.check_border();
#endif
        }
}