Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tscannerutil.h"
Toshihiro Shimizu 890ddd
Campbell Barton 107701
#include <cstring></cstring>
Campbell Barton 107701
Shinya Kitaoka 120a6e
#define BUFBYTE(X, Y, BUF, BYTEWRAP, BITOFFS)                                  \
Shinya Kitaoka 120a6e
  (((UCHAR *)(BUF))[(((X) + (BITOFFS)) >> 3) + (Y) * (BYTEWRAP)])
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#define GET_BIT(X, Y, BUF, BYTEWRAP, BITOFFS)                                  \
Shinya Kitaoka 120a6e
  ((BUFBYTE(X, Y, BUF, BYTEWRAP, BITOFFS) >> (7 - (((X) + (BITOFFS)) & 7))) &  \
Shinya Kitaoka 120a6e
   (UCHAR)1)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace TScannerUtil {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct EP {
Shinya Kitaoka 120a6e
  unsigned char r, g, b;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void copyRGBBufferToTRaster32(unsigned char *rgbBuffer, int rgbLx, int rgbLy,
Shinya Kitaoka 120a6e
                              const TRaster32P &rout, bool internal) {
Shinya Kitaoka 120a6e
  if (internal) {
Shinya Kitaoka 120a6e
    TPixelRGBM32 *dst = rout->pixels();
Shinya Kitaoka 120a6e
    EP *src           = (EP *)(rgbBuffer + (rgbLx * rgbLy - 1) * 3);
Shinya Kitaoka 120a6e
    const int w       = rout->getWrap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (int x = 0; x < rout->getLx(); ++x) {
Shinya Kitaoka 120a6e
      dst = rout->pixels() + x;
Shinya Kitaoka 120a6e
      for (int y = 0; y < rout->getLy(); ++y) {
Shinya Kitaoka 120a6e
        dst->r = src->r;
Shinya Kitaoka 120a6e
        dst->g = src->g;
Shinya Kitaoka 120a6e
        dst->b = src->b;
Shinya Kitaoka 120a6e
        dst->m = 0xff;
Shinya Kitaoka 120a6e
        dst += w;
Shinya Kitaoka 120a6e
        --src;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    unsigned char *index = rgbBuffer;
Shinya Kitaoka 120a6e
    unsigned char *end   = index + (rgbLx * rgbLy * 3);
Shinya Kitaoka 120a6e
    TPixel32 *outPix     = rout->pixels();
Shinya Kitaoka 120a6e
    while (index < end) {
Shinya Kitaoka 120a6e
      outPix->r = (int)*index;
Shinya Kitaoka 120a6e
      index++;
Shinya Kitaoka 120a6e
      outPix->g = (int)*index;
Shinya Kitaoka 120a6e
      index++;
Shinya Kitaoka 120a6e
      outPix->b = (int)*index;
Shinya Kitaoka 120a6e
      index++;
Shinya Kitaoka 120a6e
      outPix->m = 255;
Shinya Kitaoka 120a6e
      outPix++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    rout->yMirror();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void copyRGBBufferToTRasterGR8(unsigned char *rgbBuffer, int rgbLx, int rgbLy,
Shinya Kitaoka 120a6e
                               int rgbWrap, const TRasterGR8P &rout) {
Shinya Kitaoka 120a6e
  TPixelGR8 *dst = rout->pixels();
Shinya Kitaoka 120a6e
  EP *src        = (EP *)(rgbBuffer + (rgbLx * rgbLy - 1) * 3);
Shinya Kitaoka 120a6e
  const int w    = rout->getWrap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int x = 0; x < rout->getLx(); ++x) {
Shinya Kitaoka 120a6e
    dst = rout->pixels() + x;
Shinya Kitaoka 120a6e
    for (int y = 0; y < rout->getLy(); ++y) {
Shinya Kitaoka 120a6e
      *dst = TPixelGR8::from(TPixelRGBM32(src->r, src->g, src->b));
Shinya Kitaoka 120a6e
      dst += w;
Shinya Kitaoka 120a6e
      --src;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void copyGR8BufferToTRasterGR8(unsigned char *gr8Buffer, int rgbLx, int rgbLy,
Shinya Kitaoka 120a6e
                               const TRasterGR8P &rout, bool internal) {
Shinya Kitaoka 120a6e
  if (internal) {
Shinya Kitaoka 120a6e
    unsigned char *dst = rout->getRawData();
Shinya Kitaoka 120a6e
    unsigned char *src = (gr8Buffer + rgbLx * rgbLy - 1);
Shinya Kitaoka 120a6e
    const int w        = rout->getWrap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (int x = 0; x < rout->getLx(); ++x) {
Shinya Kitaoka 120a6e
      dst = rout->getRawData() + x;
Shinya Kitaoka 120a6e
      for (int y = 0; y < rout->getLy(); ++y) {
Shinya Kitaoka 120a6e
        *dst = (*src);
Shinya Kitaoka 120a6e
        dst += w;
Shinya Kitaoka 120a6e
        --src;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    memcpy(rout->getRawData(), gr8Buffer, rgbLx * rgbLy);
Shinya Kitaoka 120a6e
    rout->yMirror();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void copyGR8BufferToTRasterBW(unsigned char *gr8Buffer, int rgbLx, int rgbLy,
Shinya Kitaoka 120a6e
                              const TRasterGR8P &rout, bool internal,
Shinya Kitaoka 120a6e
                              float thres) {
Shinya Kitaoka 120a6e
  if (internal) {
Shinya Kitaoka 120a6e
    unsigned char *dst = rout->getRawData();
Shinya Kitaoka 120a6e
    unsigned char *src = (gr8Buffer + rgbLx * rgbLy - 1);
Shinya Kitaoka 120a6e
    const int w        = rout->getWrap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (int x = 0; x < rout->getLx(); ++x) {
Shinya Kitaoka 120a6e
      dst = rout->getRawData() + x;
Shinya Kitaoka 120a6e
      for (int y = 0; y < rout->getLy(); ++y) {
Shinya Kitaoka 120a6e
        if (*src < thres)
Shinya Kitaoka 120a6e
          *dst = 0;
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          *dst = 255;
Shinya Kitaoka 120a6e
        dst += w;
Shinya Kitaoka 120a6e
        --src;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    memcpy(rout->getRawData(), gr8Buffer, rgbLx * rgbLy);
Shinya Kitaoka 120a6e
    rout->yMirror();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void copyBWBufferToTRasterGR8(const unsigned char *buffer, int rgbLx, int rgbLy,
Shinya Kitaoka 120a6e
                              const TRasterGR8P &rout, bool isBW,
Shinya Kitaoka 120a6e
                              bool internal) {
Shinya Kitaoka 120a6e
  if (0)
Shinya Kitaoka 120a6e
    assert(0);
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    int i      = 0;
Shinya Kitaoka 120a6e
    UCHAR *pix = rout->getRawData();
Shinya Kitaoka 120a6e
    const unsigned char *byte;
Shinya Kitaoka 120a6e
    while (i < rgbLx * rgbLy) {
Shinya Kitaoka 120a6e
      int bytePos = i / 8;
Shinya Kitaoka 120a6e
      int bitPos  = i % 8;
Shinya Kitaoka 120a6e
      byte        = buffer + bytePos;
Shinya Kitaoka 120a6e
      bool bit    = (*byte) >> (7 - bitPos);
Shinya Kitaoka 120a6e
      if (isBW)
Shinya Kitaoka 120a6e
        *pix = (bit ? 255 : 0);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        *pix = (bit ? 0 : 255);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      pix++;
Shinya Kitaoka 120a6e
      i++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    rout->yMirror();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void copy90BWBufferToRasGR8(unsigned char *bwBuffer, int bwLx, int bwLy,
Shinya Kitaoka 120a6e
                            int bwWrap, bool isBW, TRasterGR8P &rout,
Shinya Kitaoka 120a6e
                            int mirror, int ninety) {
Shinya Kitaoka 120a6e
  int x1   = 0;
Shinya Kitaoka 120a6e
  int y1   = 0;
Shinya Kitaoka 120a6e
  int x2   = bwLx - 1;
Shinya Kitaoka 120a6e
  int y2   = bwLy - 1;
Shinya Kitaoka 120a6e
  int newx = 0;
Shinya Kitaoka 120a6e
  int newy = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UCHAR *bufin, *bufout, /* *bytein,*/ *byteout;
Shinya Kitaoka 120a6e
  int bytewrapin, bitoffsin, wrapout;
Shinya Kitaoka 120a6e
  int value_for_0, value_for_1;
Shinya Kitaoka 120a6e
  int u, v, lu, lv, su, sv, u00, v00, u0, v0, dudy, dvdy, dudx, dvdx;
Shinya Kitaoka 120a6e
  int x, y, lx, ly;
Shinya Kitaoka 120a6e
  int u1, v1, u2, v2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  mirror &= 1;
Shinya Kitaoka 120a6e
  ninety &= 3;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!ninety && !mirror) {
Shinya Kitaoka 120a6e
    assert(0);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (isBW) {
Shinya Kitaoka 120a6e
    value_for_0 = 0;
Shinya Kitaoka 120a6e
    value_for_1 = 255;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    value_for_0 = 255;
Shinya Kitaoka 120a6e
    value_for_1 = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  u1 = x1;
Shinya Kitaoka 120a6e
  v1 = y1;
Shinya Kitaoka 120a6e
  u2 = x2;
Shinya Kitaoka 120a6e
  v2 = y2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  su = u2 - u1;
Shinya Kitaoka 120a6e
  sv = v2 - v1;
Shinya Kitaoka 120a6e
  lu = u2 - u1 + 1;
Shinya Kitaoka 120a6e
  lv = v2 - v1 + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (ninety & 1) {
Shinya Kitaoka 120a6e
    lx = lv;
Shinya Kitaoka 120a6e
    ly = lu;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    lx = lu;
Shinya Kitaoka 120a6e
    ly = lv;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bufin      = bwBuffer;
Shinya Kitaoka 120a6e
  bytewrapin = (bwWrap + 7) >> 3;
Shinya Kitaoka 120a6e
  bitoffsin  = 0;  // rin->bit_offs;
Shinya Kitaoka 120a6e
  bufout     = rout->getRawData();
Shinya Kitaoka 120a6e
  wrapout    = rout->getWrap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  dudx = 0;
Shinya Kitaoka 120a6e
  dudy = 0;
Shinya Kitaoka 120a6e
  dvdx = 0;
Shinya Kitaoka 120a6e
  dvdy = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch ((mirror << 2) + ninety) {
Shinya Kitaoka 120a6e
  case (0 << 2) + 0:
Shinya Kitaoka 120a6e
    u00  = u1;
Shinya Kitaoka 120a6e
    v00  = v1;
Shinya Kitaoka 120a6e
    dudx = 1;
Shinya Kitaoka 120a6e
    dvdy = 1;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case (0 << 2) + 1:
Shinya Kitaoka 120a6e
    u00  = u1;
Shinya Kitaoka 120a6e
    v00  = v1 + sv;
Shinya Kitaoka 120a6e
    dudy = 1;
Shinya Kitaoka 120a6e
    dvdx = -1;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case (0 << 2) + 2:
Shinya Kitaoka 120a6e
    u00  = u1 + su;
Shinya Kitaoka 120a6e
    v00  = v1 + sv;
Shinya Kitaoka 120a6e
    dudx = -1;
Shinya Kitaoka 120a6e
    dvdy = -1;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case (0 << 2) + 3:
Shinya Kitaoka 120a6e
    u00  = u1 + su;
Shinya Kitaoka 120a6e
    v00  = v1;
Shinya Kitaoka 120a6e
    dudy = -1;
Shinya Kitaoka 120a6e
    dvdx = 1;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case (1 << 2) + 0:
Shinya Kitaoka 120a6e
    u00  = u1 + su;
Shinya Kitaoka 120a6e
    v00  = v1;
Shinya Kitaoka 120a6e
    dudx = -1;
Shinya Kitaoka 120a6e
    dvdy = 1;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case (1 << 2) + 1:
Shinya Kitaoka 120a6e
    u00  = u1 + su;
Shinya Kitaoka 120a6e
    v00  = v1 + sv;
Shinya Kitaoka 120a6e
    dudy = -1;
Shinya Kitaoka 120a6e
    dvdx = -1;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case (1 << 2) + 2:
Shinya Kitaoka 120a6e
    u00  = u1;
Shinya Kitaoka 120a6e
    v00  = v1 + sv;
Shinya Kitaoka 120a6e
    dudx = 1;
Shinya Kitaoka 120a6e
    dvdy = -1;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case (1 << 2) + 3:
Shinya Kitaoka 120a6e
    u00  = u1;
Shinya Kitaoka 120a6e
    v00  = v1;
Shinya Kitaoka 120a6e
    dudy = 1;
Shinya Kitaoka 120a6e
    dvdx = 1;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    abort();
Shinya Kitaoka 120a6e
    u00 = v00 = dudy = dvdx = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (dudx)
Shinya Kitaoka 120a6e
    for (u0 = u00, v0 = v00, y = newy; y < newy + ly; v0 += dvdy, y++) {
Shinya Kitaoka 120a6e
      u       = u0;
Shinya Kitaoka 120a6e
      v       = v0;
Shinya Kitaoka 120a6e
      byteout = bufout + newx + y * wrapout;
Shinya Kitaoka 120a6e
      for (x = newx; x < newx + lx; u += dudx, x++) {
Shinya Kitaoka 120a6e
        if (GET_BIT(u, v, bufin, bytewrapin, bitoffsin))
Shinya Kitaoka 120a6e
          *byteout++ = value_for_1;
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          *byteout++ = value_for_0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    for (u0 = u00, v0 = v00, y = newy; y < newy + ly; u0 += dudy, y++) {
Shinya Kitaoka 120a6e
      u       = u0;
Shinya Kitaoka 120a6e
      v       = v0;
Shinya Kitaoka 120a6e
      byteout = bufout + newx + y * wrapout;
Shinya Kitaoka 120a6e
      for (x = newx; x < newx + lx; v += dvdx, x++) {
Shinya Kitaoka 120a6e
        if (GET_BIT(u, v, bufin, bytewrapin, bitoffsin))
Shinya Kitaoka 120a6e
          *byteout++ = value_for_1;
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          *byteout++ = value_for_0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
};