Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "quickputP.h"
Toshihiro Shimizu 890ddd
#include "tpixelutils.h"
Toshihiro Shimizu 890ddd
#include "trastercm.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "tropcm.h"
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
322341
#if defined(_WIN32) && defined(x64)
322341
#define USE_SSE2
322341
#endif
322341
322341
#ifdef USE_SSE2
Shinya Kitaoka 120a6e
#include <emmintrin.h>  // per SSE2</emmintrin.h>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline bool transp(const TPixel32 &p) { return p.m == 0; }
Shinya Kitaoka 120a6e
inline bool transp(const TPixel64 &p) { return p.m == 0; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline bool opaque(const TPixel32 &p) { return p.m == 0xff; }
Shinya Kitaoka 120a6e
inline bool opaque(const TPixel64 &p) { return p.m == 0xffff; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define MODO2
Toshihiro Shimizu 890ddd
#define VELOCE
Toshihiro Shimizu 890ddd
template <class t=""></class>
Shinya Kitaoka 120a6e
void do_overT3(TRasterPT<t> rout, const TRasterPT<t> &rdn,</t></t>
Shinya Kitaoka 120a6e
               const TRasterPT<t> &rup) {</t>
Shinya Kitaoka 120a6e
  for (int y = 0; y < rout->getLy(); y++) {
Toshihiro Shimizu 890ddd
#ifdef MODO1
Shinya Kitaoka 120a6e
    const T *dn_pix = rdn->pixels(y);
Shinya Kitaoka 120a6e
    const T *up_pix = rup->pixels(y);
Shinya Kitaoka 120a6e
    T *out_pix      = rout->pixels(y);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#ifdef MODO2
Shinya Kitaoka 120a6e
    const T *dn_pix = ((T *)rdn->getRawData()) + y * rdn->getWrap();
Shinya Kitaoka 120a6e
    const T *up_pix = ((T *)rup->getRawData()) + y * rup->getWrap();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    T *out_pix = ((T *)rout->getRawData()) + y * rout->getWrap();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    const T *dn_limit = dn_pix + rdn->getLx();
Shinya Kitaoka 120a6e
    for (; dn_pix < dn_limit; dn_pix++, up_pix++, out_pix++) {
Toshihiro Shimizu 890ddd
#ifdef VELOCE
Shinya Kitaoka 120a6e
      if (transp(*up_pix))
Shinya Kitaoka 120a6e
        *out_pix = *dn_pix;
Shinya Kitaoka 120a6e
      else if (opaque(*up_pix))
Shinya Kitaoka 120a6e
        *out_pix = *up_pix;
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        *out_pix = overPix(*dn_pix, *up_pix);
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      T topval = *up_pix;
Shinya Kitaoka 120a6e
      if (transp(topval))
Shinya Kitaoka 120a6e
        *out_pix = *dn_pix;
Shinya Kitaoka 120a6e
      else if (opaque(topval))
Shinya Kitaoka 120a6e
        *out_pix = topval;
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        *out_pix = overPix(*dn_pix, topval);
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixtypedn,="" pixtypeout,="" pixtypeup="" typename=""></typename>
Toshihiro Shimizu 890ddd
void do_over(TRasterPT<pixtypeout> rout, const TRasterPT<pixtypedn> &rdn,</pixtypedn></pixtypeout>
Shinya Kitaoka 120a6e
             const TRasterPT<pixtypeup> &rup, const TRasterGR8P rmask) {</pixtypeup>
Shinya Kitaoka 120a6e
  for (int y = 0; y < rout->getLy(); y++) {
Shinya Kitaoka 120a6e
    const PixTypeDn *dn_pix =
Shinya Kitaoka 120a6e
        ((PixTypeDn *)rdn->getRawData()) + y * rdn->getWrap();
Shinya Kitaoka 120a6e
    const PixTypeUp *up_pix =
Shinya Kitaoka 120a6e
        ((PixTypeUp *)rup->getRawData()) + y * rup->getWrap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    PixTypeOut *out_pix =
Shinya Kitaoka 120a6e
        ((PixTypeOut *)rout->getRawData()) + y * rout->getWrap();
Shinya Kitaoka 120a6e
    TPixelGR8 *mask_pix =
Shinya Kitaoka 120a6e
        ((TPixelGR8 *)rmask->getRawData()) + y * rmask->getWrap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    const PixTypeDn *dn_limit = dn_pix + rout->getLx();
Shinya Kitaoka 120a6e
    for (; dn_pix < dn_limit; dn_pix++, up_pix++, out_pix++, mask_pix++) {
Shinya Kitaoka 120a6e
      if (mask_pix->value == 0x00)
Shinya Kitaoka 120a6e
        *out_pix = *dn_pix;
Shinya Kitaoka 120a6e
      else if (mask_pix->value == 0xff)
Shinya Kitaoka 120a6e
        *out_pix = *up_pix;
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        PixTypeUp p(*up_pix);
Shinya Kitaoka 120a6e
        p.m      = mask_pix->value;
Shinya Kitaoka 120a6e
        *out_pix = overPix(*dn_pix, p);  // hei!
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void do_over(TRasterCM32P rout, const TRasterCM32P &rup) {
Shinya Kitaoka 120a6e
  assert(rout->getSize() == rup->getSize());
Shinya Kitaoka 120a6e
  for (int y = 0; y < rout->getLy(); y++) {
Shinya Kitaoka 120a6e
    TPixelCM32 *out_pix       = rout->pixels(y);
Shinya Kitaoka 120a6e
    TPixelCM32 *const out_end = out_pix + rout->getLx();
Shinya Kitaoka 120a6e
    const TPixelCM32 *up_pix  = rup->pixels(y);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (; out_pix < out_end; ++out_pix, ++up_pix) {
Shinya Kitaoka 120a6e
      if (!up_pix->isPureInk() && up_pix->getPaint() != 0)  // BackgroundStyle)
Shinya Kitaoka 120a6e
        *out_pix = *up_pix;
Shinya Kitaoka 120a6e
      else if (!up_pix->isPurePaint()) {
Shinya Kitaoka 120a6e
        TUINT32 *outl = (TUINT32 *)out_pix, *upl = (TUINT32 *)up_pix;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        *outl = ((*upl) & (TPixelCM32::getInkMask())) |
Shinya Kitaoka 120a6e
                ((*outl) & (TPixelCM32::getPaintMask())) |
Shinya Kitaoka 120a6e
                std::min(up_pix->getTone(), out_pix->getTone());
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class class="" q="" t,=""></class>
Shinya Kitaoka 120a6e
void do_overT2(TRasterPT<t> rout, const TRasterPT<t> &rup) {</t></t>
Shinya Kitaoka 120a6e
  UINT max    = T::maxChannelValue;
Shinya Kitaoka 120a6e
  double maxD = max;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(rout->getSize() == rup->getSize());
Shinya Kitaoka 120a6e
  for (int y = 0; y < rout->getLy(); y++) {
Shinya Kitaoka 120a6e
    T *out_pix       = rout->pixels(y);
Shinya Kitaoka 120a6e
    T *const out_end = out_pix + rout->getLx();
Shinya Kitaoka 120a6e
    const T *up_pix  = rup->pixels(y);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (; out_pix < out_end; ++out_pix, ++up_pix) {
Shinya Kitaoka 120a6e
      if (up_pix->m == max)
Shinya Kitaoka 120a6e
        *out_pix = *up_pix;
Shinya Kitaoka 120a6e
      else if (up_pix->m > 0) {
Shinya Kitaoka 120a6e
        TUINT32 r, g, b;
Shinya Kitaoka 120a6e
        r = up_pix->r + (out_pix->r * (max - up_pix->m)) / maxD;
Shinya Kitaoka 120a6e
        g = up_pix->g + (out_pix->g * (max - up_pix->m)) / maxD;
Shinya Kitaoka 120a6e
        b = up_pix->b + (out_pix->b * (max - up_pix->m)) / maxD;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        out_pix->r = (r < max) ? (Q)r : (Q)max;
Shinya Kitaoka 120a6e
        out_pix->g = (g < max) ? (Q)g : (Q)max;
Shinya Kitaoka 120a6e
        out_pix->b = (b < max) ? (Q)b : (Q)max;
Shinya Kitaoka 120a6e
        out_pix->m = up_pix->m + (out_pix->m * (max - up_pix->m)) / maxD;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
322341
#ifdef USE_SSE2
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void do_over_SSE2(TRaster32P rout, const TRaster32P &rup) {
Shinya Kitaoka 120a6e
  __m128i zeros = _mm_setzero_si128();
Shinya Kitaoka 120a6e
  __m128i out_pix_packed_i, up_pix_packed_i;
Shinya Kitaoka 120a6e
  __m128 out_pix_packed, up_pix_packed;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  float maxChannelValue    = 255.0;
Shinya Kitaoka 120a6e
  float maxChannelValueInv = 1.0f / maxChannelValue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  __m128 maxChanneValue_packed = _mm_load1_ps(&maxChannelValue);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(rout->getSize() == rup->getSize());
Shinya Kitaoka 120a6e
  for (int y = 0; y < rout->getLy(); y++) {
Shinya Kitaoka 120a6e
    TPixel32 *out_pix       = rout->pixels(y);
Shinya Kitaoka 120a6e
    TPixel32 *const out_end = out_pix + rout->getLx();
Shinya Kitaoka 120a6e
    const TPixel32 *up_pix  = rup->pixels(y);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (; out_pix < out_end; ++out_pix, ++up_pix) {
Shinya Kitaoka 120a6e
      if (up_pix->m == 0xff)
Shinya Kitaoka 120a6e
        *out_pix = *up_pix;
Shinya Kitaoka 120a6e
      else if (up_pix->m > 0) {
Shinya Kitaoka 120a6e
        float factor         = (255.0f - up_pix->m) / 255.0f;
Shinya Kitaoka 120a6e
        __m128 factor_packed = _mm_load1_ps(&factor);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        // carica up_pix e out_pix in due registri a 128 bit
Shinya Kitaoka 120a6e
        up_pix_packed_i =
Shinya Kitaoka 120a6e
            _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(DWORD *)up_pix), zeros);
Shinya Kitaoka 120a6e
        up_pix_packed =
Shinya Kitaoka 120a6e
            _mm_cvtepi32_ps(_mm_unpacklo_epi16(up_pix_packed_i, zeros));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        out_pix_packed_i =
Shinya Kitaoka 120a6e
            _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(DWORD *)out_pix), zeros);
Shinya Kitaoka 120a6e
        out_pix_packed =
Shinya Kitaoka 120a6e
            _mm_cvtepi32_ps(_mm_unpacklo_epi16(out_pix_packed_i, zeros));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        out_pix_packed = _mm_add_ps(up_pix_packed,
Shinya Kitaoka 120a6e
                                    _mm_mul_ps(out_pix_packed, factor_packed));
Shinya Kitaoka 120a6e
        out_pix_packed = _mm_min_ps(maxChanneValue_packed, out_pix_packed);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        out_pix_packed_i    = _mm_cvtps_epi32(out_pix_packed);
Shinya Kitaoka 120a6e
        out_pix_packed_i    = _mm_packs_epi32(out_pix_packed_i, zeros);
Shinya Kitaoka 120a6e
        out_pix_packed_i    = _mm_packus_epi16(out_pix_packed_i, zeros);
Shinya Kitaoka 120a6e
        *(DWORD *)(out_pix) = _mm_cvtsi128_si32(out_pix_packed_i);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void do_over(TRaster32P rout, const TRasterGR8P &rup) {
Shinya Kitaoka 120a6e
  assert(rout->getSize() == rup->getSize());
Shinya Kitaoka 120a6e
  for (int y = rout->getLy(); --y >= 0;) {
Shinya Kitaoka 120a6e
    TPixel32 *out_pix       = rout->pixels(y);
Shinya Kitaoka 120a6e
    TPixel32 *const out_end = out_pix + rout->getLx();
Shinya Kitaoka 120a6e
    const TPixelGR8 *up_pix = rup->pixels(y);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (; out_pix < out_end; ++out_pix, ++up_pix) {
Shinya Kitaoka 120a6e
      int v      = up_pix->value;
Shinya Kitaoka 120a6e
      out_pix->r = out_pix->r * v / 255;
Shinya Kitaoka 120a6e
      out_pix->g = out_pix->r;
Shinya Kitaoka 120a6e
      out_pix->b = out_pix->r;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void do_over(TRasterGR8P rout, const TRaster32P &rup) {
Shinya Kitaoka 120a6e
  assert(rout->getSize() == rup->getSize());
Shinya Kitaoka 120a6e
  for (int y = rout->getLy(); --y >= 0;) {
Shinya Kitaoka 120a6e
    TPixelGR8 *out_pix       = rout->pixels(y);
Shinya Kitaoka 120a6e
    TPixelGR8 *const out_end = out_pix + rout->getLx();
Shinya Kitaoka 120a6e
    const TPixel32 *up_pix   = rup->pixels(y);
Shinya Kitaoka 120a6e
    TPixel32 *temp_pix       = new TPixel32();
Shinya Kitaoka 120a6e
    for (; out_pix < out_end; ++out_pix, ++up_pix) {
Shinya Kitaoka 120a6e
      temp_pix->r        = out_pix->value;
Shinya Kitaoka 120a6e
      temp_pix->g        = out_pix->value;
Shinya Kitaoka 120a6e
      temp_pix->b        = out_pix->value;
Shinya Kitaoka 120a6e
      temp_pix->m        = 0xff;
Shinya Kitaoka 120a6e
      TPixel32 out32_pix = overPix(*temp_pix, *up_pix);
Shinya Kitaoka 120a6e
      *out_pix           = out_pix->from(out32_pix);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    delete temp_pix;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
shun-iwasawa 481b59
//-----------------------------------------------------------------------------
shun-iwasawa 481b59
shun-iwasawa 481b59
void do_over(TRasterFP rout, const TRasterFP &rup) {
shun-iwasawa 481b59
  assert(rout->getSize() == rup->getSize());
shun-iwasawa 481b59
  for (int y = 0; y < rout->getLy(); y++) {
shun-iwasawa 481b59
    TPixelF *out_pix       = rout->pixels(y);
shun-iwasawa 481b59
    TPixelF *const out_end = out_pix + rout->getLx();
shun-iwasawa 481b59
    const TPixelF *up_pix  = rup->pixels(y);
shun-iwasawa 481b59
shun-iwasawa 481b59
    for (; out_pix < out_end; ++out_pix, ++up_pix) {
shun-iwasawa 481b59
      if (up_pix->m >= 1.f)
shun-iwasawa 481b59
        *out_pix = *up_pix;
shun-iwasawa 481b59
      else if (up_pix->m > 0.f) {
shun-iwasawa 481b59
        out_pix->r = up_pix->r + out_pix->r * (1.f - up_pix->m);
shun-iwasawa 481b59
        out_pix->g = up_pix->g + out_pix->g * (1.f - up_pix->m);
shun-iwasawa 481b59
        out_pix->b = up_pix->b + out_pix->b * (1.f - up_pix->m);
shun-iwasawa 481b59
        out_pix->m = up_pix->m + out_pix->m * (1.f - up_pix->m);
shun-iwasawa 481b59
      }
shun-iwasawa 481b59
    }
shun-iwasawa 481b59
  }
shun-iwasawa 481b59
}
shun-iwasawa 481b59
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa 27b0cf
static void do_over(TRaster32P rout, const TRasterGR8P &rup,
shun-iwasawa 27b0cf
                    const TPixel32 &color) {
Shinya Kitaoka 120a6e
  assert(rout->getSize() == rup->getSize());
Shinya Kitaoka 120a6e
  for (int y = rout->getLy(); --y >= 0;) {
Shinya Kitaoka 120a6e
    TPixel32 *out_pix       = rout->pixels(y);
Shinya Kitaoka 120a6e
    TPixel32 *const out_end = out_pix + rout->getLx();
Shinya Kitaoka 120a6e
    const TPixelGR8 *up_pix = rup->pixels(y);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (; out_pix < out_end; ++out_pix, ++up_pix) {
Shinya Kitaoka 120a6e
      double v = up_pix->value / 255.0;
Shinya Kitaoka 120a6e
      TPixel32 up(troundp(v * color.r), troundp(v * color.g),
Shinya Kitaoka 120a6e
                  troundp(v * color.b), troundp(v * color.m));
Shinya Kitaoka 120a6e
      *out_pix = overPix(*out_pix, up);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRop::over(TRaster32P rout, const TRasterGR8P &rup,
Shinya Kitaoka 120a6e
                const TPixel32 &color) {
Shinya Kitaoka 120a6e
  rout->lock();
Shinya Kitaoka 120a6e
  do_over(rout, rup, color);
Shinya Kitaoka 120a6e
  rout->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRop::over(const TRasterP &rout, const TRasterP &rdn,
Shinya Kitaoka 120a6e
                const TRasterP &rup) {
Shinya Kitaoka 120a6e
  TRect rect = rout->getBounds() * rdn->getBounds() * rup->getBounds();
Shinya Kitaoka 120a6e
  if (rect.isEmpty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterP cRout = rout->extract(rect);
Shinya Kitaoka 120a6e
  TRasterP cRdn  = rdn->extract(rect);
Shinya Kitaoka 120a6e
  TRasterP cRup  = rup->extract(rect);
Shinya Kitaoka 120a6e
  rout->lock();
Shinya Kitaoka 120a6e
  rdn->lock();
Shinya Kitaoka 120a6e
  rup->lock();
Shinya Kitaoka 120a6e
  TRaster32P rout32 = cRout, rdn32 = cRdn, rup32 = cRup;
Shinya Kitaoka 120a6e
  TRaster64P rout64 = cRout, rdn64 = cRdn, rup64 = cRup;
Shinya Kitaoka 120a6e
  if (rout32 && rdn32 && rup32)
Shinya Kitaoka 120a6e
    do_overT3<tpixel32>(rout32, rdn32, rup32);</tpixel32>
Shinya Kitaoka 120a6e
  else if (rout64 && rdn64 && rup64)
Shinya Kitaoka 120a6e
    do_overT3<tpixel64>(rout64, rdn64, rup64);</tpixel64>
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    rout->unlock();
Shinya Kitaoka 120a6e
    rdn->unlock();
Shinya Kitaoka 120a6e
    rup->unlock();
Shinya Kitaoka 120a6e
    throw TRopException("unsupported pixel type");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rout->unlock();
Shinya Kitaoka 120a6e
  rdn->unlock();
Shinya Kitaoka 120a6e
  rup->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRop::over(const TRasterP &rout, const TRasterP &rup, const TPoint &pos) {
Shinya Kitaoka 120a6e
  TRect outRect(rout->getBounds());
Shinya Kitaoka 120a6e
  TRect upRect(rup->getBounds() + pos);
Shinya Kitaoka 120a6e
  TRect intersection = outRect * upRect;
Shinya Kitaoka 120a6e
  if (intersection.isEmpty()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRasterP cRout = rout->extract(intersection);
Shinya Kitaoka 120a6e
  TRect r        = intersection - pos;
Shinya Kitaoka 120a6e
  TRasterP cRup  = rup->extract(r);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRaster32P rout32 = cRout, rup32 = cRup;
Shinya Kitaoka 120a6e
  TRaster64P rout64 = cRout, rup64 = cRup;
shun-iwasawa 481b59
  TRasterFP routF = cRout, rupF = cRup;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRasterGR8P rout8 = cRout, rup8 = cRup;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRasterCM32P routCM32 = cRout, rupCM32 = cRup;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  rout->lock();
Shinya Kitaoka 120a6e
  rup->lock();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // TRaster64P rout64 = rout, rin64 = rin;
Shinya Kitaoka 120a6e
  if (rout32 && rup32) {
322341
#ifdef USE_SSE2
Shinya Kitaoka 120a6e
    if (TSystem::getCPUExtensions() & TSystem::CpuSupportsSse2)
Shinya Kitaoka 120a6e
      do_over_SSE2(rout32, rup32);
Shinya Kitaoka 120a6e
    else
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
      do_overT2<tpixel32, uchar="">(rout32, rup32);</tpixel32,>
Shinya Kitaoka 120a6e
  } else if (rout64) {
Shinya Kitaoka 120a6e
    if (!rup64) {
Shinya Kitaoka 120a6e
      TRaster64P raux(cRup->getSize());
Shinya Kitaoka 120a6e
      TRop::convert(raux, cRup);
Shinya Kitaoka 120a6e
      rup64 = raux;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    do_overT2<tpixel64, ushort="">(rout64, rup64);</tpixel64,>
Shinya Kitaoka 120a6e
  } else if (rout32 && rup8)
Shinya Kitaoka 120a6e
    do_over(rout32, rup8);
Shinya Kitaoka 120a6e
  else if (rout8 && rup32)
Shinya Kitaoka 120a6e
    do_over(rout8, rup32);
Shinya Kitaoka 120a6e
  else if (rout8 && rup8)
Shinya Kitaoka 120a6e
    TRop::copy(rout8, rup8);
Shinya Kitaoka 120a6e
  else if (routCM32 && rupCM32)
Shinya Kitaoka 120a6e
    do_over(routCM32, rupCM32);
shun-iwasawa 481b59
  else if (routF && rupF)
shun-iwasawa 481b59
    do_over(routF, rupF);
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    rout->unlock();
Shinya Kitaoka 120a6e
    rup->unlock();
Shinya Kitaoka 120a6e
    throw TRopException("unsupported pixel type");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rout->unlock();
Shinya Kitaoka 120a6e
  rup->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
static void addBackground32(TRaster32P ras, const TPixel32 &col) {
Shinya Kitaoka 120a6e
  ras->lock();
Shinya Kitaoka 120a6e
  int nrows = ras->getLy();
Shinya Kitaoka 120a6e
  while (nrows-- > 0) {
Shinya Kitaoka 120a6e
    TPixel32 *pix    = ras->pixels(nrows);
Shinya Kitaoka 120a6e
    TPixel32 *endPix = pix + ras->getLx();
Shinya Kitaoka 120a6e
    while (pix < endPix) {
Shinya Kitaoka 120a6e
      *pix = overPix(col, *pix);
Shinya Kitaoka 120a6e
      pix++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  ras->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRop::addBackground(TRasterP ras, const TPixel32 &col) {
Shinya Kitaoka 120a6e
  TRaster32P ras32 = ras;
Shinya Kitaoka 120a6e
  if (ras32)
Shinya Kitaoka 120a6e
    addBackground32(ras32, col);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    throw TRopException("unsupported pixel type");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Usata tinylinetest
Shinya Kitaoka 120a6e
static void my_do_over(TRaster32P rout, const TRasterGR8P &rup) {
Shinya Kitaoka 120a6e
  assert(rout->getSize() == rup->getSize());
Shinya Kitaoka 120a6e
  for (int y = rout->getLy(); --y >= 0;) {
Shinya Kitaoka 120a6e
    TPixel32 *out_pix       = rout->pixels(y);
Shinya Kitaoka 120a6e
    TPixel32 *const out_end = out_pix + rout->getLx();
Shinya Kitaoka 120a6e
    const TPixelGR8 *up_pix = rup->pixels(y);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (; out_pix < out_end; ++out_pix, ++up_pix) {
Shinya Kitaoka 120a6e
      int v      = up_pix->value;
Shinya Kitaoka 120a6e
      out_pix->r = out_pix->r * v / 255;
Shinya Kitaoka 120a6e
      out_pix->g = out_pix->r;
Shinya Kitaoka 120a6e
      out_pix->b = out_pix->r;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRop::over(const TRasterP &out, const TRasterP &up, const TAffine &aff,
Shinya Kitaoka 120a6e
                ResampleFilterType filterType) {
Shinya Kitaoka 120a6e
  out->lock();
Shinya Kitaoka 120a6e
  up->lock();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (filterType == ClosestPixel || filterType == Bilinear)
Shinya Kitaoka 120a6e
    ::quickPut(out, up, aff, filterType);
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    TRect rasterBounds = up->getBounds();
Shinya Kitaoka 120a6e
    TRectD dbounds(rasterBounds.x0, rasterBounds.y0, rasterBounds.x1 + 1,
Shinya Kitaoka 120a6e
                   rasterBounds.y1 + 1);
Shinya Kitaoka 120a6e
    dbounds = aff * dbounds;
Shinya Kitaoka 120a6e
    TRect bounds(tfloor(dbounds.x0), tfloor(dbounds.y0), tceil(dbounds.x1) - 1,
Shinya Kitaoka 120a6e
                 tceil(dbounds.y1) - 1);
Shinya Kitaoka 120a6e
    TRasterP tmp = up->create(bounds.getLx(), bounds.getLy());
Shinya Kitaoka 120a6e
    resample(tmp, up, TTranslation(-bounds.x0, -bounds.y0) * aff, filterType);
Shinya Kitaoka 120a6e
    over(out, tmp, bounds.getP00());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  out->unlock();
Shinya Kitaoka 120a6e
  up->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRop::over(const TRasterP &out, const TRasterP &up, const TPoint &pos,
Shinya Kitaoka 120a6e
                const TAffine &aff, ResampleFilterType filterType) {
Shinya Kitaoka 120a6e
  if (aff.isIdentity())
Shinya Kitaoka 120a6e
    // simple over with offset
Shinya Kitaoka 120a6e
    TRop::over(out, up, pos);
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    TRect rasterBounds = up->getBounds();
Shinya Kitaoka 120a6e
    TRectD dbounds(rasterBounds.x0, rasterBounds.y0, rasterBounds.x1,
Shinya Kitaoka 120a6e
                   rasterBounds.y1);
Shinya Kitaoka 120a6e
    dbounds = aff * dbounds;
Shinya Kitaoka 120a6e
    TRect bounds(tfloor(dbounds.x0), tfloor(dbounds.y0), tceil(dbounds.x1),
Shinya Kitaoka 120a6e
                 tceil(dbounds.y1));
Shinya Kitaoka 120a6e
    TRasterP tmp = up->create(bounds.getLx(), bounds.getLy());
Shinya Kitaoka 120a6e
    resample(tmp, up, TTranslation(-dbounds.getP00()) * aff, filterType);
Shinya Kitaoka 120a6e
    TRop::over(out, tmp, pos);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRop::over(TRasterP rout, const TRasterCM32P &rup, TPalette *palette,
Shinya Kitaoka 120a6e
                const TPoint &point, const TAffine &aff) {
Shinya Kitaoka 120a6e
  TRaster32P app(rup->getSize());
Shinya Kitaoka 120a6e
  TRop::convert(app, rup, palette);
Shinya Kitaoka 120a6e
  TRop::over(rout, app, point, aff);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRop::quickPut(const TRasterP &out, const TRasterP &up, const TAffine &aff,
Shinya Kitaoka 120a6e
                    const TPixel32 &colorScale, bool doPremultiply,
Shinya Kitaoka 120a6e
                    bool whiteTransp, bool firstColumn,
Shinya Kitaoka 120a6e
                    bool doRasterDarkenBlendedView) {
Shinya Kitaoka 120a6e
  ::quickPut(out, up, aff, ClosestPixel, colorScale, doPremultiply, whiteTransp,
Shinya Kitaoka 120a6e
             firstColumn, doRasterDarkenBlendedView);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRop::over(const TRasterP &out, const TRasterP &dn, const TRasterP &up,
Shinya Kitaoka 120a6e
                const TRasterGR8P &mask) {
Shinya Kitaoka 120a6e
  out->lock();
Shinya Kitaoka 120a6e
  up->lock();
Shinya Kitaoka 120a6e
  dn->lock();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster32P out32 = out;
Shinya Kitaoka 120a6e
  TRaster32P dn32  = dn;
Shinya Kitaoka 120a6e
  TRaster32P up32  = up;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (out32 && dn32 && up32)
Shinya Kitaoka 120a6e
    do_over<tpixel32, tpixel32="" tpixel32,="">(out32, dn32, up32, mask);</tpixel32,>
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    TRaster64P out64 = out;
Shinya Kitaoka 120a6e
    TRaster64P dn64  = dn;
Shinya Kitaoka 120a6e
    TRaster64P up64  = up;
Shinya Kitaoka 120a6e
    if (out64 && dn64 && up64)
Shinya Kitaoka 120a6e
      do_over<tpixel64, tpixel64="" tpixel64,="">(out64, dn64, up64, mask);</tpixel64,>
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      throw TRopException("unsupported pixel type");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  out->unlock();
Shinya Kitaoka 120a6e
  up->unlock();
Shinya Kitaoka 120a6e
  dn->unlock();
Toshihiro Shimizu 890ddd
}