


#include "misc.h"

 
void ucharRemap(uchar *in, int length, uchar *map, uchar *out)
{
  int extras = length & 0xf;                 /* NOTE: unrolled 16 times */
  uchar *end = in  +  (length & ~0xf);

  
  if (out == NULL  ||  out == in) {          /* being done in place */
    while (in < end) {
      in[0]  = map[in[0]];   in[1]  = map[in[1]];
      in[2]  = map[in[2]];   in[3]  = map[in[3]];
      in[4]  = map[in[4]];   in[5]  = map[in[5]];
      in[6]  = map[in[6]];   in[7]  = map[in[7]];    
      in[8]  = map[in[8]];   in[9]  = map[in[9]];
      in[10] = map[in[10]];  in[11] = map[in[11]];
      in[12] = map[in[12]];  in[13] = map[in[13]];
      in[14] = map[in[14]];  in[15] = map[in[15]];

      in += 16;
    }

    end += extras;
    while (in < end) {
      *in = map[*in]; in++;
    }
  }
  else {
    while (in < end) {
      out[0]  = map[in[0]];   out[1]  = map[in[1]];
      out[2]  = map[in[2]];   out[3]  = map[in[3]];
      out[4]  = map[in[4]];   out[5]  = map[in[5]];
      out[6]  = map[in[6]];   out[7]  = map[in[7]];
      out[8]  = map[in[8]];   out[9]  = map[in[9]];
      out[10] = map[in[10]];  out[11] = map[in[11]];
      out[12] = map[in[12]];  out[13] = map[in[13]];
      out[14] = map[in[14]];  out[15] = map[in[15]];

      out += 16;
      in  += 16;
    }

    end += extras;
    while (in < end) {
      *(out++) = map[*(in++)];
    }
  }
}


extern void ucharRemapPred(uchar *in, int length, uchar *pred,
                           uchar *map, uchar *out)
{
  int extras = length & 0xf;                 /* NOTE: unrolled 16 times */
  uchar *end = in  +  (length & ~0xf);

  
  if (out == NULL  ||  out == in) {          /* being done in place */
    while (in < end) {
      if (pred[in[0]])  in[0]  = map[in[0]];  if (pred[in[1]])  in[1]  = map[in[1]];
      if (pred[in[2]])  in[2]  = map[in[2]];  if (pred[in[3]])  in[3]  = map[in[3]];
      if (pred[in[4]])  in[4]  = map[in[4]];  if (pred[in[5]])  in[5]  = map[in[5]];
      if (pred[in[6]])  in[6]  = map[in[6]];  if (pred[in[7]])  in[7]  = map[in[7]];
      if (pred[in[8]])  in[8]  = map[in[8]];  if (pred[in[9]])  in[9]  = map[in[9]];
      if (pred[in[10]]) in[10] = map[in[10]]; if (pred[in[11]]) in[11] = map[in[11]];
      if (pred[in[12]]) in[12] = map[in[12]]; if (pred[in[13]]) in[13] = map[in[13]];
      if (pred[in[14]]) in[14] = map[in[14]]; if (pred[in[15]]) in[15] = map[in[15]];

      in += 16;
    }

    end += extras;
    while (in < end) {
      *in = map[*in]; in++;
    }
  }
  else {
    while (in < end) {
      if (pred[in[0]])  out[0]  = map[in[0]];  if (pred[in[1]])  out[1]  = map[in[1]];
      if (pred[in[2]])  out[2]  = map[in[2]];  if (pred[in[3]])  out[3]  = map[in[3]];
      if (pred[in[4]])  out[4]  = map[in[4]];  if (pred[in[5]])  out[5]  = map[in[5]];
      if (pred[in[6]])  out[6]  = map[in[6]];  if (pred[in[7]])  out[7]  = map[in[7]];
      if (pred[in[8]])  out[8]  = map[in[8]];  if (pred[in[9]])  out[9]  = map[in[9]];
      if (pred[in[10]]) out[10] = map[in[10]]; if (pred[in[11]]) out[11] = map[in[11]];
      if (pred[in[12]]) out[12] = map[in[12]]; if (pred[in[13]]) out[13] = map[in[13]];
      if (pred[in[14]]) out[14] = map[in[14]]; if (pred[in[15]]) out[15] = map[in[15]];

      out += 16;
      in  += 16;
    }

    end += extras;
    for ( ; in < end; in++, out++) {
      if (pred[*in]) *out = map[*in];
    }
  }
}
