void ACLosslessScan::WriteMCU(struct Line **prev,struct Line **top)
{ 
#if ACCUSOFT_CODE
  UBYTE c;
  //
  // Parse a single MCU, which is now a group of pixels.
  for(c = 0;c < m_ucCount;c++) {
    struct QMContextSet &contextset = m_Context[m_ucContext[c]];
    struct Line *line = top[c];
    struct Line *pline= prev[c];
    UBYTE ym = m_ucMCUHeight[c];
    class PredictorBase *mcupred = m_pPredict[c];
    ULONG  x = m_ulX[c];
    LONG *lp = line->m_pData + x;
    LONG *pp = (pline)?(pline->m_pData + x):(NULL);
    //
    // Write MCUwidth * MCUheight coefficients starting at the line top.
    do {
      class PredictorBase *pred = mcupred;
      UBYTE xm = m_ucMCUWidth[c];
      do {
        // Decode now the difference between the predicted value and
        // the real value.
        LONG v = pred->EncodeSample(lp,pp);
        //
        // Get the sign coding context.
        struct QMContextSet::ContextZeroSet &zset = contextset.ClassifySignZero(m_plDa[c][ym-1],m_plDb[c][x],
                                                                                m_ucSmall[c],m_ucLarge[c]);
        // 
        if (v) {
          LONG sz;
          m_Coder.Put(zset.S0,true);
          //
          if (v < 0) {
            m_Coder.Put(zset.SS,true);
            sz = -(v + 1);
          } else {
            m_Coder.Put(zset.SS,false);
            sz =   v - 1;
          }
          //
          if (sz >= 1) {
            struct QMContextSet::MagnitudeSet &mset = contextset.ClassifyMagnitude(m_plDb[c][x],m_ucLarge[c]);
            int  i = 0;
            LONG m = 2;
            //
            m_Coder.Put((v > 0)?(zset.SP):(zset.SN),true);
            //
            while(sz >= m) {
              m_Coder.Put(mset.X[i],true);
              m <<= 1;
              i++;
            }
            m_Coder.Put(mset.X[i],false);
            //
            m >>= 1;
            while((m >>= 1)) {
              m_Coder.Put(mset.M[i],(m & sz)?(true):(false));
            }
          } else {
            m_Coder.Put((v > 0)?(zset.SP):(zset.SN),false);
          }
        } else {
          m_Coder.Put(zset.S0,false);
        }
        //
        // Update Da and Db.
        // Is this a bug? 32768 does not exist, but -32768 does. 
        // The reference streams use -32768, so let's stick to that.
        m_plDb[c][x]    = v;
        m_plDa[c][ym-1] = v;
        //
        // One pixel done. Proceed to the next in the MCU. Note that
        // the lines have been extended such that always a complete MCU is present.
      } while(--xm && (lp++,pp++,x++,pred = pred->MoveRight(),true));
      //
      // Go to the next line.
    } while(--ym && (pp = line->m_pData + (x = m_ulX[c]),line = (line->m_pNext)?(line->m_pNext):(line),
                     lp = line->m_pData + x,mcupred = mcupred->MoveDown(),true));
  }
#else
  NOREF(prev);
  NOREF(top);
#endif
}
void ACLosslessScan::WriteMCU(struct Line **prev,struct Line **top)
{ 
#if ACCUSOFT_CODE
  UBYTE c;
   
   
  for(c = 0;c < m_ucCount;c++) {
    struct QMContextSet &contextset = m_Context[m_ucContext[c]];
    struct Line *line = top[c];
    struct Line *pline= prev[c];
    UBYTE ym = m_ucMCUHeight[c];
    class PredictorBase *mcupred = m_pPredict[c];
    ULONG  x = m_ulX[c];
    LONG *lp = line->m_pData + x;
    LONG *pp = (pline)?(pline->m_pData + x):(NULL);
     
     
    do {
      class PredictorBase *pred = mcupred;
      UBYTE xm = m_ucMCUWidth[c];
      do {
         
         
        LONG v = pred->EncodeSample(lp,pp);
         
         
        struct QMContextSet::ContextZeroSet &zset = contextset.ClassifySignZero(m_plDa[c][ym-1],m_plDb[c][x],
                                                                                m_ucSmall[c],m_ucLarge[c]);
         
        if (v) {
          LONG sz;
          m_Coder.Put(zset.S0,true);
           
          if (v < 0) {
            m_Coder.Put(zset.SS,true);
            sz = -(v + 1);
          } else {
            m_Coder.Put(zset.SS,false);
            sz =   v - 1;
          }
           
          if (sz >= 1) {
            struct QMContextSet::MagnitudeSet &mset = contextset.ClassifyMagnitude(m_plDb[c][x],m_ucLarge[c]);
            int  i = 0;
            LONG m = 2;
             
            m_Coder.Put((v > 0)?(zset.SP):(zset.SN),true);
             
            while(sz >= m) {
              m_Coder.Put(mset.X[i],true);
              m <<= 1;
              i++;
            }
            m_Coder.Put(mset.X[i],false);
             
            m >>= 1;
            while((m >>= 1)) {
              m_Coder.Put(mset.M[i],(m & sz)?(true):(false));
            }
          } else {
            m_Coder.Put((v > 0)?(zset.SP):(zset.SN),false);
          }
        } else {
          m_Coder.Put(zset.S0,false);
        }
         
         
         
         
        m_plDb[c][x]    = v;
        m_plDa[c][ym-1] = v;
         
         
         
      } while(--xm && (lp++,pp++,x++,pred = pred->MoveRight(),true));
       
       
    } while(--ym && (pp = line->m_pData + (x = m_ulX[c]),line = (line->m_pNext)?(line->m_pNext):(line),
                     lp = line->m_pData + x,mcupred = mcupred->MoveDown(),true));
  }
#else
  NOREF(prev);
  NOREF(top);
#endif
}