Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "traster.h"
Toshihiro Shimizu 890ddd
#include "trastercm.h"
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "tcolorstyles.h"
Toshihiro Shimizu 890ddd
//#include "trop.h"
Toshihiro Shimizu 890ddd
#include "tropcm.h"
Toshihiro Shimizu 890ddd
#include "tpixelutils.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 6526c7
#include <memory></memory>
Shinya Kitaoka 6526c7
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class class="" pixin="" pixout,=""></class>
Shinya Kitaoka 120a6e
void doConvolve_row_9_i(PIXOUT *pixout, int n, PIXIN *pixarr[], long w[]) {
Shinya Kitaoka 120a6e
  long w1, w2, w3, w4, w5, w6, w7, w8, w9;
Shinya Kitaoka 120a6e
  PIXIN *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9;
Shinya Kitaoka 120a6e
  w1 = w[0];
Shinya Kitaoka 120a6e
  w2 = w[1];
Shinya Kitaoka 120a6e
  w3 = w[2];
Shinya Kitaoka 120a6e
  w4 = w[3];
Shinya Kitaoka 120a6e
  w5 = w[4];
Shinya Kitaoka 120a6e
  w6 = w[5];
Shinya Kitaoka 120a6e
  w7 = w[6];
Shinya Kitaoka 120a6e
  w8 = w[7];
Shinya Kitaoka 120a6e
  w9 = w[8];
Shinya Kitaoka 120a6e
  p1 = pixarr[0];
Shinya Kitaoka 120a6e
  p2 = pixarr[1];
Shinya Kitaoka 120a6e
  p3 = pixarr[2];
Shinya Kitaoka 120a6e
  p4 = pixarr[3];
Shinya Kitaoka 120a6e
  p5 = pixarr[4];
Shinya Kitaoka 120a6e
  p6 = pixarr[5];
Shinya Kitaoka 120a6e
  p7 = pixarr[6];
Shinya Kitaoka 120a6e
  p8 = pixarr[7];
Shinya Kitaoka 120a6e
  p9 = pixarr[8];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int rightShift = 16 +
Shinya Kitaoka 120a6e
                   ((int)sizeof(typename PIXIN::Channel) -
Shinya Kitaoka 120a6e
                    (int)sizeof(typename PIXOUT::Channel)) *
Shinya Kitaoka 120a6e
                       8;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (n-- > 0) {
Shinya Kitaoka 120a6e
    pixout->r = (typename PIXOUT::Channel)(
Shinya Kitaoka 120a6e
        (p1->r * w1 + p2->r * w2 + p3->r * w3 + p4->r * w4 + p5->r * w5 +
Shinya Kitaoka 120a6e
         p6->r * w6 + p7->r * w7 + p8->r * w8 + p9->r * w9 + (1 << 15)) >>
Shinya Kitaoka 120a6e
        rightShift);
Shinya Kitaoka 120a6e
    pixout->g = (typename PIXOUT::Channel)(
Shinya Kitaoka 120a6e
        (p1->g * w1 + p2->g * w2 + p3->g * w3 + p4->g * w4 + p5->g * w5 +
Shinya Kitaoka 120a6e
         p6->g * w6 + p7->g * w7 + p8->g * w8 + p9->g * w9 + (1 << 15)) >>
Shinya Kitaoka 120a6e
        rightShift);
Shinya Kitaoka 120a6e
    pixout->b = (typename PIXOUT::Channel)(
Shinya Kitaoka 120a6e
        (p1->b * w1 + p2->b * w2 + p3->b * w3 + p4->b * w4 + p5->b * w5 +
Shinya Kitaoka 120a6e
         p6->b * w6 + p7->b * w7 + p8->b * w8 + p9->b * w9 + (1 << 15)) >>
Shinya Kitaoka 120a6e
        rightShift);
Shinya Kitaoka 120a6e
    pixout->m = (typename PIXOUT::Channel)(
Shinya Kitaoka 120a6e
        (p1->m * w1 + p2->m * w2 + p3->m * w3 + p4->m * w4 + p5->m * w5 +
Shinya Kitaoka 120a6e
         p6->m * w6 + p7->m * w7 + p8->m * w8 + p9->m * w9 + (1 << 15)) >>
Shinya Kitaoka 120a6e
        rightShift);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    p1++;
Shinya Kitaoka 120a6e
    p2++;
Shinya Kitaoka 120a6e
    p3++;
Shinya Kitaoka 120a6e
    p4++;
Shinya Kitaoka 120a6e
    p5++;
Shinya Kitaoka 120a6e
    p6++;
Shinya Kitaoka 120a6e
    p7++;
Shinya Kitaoka 120a6e
    p8++;
Shinya Kitaoka 120a6e
    p9++;
Shinya Kitaoka 120a6e
    pixout++;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class pixout=""></class>
Shinya Kitaoka 120a6e
void doConvolve_cm32_row_9_i(PIXOUT *pixout, int n, TPixelCM32 *pixarr[],
Shinya Kitaoka 120a6e
                             long w[], const std::vector<tpixel32> &paints,</tpixel32>
Shinya Kitaoka 120a6e
                             const std::vector<tpixel32> &inks) {</tpixel32>
Shinya Kitaoka 120a6e
  long w1, w2, w3, w4, w5, w6, w7, w8, w9;
Shinya Kitaoka 120a6e
  TPixelCM32 *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9;
Shinya Kitaoka 120a6e
  TPixel32 val[9];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  w1 = w[0];
Shinya Kitaoka 120a6e
  w2 = w[1];
Shinya Kitaoka 120a6e
  w3 = w[2];
Shinya Kitaoka 120a6e
  w4 = w[3];
Shinya Kitaoka 120a6e
  w5 = w[4];
Shinya Kitaoka 120a6e
  w6 = w[5];
Shinya Kitaoka 120a6e
  w7 = w[6];
Shinya Kitaoka 120a6e
  w8 = w[7];
Shinya Kitaoka 120a6e
  w9 = w[8];
Shinya Kitaoka 120a6e
  p1 = pixarr[0];
Shinya Kitaoka 120a6e
  p2 = pixarr[1];
Shinya Kitaoka 120a6e
  p3 = pixarr[2];
Shinya Kitaoka 120a6e
  p4 = pixarr[3];
Shinya Kitaoka 120a6e
  p5 = pixarr[4];
Shinya Kitaoka 120a6e
  p6 = pixarr[5];
Shinya Kitaoka 120a6e
  p7 = pixarr[6];
Shinya Kitaoka 120a6e
  p8 = pixarr[7];
Shinya Kitaoka 120a6e
  p9 = pixarr[8];
Shinya Kitaoka 120a6e
  while (n-- > 0) {
Shinya Kitaoka 120a6e
    for (int i = 0; i < 9; ++i) {
Shinya Kitaoka 120a6e
      int tone  = p1->getTone();
Shinya Kitaoka 120a6e
      int paint = p1->getPaint();
Shinya Kitaoka 120a6e
      int ink   = p1->getInk();
Shinya Kitaoka 120a6e
      if (tone == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
        val[i] = paints[paint];
Shinya Kitaoka 120a6e
      else if (tone == 0)
Shinya Kitaoka 120a6e
        val[i] = inks[ink];
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        val[i] =
Shinya Kitaoka 120a6e
            blend(inks[ink], paints[paint], tone, TPixelCM32::getMaxTone());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    pixout->r = (typename PIXOUT::Channel)(
Rozhuk Ivan 823a31
        (val[0].r * w1 + val[1].r * w2 + val[2].r * w3 + val[3].r * w4 +
Rozhuk Ivan 823a31
         val[4].r * w5 + val[5].r * w6 + val[6].r * w7 + val[7].r * w8 +
Rozhuk Ivan 823a31
         val[8].r * w9 + (1 << 15)) >>
Shinya Kitaoka 120a6e
        16);
Shinya Kitaoka 120a6e
    pixout->g = (typename PIXOUT::Channel)(
Rozhuk Ivan 823a31
        (val[0].g * w1 + val[1].g * w2 + val[2].g * w3 + val[3].g * w4 +
Rozhuk Ivan 823a31
         val[4].g * w5 + val[5].g * w6 + val[6].g * w7 + val[7].g * w8 +
Rozhuk Ivan 823a31
         val[8].g * w9 + (1 << 15)) >>
Shinya Kitaoka 120a6e
        16);
Shinya Kitaoka 120a6e
    pixout->b = (typename PIXOUT::Channel)(
Rozhuk Ivan 823a31
        (val[0].b * w1 + val[1].b * w2 + val[2].b * w3 + val[3].b * w4 +
Rozhuk Ivan 823a31
         val[4].b * w5 + val[5].b * w6 + val[6].b * w7 + val[7].b * w8 +
Rozhuk Ivan 823a31
         val[8].b * w9 + (1 << 15)) >>
Shinya Kitaoka 120a6e
        16);
Shinya Kitaoka 120a6e
    pixout->m = (typename PIXOUT::Channel)(
Rozhuk Ivan 823a31
        (val[0].m * w1 + val[1].m * w2 + val[2].m * w3 + val[3].m * w4 +
Rozhuk Ivan 823a31
         val[4].m * w5 + val[5].m * w6 + val[6].m * w7 + val[7].m * w8 +
Rozhuk Ivan 823a31
         val[8].m * w9 + (1 << 15)) >>
Shinya Kitaoka 120a6e
        16);
Shinya Kitaoka 120a6e
    p1++;
Shinya Kitaoka 120a6e
    p2++;
Shinya Kitaoka 120a6e
    p3++;
Shinya Kitaoka 120a6e
    p4++;
Shinya Kitaoka 120a6e
    p5++;
Shinya Kitaoka 120a6e
    p6++;
Shinya Kitaoka 120a6e
    p7++;
Shinya Kitaoka 120a6e
    p8++;
Shinya Kitaoka 120a6e
    p9++;
Shinya Kitaoka 120a6e
    pixout++;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class class="" pixin="" pixout,=""></class>
Shinya Kitaoka 120a6e
void doConvolve_row_i(PIXOUT *pixout, int n, PIXIN *pixarr[], long w[],
Shinya Kitaoka 120a6e
                      int pixn) {
Shinya Kitaoka 120a6e
  long ar, ag, ab, am;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int rightShift = 16 +
Shinya Kitaoka 120a6e
                   ((int)sizeof(typename PIXIN::Channel) -
Shinya Kitaoka 120a6e
                    (int)sizeof(typename PIXOUT::Channel)) *
Shinya Kitaoka 120a6e
                       8;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (n-- > 0) {
Shinya Kitaoka 120a6e
    ar = ag = ab = am = 0;
Shinya Kitaoka 120a6e
    for (i = 0; i < pixn; i++) {
Shinya Kitaoka 120a6e
      ar += pixarr[i]->r * w[i];
Shinya Kitaoka 120a6e
      ag += pixarr[i]->g * w[i];
Shinya Kitaoka 120a6e
      ab += pixarr[i]->b * w[i];
Shinya Kitaoka 120a6e
      am += pixarr[i]->m * w[i];
Shinya Kitaoka 120a6e
      pixarr[i]++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    pixout->r = (typename PIXOUT::Channel)((ar + (1 << 15)) >> rightShift);
Shinya Kitaoka 120a6e
    pixout->g = (typename PIXOUT::Channel)((ag + (1 << 15)) >> rightShift);
Shinya Kitaoka 120a6e
    pixout->b = (typename PIXOUT::Channel)((ab + (1 << 15)) >> rightShift);
Shinya Kitaoka 120a6e
    pixout->m = (typename PIXOUT::Channel)((am + (1 << 15)) >> rightShift);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    pixout++;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class pixout=""></class>
Shinya Kitaoka 120a6e
void doConvolve_cm32_row_i(PIXOUT *pixout, int n, TPixelCM32 *pixarr[],
Shinya Kitaoka 120a6e
                           long w[], int pixn,
Shinya Kitaoka 120a6e
                           const std::vector<tpixel32> &paints,</tpixel32>
Shinya Kitaoka 120a6e
                           const std::vector<tpixel32> &inks) {</tpixel32>
Shinya Kitaoka 120a6e
  long ar, ag, ab, am;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (n-- > 0) {
Shinya Kitaoka 120a6e
    ar = ag = ab = am = 0;
Shinya Kitaoka 120a6e
    for (i = 0; i < pixn; i++) {
Shinya Kitaoka 120a6e
      TPixel32 val;
Shinya Kitaoka 120a6e
      int tone  = pixarr[i]->getTone();
Shinya Kitaoka 120a6e
      int paint = pixarr[i]->getPaint();
Shinya Kitaoka 120a6e
      int ink   = pixarr[i]->getInk();
Shinya Kitaoka 120a6e
      if (tone == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
        val = paints[paint];
Shinya Kitaoka 120a6e
      else if (tone == 0)
Shinya Kitaoka 120a6e
        val = inks[ink];
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        val = blend(inks[ink], paints[paint], tone, TPixelCM32::getMaxTone());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      ar += val.r * w[i];
Shinya Kitaoka 120a6e
      ag += val.g * w[i];
Shinya Kitaoka 120a6e
      ab += val.b * w[i];
Shinya Kitaoka 120a6e
      am += val.m * w[i];
Shinya Kitaoka 120a6e
      pixarr[i]++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    pixout->r = (typename PIXOUT::Channel)((ar + (1 << 15)) >> 16);
Shinya Kitaoka 120a6e
    pixout->g = (typename PIXOUT::Channel)((ag + (1 << 15)) >> 16);
Shinya Kitaoka 120a6e
    pixout->b = (typename PIXOUT::Channel)((ab + (1 << 15)) >> 16);
Shinya Kitaoka 120a6e
    pixout->m = (typename PIXOUT::Channel)((am + (1 << 15)) >> 16);
Shinya Kitaoka 120a6e
    pixout++;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class class="" pixin="" pixout,=""></class>
Shinya Kitaoka 120a6e
void doConvolve_3_i(TRasterPT<pixout> rout, TRasterPT<pixin> rin, int dx,</pixin></pixout>
Shinya Kitaoka 120a6e
                    int dy, double conv[]) {
Shinya Kitaoka 120a6e
  PIXIN *bufferin;
Shinya Kitaoka 120a6e
  PIXOUT *bufferout;
Shinya Kitaoka 120a6e
  PIXIN *pixin;
Shinya Kitaoka 120a6e
  PIXOUT *pixout;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  PIXIN *pixarr[9];
Shinya Kitaoka 120a6e
  long w[9];
Shinya Kitaoka 120a6e
  int pixn;
Shinya Kitaoka 120a6e
  int wrapin, wrapout;
Shinya Kitaoka 120a6e
  int x, y, n;
Shinya Kitaoka 120a6e
  int x1, y1, x2, y2;
Shinya Kitaoka 120a6e
  int fx1, fy1, fx2, fy2, fx, fy;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rout->clear();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  wrapin  = rin->getWrap();
Shinya Kitaoka 120a6e
  wrapout = rout->getWrap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* calcolo l'area di output interessata */
Shinya Kitaoka 120a6e
  x1 = std::max(0, -dx - 1);
Shinya Kitaoka 120a6e
  y1 = std::max(0, -dy - 1);
Shinya Kitaoka 120a6e
  x2 = std::min(rout->getLx() - 1, -dx + rin->getLx());
Shinya Kitaoka 120a6e
  y2 = std::min(rout->getLy() - 1, -dy + rin->getLy());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rin->lock();
Shinya Kitaoka 120a6e
  rout->lock();
Shinya Kitaoka 120a6e
  bufferin  = rin->pixels();
Shinya Kitaoka 120a6e
  bufferout = rout->pixels();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (y = y1; y <= y2; y++) {
Shinya Kitaoka 120a6e
    fy1 = std::max(-1, -dy - y);
Shinya Kitaoka 120a6e
    fy2 = std::min(1, -dy + rin->getLy() - 1 - y);
Shinya Kitaoka 120a6e
    if (fy1 > fy2) continue;
Shinya Kitaoka 120a6e
    x      = x1;
Shinya Kitaoka 120a6e
    pixout = bufferout + wrapout * y + x;
Shinya Kitaoka 120a6e
    pixin  = bufferin + wrapin * (y + dy) + (x + dx);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    while (x <= x2) {
Shinya Kitaoka 120a6e
      fx1 = std::max(-1, -dx - x);
Shinya Kitaoka 120a6e
      fx2 = std::min(1, -dx + rin->getLx() - 1 - x);
Shinya Kitaoka 120a6e
      if (x > -dx && x < -dx + rin->getLx() - 1)
Shinya Kitaoka 120a6e
        n = std::min(-dx + rin->getLx() - 1 - x, x2 - x + 1);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        n = 1;
Shinya Kitaoka 120a6e
      if (n < 1) break;
Shinya Kitaoka 120a6e
      pixn = 0;
Shinya Kitaoka 120a6e
      for (fy = fy1; fy <= fy2; fy++)
Shinya Kitaoka 120a6e
        for (fx = fx1; fx <= fx2; fx++) {
Shinya Kitaoka 120a6e
          pixarr[pixn] = pixin + fy * wrapin + fx;
Shinya Kitaoka 120a6e
          w[pixn]      = (long)(conv[(fy + 1) * 3 + fx + 1] * (1 << 16));
Shinya Kitaoka 120a6e
          pixn++;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      if (pixn == 9)
Shinya Kitaoka 120a6e
        doConvolve_row_9_i<pixout, pixin="">(pixout, n, pixarr, w);</pixout,>
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        doConvolve_row_i<pixout, pixin="">(pixout, n, pixarr, w, pixn);</pixout,>
Shinya Kitaoka 120a6e
      x += n;
Shinya Kitaoka 120a6e
      pixin += n;
Shinya Kitaoka 120a6e
      pixout += n;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  rin->unlock();
Shinya Kitaoka 120a6e
  rout->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class class="" pixin="" pixout,=""></class>
Shinya Kitaoka 120a6e
void doConvolve_i(TRasterPT<pixout> rout, TRasterPT<pixin> rin, int dx, int dy,</pixin></pixout>
Shinya Kitaoka 120a6e
                  double conv[], int radius) {
Shinya Kitaoka 120a6e
  PIXIN *bufferin;
Shinya Kitaoka 120a6e
  PIXOUT *bufferout;
Shinya Kitaoka 120a6e
  PIXIN *pixin;
Shinya Kitaoka 120a6e
  PIXOUT *pixout;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int radiusSquare = sq(radius);
Shinya Kitaoka 120a6e
  std::unique_ptr<pixin *[]=""> pixarr(new PIXIN *[radiusSquare]);</pixin>
Shinya Kitaoka 120a6e
  std::unique_ptr<long[]> w(new long[radiusSquare]);</long[]>
Shinya Kitaoka 120a6e
  int pixn;
Shinya Kitaoka 120a6e
  int wrapin, wrapout;
Shinya Kitaoka 120a6e
  int x, y, n;
Shinya Kitaoka 120a6e
  int x1, y1, x2, y2;
Shinya Kitaoka 120a6e
  int fx1, fy1, fx2, fy2, fx, fy;
Shinya Kitaoka 120a6e
  int radius1 = radius / 2;
Shinya Kitaoka 120a6e
  int radius0 = radius1 - radius + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rout->clear();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  wrapin  = rin->getWrap();
Shinya Kitaoka 120a6e
  wrapout = rout->getWrap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* calcolo l'area di output interessata */
Shinya Kitaoka 120a6e
  x1 = std::max(0, -dx - 1);
Shinya Kitaoka 120a6e
  y1 = std::max(0, -dy - 1);
Shinya Kitaoka 120a6e
  x2 = std::min(rout->getLx() - 1, -dx + rin->getLx());
Shinya Kitaoka 120a6e
  y2 = std::min(rout->getLy() - 1, -dy + rin->getLy());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rin->lock();
Shinya Kitaoka 120a6e
  rout->lock();
Shinya Kitaoka 120a6e
  bufferin  = rin->pixels();
Shinya Kitaoka 120a6e
  bufferout = rout->pixels();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (y = y1; y <= y2; y++) {
Shinya Kitaoka 120a6e
    fy1 = std::max(radius0, -dy - y);
Shinya Kitaoka 120a6e
    fy2 = std::min(radius1, -dy - y + rin->getLy() - 1);
Shinya Kitaoka 120a6e
    if (fy1 > fy2) continue;
Shinya Kitaoka 120a6e
    x      = x1;
Shinya Kitaoka 120a6e
    pixout = bufferout + wrapout * y + x;
Shinya Kitaoka 120a6e
    pixin  = bufferin + wrapin * (y + dy) + (x + dx);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    while (x <= x2) {
Shinya Kitaoka 120a6e
      fx1 = std::max(radius0, -dx - x);
Shinya Kitaoka 120a6e
      fx2 = std::min(radius1, -dx - x + rin->getLx() - 1);
Shinya Kitaoka 120a6e
      if (x > -dx && x < -dx + rin->getLx() - 1)
Shinya Kitaoka 120a6e
        n = std::min(-dx + rin->getLx() - 1 - x, x2 - x + 1);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        n = 1;
Shinya Kitaoka 120a6e
      if (n < 1) break;
Shinya Kitaoka 120a6e
      pixn = 0;
Shinya Kitaoka 120a6e
      for (fy = fy1; fy <= fy2; fy++)
Shinya Kitaoka 120a6e
        for (fx = fx1; fx <= fx2; fx++) {
Shinya Kitaoka 120a6e
          pixarr[pixn] = pixin + fy * wrapin + fx;
Shinya Kitaoka 120a6e
          w[pixn] =
Shinya Kitaoka 120a6e
              (long)(conv[(fy - radius0) * radius + fx - radius0] * (1 << 16));
Shinya Kitaoka 120a6e
          pixn++;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      doConvolve_row_i<pixout, pixin="">(pixout, n, pixarr.get(), w.get(), pixn);</pixout,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      x += n;
Shinya Kitaoka 120a6e
      pixin += n;
Shinya Kitaoka 120a6e
      pixout += n;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rin->unlock();
Shinya Kitaoka 120a6e
  rout->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class pixout=""></class>
Shinya Kitaoka 120a6e
void doConvolve_cm32_3_i(TRasterPT<pixout> rout, TRasterCM32P rin,</pixout>
Shinya Kitaoka 120a6e
                         const TPaletteP &palette, int dx, int dy,
Shinya Kitaoka 120a6e
                         double conv[]) {
Shinya Kitaoka 120a6e
  TPixelCM32 *pixin;
Shinya Kitaoka 120a6e
  PIXOUT *pixout;
Shinya Kitaoka 120a6e
  TPixelCM32 *pixarr[9];
Shinya Kitaoka 120a6e
  long w[9];
Shinya Kitaoka 120a6e
  int pixn;
Shinya Kitaoka 120a6e
  int wrapin, wrapout;
Shinya Kitaoka 120a6e
  int x, y, n;
Shinya Kitaoka 120a6e
  int x1, y1, x2, y2;
Shinya Kitaoka 120a6e
  int fx1, fy1, fx2, fy2, fx, fy;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rout->clear();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  wrapin  = rin->getWrap();
Shinya Kitaoka 120a6e
  wrapout = rout->getWrap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* calcolo l'area di output interessata */
Shinya Kitaoka 120a6e
  x1 = std::max(0, -dx - 1);
Shinya Kitaoka 120a6e
  y1 = std::max(0, -dy - 1);
Shinya Kitaoka 120a6e
  x2 = std::min(rout->getLx() - 1, -dx + rin->getLx());
Shinya Kitaoka 120a6e
  y2 = std::min(rout->getLy() - 1, -dy + rin->getLy());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int colorCount = palette->getStyleCount();
Shinya Kitaoka 120a6e
  colorCount     = std::max(
Shinya Kitaoka 120a6e
      {colorCount, TPixelCM32::getMaxInk(), TPixelCM32::getMaxPaint()});
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<tpixel32> paints(colorCount);</tpixel32>
Shinya Kitaoka 120a6e
  std::vector<tpixel32> inks(colorCount);</tpixel32>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rin->lock();
Shinya Kitaoka 120a6e
  rout->lock();
Shinya Kitaoka 120a6e
  TPixelCM32 *bufferin = rin->pixels();
Shinya Kitaoka 120a6e
  PIXOUT *bufferout    = rout->pixels();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int i  = 0; i < palette->getStyleCount(); i++)
Shinya Kitaoka 120a6e
    paints[i] = inks[i] = palette->getStyle(i)->getAverageColor();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (y = y1; y <= y2; y++) {
Shinya Kitaoka 120a6e
    fy1 = std::max(-1, -dy - y);
Shinya Kitaoka 120a6e
    fy2 = std::min(1, -dy + rin->getLy() - 1 - y);
Shinya Kitaoka 120a6e
    if (fy1 > fy2) continue;
Shinya Kitaoka 120a6e
    x      = x1;
Shinya Kitaoka 120a6e
    pixout = bufferout + wrapout * y + x;
Shinya Kitaoka 120a6e
    pixin  = bufferin + wrapin * (y + dy) + (x + dx);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    while (x <= x2) {
Shinya Kitaoka 120a6e
      fx1 = std::max(-1, -dx - x);
Shinya Kitaoka 120a6e
      fx2 = std::min(1, -dx + rin->getLx() - 1 - x);
Shinya Kitaoka 120a6e
      if (x > -dx && x < -dx + rin->getLx() - 1)
Shinya Kitaoka 120a6e
        n = std::min(-dx + rin->getLx() - 1 - x, x2 - x + 1);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        n = 1;
Shinya Kitaoka 120a6e
      if (n < 1) break;
Shinya Kitaoka 120a6e
      pixn = 0;
Shinya Kitaoka 120a6e
      for (fy = fy1; fy <= fy2; fy++)
Shinya Kitaoka 120a6e
        for (fx = fx1; fx <= fx2; fx++) {
Shinya Kitaoka 120a6e
          pixarr[pixn] = pixin + fy * wrapin + fx;
Shinya Kitaoka 120a6e
          w[pixn]      = (long)(conv[(fy + 1) * 3 + fx + 1] * (1 << 16));
Shinya Kitaoka 120a6e
          pixn++;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      if (pixn == 9)
Shinya Kitaoka 120a6e
        doConvolve_cm32_row_9_i<pixout>(pixout, n, pixarr, w, paints, inks);</pixout>
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        doConvolve_cm32_row_i<pixout>(pixout, n, pixarr, w, pixn, paints, inks);</pixout>
Shinya Kitaoka 120a6e
      x += n;
Shinya Kitaoka 120a6e
      pixin += n;
Shinya Kitaoka 120a6e
      pixout += n;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  rin->unlock();
Shinya Kitaoka 120a6e
  rout->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class pixout=""></class>
Shinya Kitaoka 120a6e
void doConvolve_cm32_i(TRasterPT<pixout> rout, TRasterCM32P rin,</pixout>
Shinya Kitaoka 120a6e
                       const TPaletteP &palette, int dx, int dy, double conv[],
Shinya Kitaoka 120a6e
                       int radius) {
Shinya Kitaoka 120a6e
  TPixelCM32 *pixin;
Shinya Kitaoka 120a6e
  PIXOUT *pixout;
Shinya Kitaoka 120a6e
  int radiusSquare = sq(radius);
Shinya Kitaoka 120a6e
  std::unique_ptr<tpixelcm32 *[]=""> pixarr(new TPixelCM32 *[radiusSquare]);</tpixelcm32>
Shinya Kitaoka 120a6e
  std::unique_ptr<long[]> w(new long[radiusSquare]);</long[]>
Shinya Kitaoka 120a6e
  int pixn;
Shinya Kitaoka 120a6e
  int wrapin, wrapout;
Shinya Kitaoka 120a6e
  int x, y, n;
Shinya Kitaoka 120a6e
  int x1, y1, x2, y2;
Shinya Kitaoka 120a6e
  int fx1, fy1, fx2, fy2, fx, fy;
Shinya Kitaoka 120a6e
  int radius1 = radius / 2;
Shinya Kitaoka 120a6e
  int radius0 = radius1 - radius + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rout->clear();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  wrapin  = rin->getWrap();
Shinya Kitaoka 120a6e
  wrapout = rout->getWrap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* calcolo l'area di output interessata */
Shinya Kitaoka 120a6e
  x1 = std::max(0, -dx - 1);
Shinya Kitaoka 120a6e
  y1 = std::max(0, -dy - 1);
Shinya Kitaoka 120a6e
  x2 = std::min(rout->getLx() - 1, -dx + rin->getLx());
Shinya Kitaoka 120a6e
  y2 = std::min(rout->getLy() - 1, -dy + rin->getLy());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int colorCount = palette->getStyleCount();
Shinya Kitaoka 120a6e
  colorCount     = std::max(
Shinya Kitaoka 120a6e
      {colorCount, TPixelCM32::getMaxInk(), TPixelCM32::getMaxPaint()});
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<tpixel32> paints(colorCount);</tpixel32>
Shinya Kitaoka 120a6e
  std::vector<tpixel32> inks(colorCount);</tpixel32>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rin->lock();
Shinya Kitaoka 120a6e
  rout->lock();
Shinya Kitaoka 120a6e
  TPixelCM32 *bufferin = rin->pixels();
Shinya Kitaoka 120a6e
  PIXOUT *bufferout    = rout->pixels();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int i  = 0; i < palette->getStyleCount(); i++)
Shinya Kitaoka 120a6e
    paints[i] = inks[i] = palette->getStyle(i)->getAverageColor();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (y = y1; y <= y2; y++) {
Shinya Kitaoka 120a6e
    fy1 = std::max(radius0, -dy - y);
Shinya Kitaoka 120a6e
    fy2 = std::min(radius1, -dy + rin->getLy() - 1 - y);
Shinya Kitaoka 120a6e
    if (fy1 > fy2) continue;
Shinya Kitaoka 120a6e
    x      = x1;
Shinya Kitaoka 120a6e
    pixout = bufferout + wrapout * y + x;
Shinya Kitaoka 120a6e
    pixin  = bufferin + wrapin * (y + dy) + (x + dx);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    while (x <= x2) {
Shinya Kitaoka 120a6e
      fx1 = std::max(radius0, -dx - x);
Shinya Kitaoka 120a6e
      fx2 = std::min(radius1, -dx + rin->getLx() - 1 - x);
Shinya Kitaoka 120a6e
      if (x > -dx && x < -dx + rin->getLx() - 1)
Shinya Kitaoka 120a6e
        n = std::min(-dx + rin->getLx() - 1 - x, x2 - x + 1);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        n = 1;
Shinya Kitaoka 120a6e
      if (n < 1) break;
Shinya Kitaoka 120a6e
      pixn = 0;
Shinya Kitaoka 120a6e
      for (fy = fy1; fy <= fy2; fy++)
Shinya Kitaoka 120a6e
        for (fx = fx1; fx <= fx2; fx++) {
Shinya Kitaoka 120a6e
          pixarr[pixn] = pixin + fy * wrapin + fx;
Shinya Kitaoka 120a6e
          w[pixn] =
Shinya Kitaoka 120a6e
              (long)(conv[(fy - radius0) * radius + fx - radius0] * (1 << 16));
Shinya Kitaoka 120a6e
          pixn++;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      doConvolve_cm32_row_i<pixout>(pixout, n, pixarr.get(), w.get(), pixn,</pixout>
Shinya Kitaoka 120a6e
                                    paints, inks);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      x += n;
Shinya Kitaoka 120a6e
      pixin += n;
Shinya Kitaoka 120a6e
      pixout += n;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rin->unlock();
Shinya Kitaoka 120a6e
  rout->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // anonymous namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRop::convolve_3_i(TRasterP rout, TRasterP rin, int dx, int dy,
Shinya Kitaoka 120a6e
                        double conv[]) {
Shinya Kitaoka 120a6e
  TRaster32P rin32 = rin;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (rin32) {
Shinya Kitaoka 120a6e
    TRaster32P rout32 = rout;
Shinya Kitaoka 120a6e
    if (rout32) {
Shinya Kitaoka 120a6e
      doConvolve_3_i<tpixel32, tpixel32="">(rout32, rin32, dx, dy, conv);</tpixel32,>
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRaster64P rout64 = rout;
Shinya Kitaoka 120a6e
    if (rout64) {
Shinya Kitaoka 120a6e
      doConvolve_3_i<tpixel64, tpixel32="">(rout64, rin32, dx, dy, conv);</tpixel64,>
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    TRaster64P rin64 = rin;
Shinya Kitaoka 120a6e
    if (rin64) {
Shinya Kitaoka 120a6e
      TRaster32P rout32 = rout;
Shinya Kitaoka 120a6e
      if (rout32) {
Shinya Kitaoka 120a6e
        doConvolve_3_i<tpixel32, tpixel64="">(rout32, rin64, dx, dy, conv);</tpixel32,>
Shinya Kitaoka 120a6e
        return;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      TRaster64P rout64 = rout;
Shinya Kitaoka 120a6e
      if (rout64) {
Shinya Kitaoka 120a6e
        doConvolve_3_i<tpixel64, tpixel64="">(rout64, rin64, dx, dy, conv);</tpixel64,>
Shinya Kitaoka 120a6e
        return;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  throw TRopException("TRop::convolve_3_i: unsupported pixel type");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRop::convolve_3_i(TRasterP rout, TRasterCM32P rin,
Shinya Kitaoka 120a6e
                        const TPaletteP &palette, int dx, int dy,
Shinya Kitaoka 120a6e
                        double conv[]) {
Shinya Kitaoka 120a6e
  TRaster32P rout32 = rout;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (rout32) {
Shinya Kitaoka 120a6e
    doConvolve_cm32_3_i<tpixel32>(rout32, rin, palette, dx, dy, conv);</tpixel32>
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRaster64P rout64 = rout;
Shinya Kitaoka 120a6e
  if (rout64) {
Shinya Kitaoka 120a6e
    doConvolve_cm32_3_i<tpixel64>(rout64, rin, palette, dx, dy, conv);</tpixel64>
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  throw TRopException("TRop::convolve_3_i: unsupported pixel type");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRop::convolve_i(TRasterP rout, TRasterP rin, int dx, int dy,
Shinya Kitaoka 120a6e
                      double conv[], int radius) {
Shinya Kitaoka 120a6e
  TRaster32P rin32 = rin;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (rin32) {
Shinya Kitaoka 120a6e
    TRaster32P rout32 = rout;
Shinya Kitaoka 120a6e
    if (rout32) {
Shinya Kitaoka 120a6e
      doConvolve_i<tpixel32, tpixel32="">(rout32, rin32, dx, dy, conv, radius);</tpixel32,>
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRaster64P rout64 = rout;
Shinya Kitaoka 120a6e
    if (rout64) {
Shinya Kitaoka 120a6e
      doConvolve_i<tpixel64, tpixel32="">(rout64, rin32, dx, dy, conv, radius);</tpixel64,>
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    TRaster64P rin64 = rin;
Shinya Kitaoka 120a6e
    if (rin64) {
Shinya Kitaoka 120a6e
      TRaster32P rout32 = rout;
Shinya Kitaoka 120a6e
      if (rout32) {
Shinya Kitaoka 120a6e
        doConvolve_i<tpixel32, tpixel64="">(rout32, rin64, dx, dy, conv, radius);</tpixel32,>
Shinya Kitaoka 120a6e
        return;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      TRaster64P rout64 = rout;
Shinya Kitaoka 120a6e
      if (rout64) {
Shinya Kitaoka 120a6e
        doConvolve_i<tpixel64, tpixel64="">(rout64, rin64, dx, dy, conv, radius);</tpixel64,>
Shinya Kitaoka 120a6e
        return;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  throw TRopException("TRop::convolve_i: unsupported pixel type");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRop::convolve_i(TRasterP rout, TRasterCM32P rin, const TPaletteP &palette,
Shinya Kitaoka 120a6e
                      int dx, int dy, double conv[], int radius) {
Shinya Kitaoka 120a6e
  TRaster32P rout32 = rout;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (rout32) {
Shinya Kitaoka 120a6e
    doConvolve_cm32_i<tpixel32>(rout32, rin, palette, dx, dy, conv, radius);</tpixel32>
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster64P rout64 = rout;
Shinya Kitaoka 120a6e
  if (rout64) {
Shinya Kitaoka 120a6e
    doConvolve_cm32_i<tpixel64>(rout64, rin, palette, dx, dy, conv, radius);</tpixel64>
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  throw TRopException("TRop::convolve_i: unsupported pixel type");
Toshihiro Shimizu 890ddd
}